{% extends "base.html" %}
{% block title %}{{ tp_app_label }} — Панель{% endblock %}

{% block content %}
<!-- Счётчик аккаунтов вынесен в sidebar как badge к «Менеджер аккаунтов» (см. base.html). -->
<span id="accounts-count" style="display:none;">0</span>

<!-- Активные задачи. Плашка внизу страницы (position:fixed), появляется только при активной задаче. -->
<div id="active-jobs" style="display:none;position:fixed;bottom:12px;left:50%;transform:translateX(-50%);z-index:80;max-width:640px;width:calc(100vw - 280px);"></div>

<!-- TAB «Главная» (dashboard) удалён. -->

<!-- ═══ TAB: Рассылка по чатам ═══ -->
<div class="section active" id="tab-spam">
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-megaphone text-info"></i><div class="ch-text"><div class="ch-title">Рассылка по чатам</div><div class="card-sub">массовая отправка по выбранным чатам</div></div></div>
        <div class="card-body">
            <!-- Убрана отдельная «активный акк» строка — только мульти-пикер. -->
            <div class="d-flex align-center gap-2 mb-2 flex-wrap" style="font-size:0.78rem;">
                <button class="btn btn-accent btn-sm" onclick="openSpamMultiPicker()" style="font-size:0.78rem;padding:5px 14px;">
                    <i class="bi bi-people"></i> Выбрать аккаунты
                </button>
                <span id="spam-multi-count" style="color:var(--text-muted);font-weight:700;">0</span>
            </div>
            <div class="info-box">
                Чаты делятся между аккаунтами: в один чат пишет только один аккаунт, поэтому двойных сообщений не будет. Если хотите, чтобы каждый аккаунт написал во все свои чаты, включите галочку ниже. Чтобы сообщения не были одинаковыми, впишите варианты через <code>{привет|здравствуйте}</code>. Лимит и паузы считаются отдельно для каждого аккаунта.
            </div>
            <div class="rd-group"><div class="rd-group-title">СООБЩЕНИЕ</div>
            <div class="d-flex gap-3 mb-2 align-center flex-wrap">
                <label class="ad-check m-0"><input type="radio" name="spam-mode" id="spam-mode-text" value="text" checked onchange="onSpamModeChange()"> <span>Свой текст</span></label>
                <label class="ad-check m-0"><input type="radio" name="spam-mode" id="spam-mode-forward" value="forward" onchange="onSpamModeChange()"> <span>Пересылка из чата</span></label>
            </div>

            <div id="spam-mode-text-block">
                <div class="d-flex gap-2 align-center mb-1 flex-wrap">
                    <label class="form-label m-0">Текст сообщения <span class="tt" data-tip="Формат текста сообщения. «Обычный» — текст как есть. «Markdown» — поддержка **жирного**, *курсива*, [ссылок](url). «HTML» — теги <b>жирный</b>, <i>курсив</i>, <a href>ссылка</a>.">?</span></label>
                    <select class="form-control" id="spam-parse-mode" style="width:auto;font-size:0.72rem;padding:3px 8px;">
                        <option value="">Обычный</option>
                        <option value="md">Markdown</option>
                        <option value="html">HTML</option>
                    </select>
                </div>
                <textarea class="form-control mb-2" id="spam-tpl" rows="3"
                    placeholder="Напишите текст. Для вариантов: {привет|здравствуйте}"></textarea>
                <button type="button" class="btn btn-outline btn-sm mb-2" onclick="spintaxPreview('spam-tpl','spam-tpl-preview')">
                    <i class="bi bi-eye"></i> Показать пример сообщения
                </button>
                <div id="spam-tpl-preview" class="spintax-preview" style="display:none;"></div>

                <details class="ad-block" ontoggle="if(this.open) spamLoadStopwords()">
                    <summary><i class="bi bi-shield-check"></i> Проверка текста (стоп-слова + ИИ)</summary>
                    <div class="ad-body">
                        <div style="font-size:0.7rem;color:var(--text-muted);margin-bottom:6px;line-height:1.5;">
                            Telegram не сообщает, из-за какого слова режут — свой бан-лист держит бот чата. Это подсказка: подсветим рискованные слова в тексте, чтобы поправить до рассылки.
                        </div>
                        <div class="d-flex gap-2 mb-2 flex-wrap">
                            <button type="button" class="btn btn-outline btn-sm" onclick="spamCheckStopwords()"><i class="bi bi-search"></i> Проверить по списку</button>
                            <button type="button" class="btn btn-outline btn-sm" onclick="spamCheckTextAI(this)" style="border-color:var(--accent);color:var(--accent);"><i class="bi bi-stars"></i> Проверить ИИ</button>
                        </div>
                        <div id="spam-textcheck-result" style="display:none;font-size:0.72rem;background:var(--bg-card-hover);border-radius:4px;padding:8px 10px;margin-bottom:8px;line-height:1.5;"></div>
                        <label class="form-label" style="font-size:0.75rem;">Мой список стоп-слов <span style="color:var(--text-muted);font-weight:400;">(по одному на строке)</span></label>
                        <textarea class="form-control mb-2" id="spam-stopwords" rows="3" placeholder="казино&#10;ставки&#10;заработок&#10;t.me/"></textarea>
                        <button type="button" class="btn btn-outline btn-sm" onclick="spamSaveStopwords(this)"><i class="bi bi-save"></i> Сохранить список</button>
                    </div>
                </details>
            </div>

            <div id="spam-mode-forward-block" style="display:none;">
                <label class="form-label">Источник для пересылки</label>
                <div class="grid-2 mb-2">
                    <input type="text" class="form-control" id="spam-forward-chat" placeholder="@channel или ID чата откуда пересылать">
                    <input type="number" class="form-control" id="spam-forward-msg-id" placeholder="ID сообщения" min="1">
                </div>
                <div class="info-box fs-70">
                    Перешлёт сообщение #N из канала. Контент сохранится 1-в-1 (форматирование, медиа, эмбеды) — выглядит как обычный share.
                </div>
            </div>
            </div>

            <details class="ad-block">
                <summary><i class="bi bi-arrow-repeat"></i> Цикличная рассылка</summary>
                <div class="ad-body">
                    <label class="ad-check"><input type="checkbox" id="spam-loop"> <span>Повторять рассылку кругами<span class="ad-hint">Прошли весь список — отдохнули — пошли по новому кругу</span></span></label>
                    <div style="display:flex;gap:8px;align-items:center;margin-top:6px;font-size:0.74rem;color:var(--text-muted-strong);">
                        Пауза между кругами: от
                        <input type="number" class="form-control tp-sec" id="spam-loop-seconds" value="600" min="60" max="604800" style="width:80px;">
                        до
                        <input type="number" class="form-control tp-sec" id="spam-loop-seconds-max" value="900" min="60" max="604800" style="width:80px;">
                        сек
                        <span class="tp-sec-hint" data-for="spam-loop-seconds"></span>
                        <span class="tt" data-tip="Софт ждёт случайное время из этого диапазона — одинаковая пауза каждый круг выглядит как бот. Нужна ровная пауза — поставь одинаковые числа. 600-900 сек = 10-15 минут.">?</span>
                    </div>
                    <div style="display:flex;gap:8px;align-items:center;margin-top:6px;font-size:0.74rem;color:var(--text-muted-strong);">
                        Сколько кругов
                        <input type="number" class="form-control" id="spam-loop-rounds" value="" min="0" max="999" placeholder="∞" style="width:70px;">
                        <span style="color:var(--text-muted);">0 = без ограничения, пока не нажмёшь «Стоп»</span>
                    </div>
                </div>
            </details>

            <div class="rd-group"><div class="rd-group-title">ИСТОЧНИК ЧАТОВ</div>
            <div class="d-flex gap-2 mb-2 flex-wrap">
                <button class="btn btn-info btn-sm" onclick="collectTargets()">
                    <i class="bi bi-search"></i> Найти чаты аккаунта
                </button>
                <button class="btn btn-outline btn-sm" onclick="applyPreparedChats()" data-tip="Подставить чаты, собранные «Подготовкой аккаунтов» в модуле Проверка (писабельные чаты живых акков).">
                    <i class="bi bi-clipboard-check"></i> Подставить собранные чаты
                </button>
                <button class="btn btn-outline btn-sm" onclick="toggleManualTargets('spam')">
                    <i class="bi bi-pencil"></i> Вручную
                </button>
                <button class="btn btn-outline btn-sm" onclick="clearTargets('spam')">
                    <i class="bi bi-trash text-danger"></i>
                </button>
            </div>

            <div id="spam-manual" style="display:none;" class="mb-2">
                <textarea class="form-control" id="spam-targets-input" rows="3"
                    placeholder="ID, @username или ссылка t.me/ — по одному на строке&#10;-1001234567890&#10;@mychat&#10;https://t.me/mychat"></textarea>
                <button class="btn btn-outline btn-sm mt-2" onclick="addManualTargets('spam')">
                    <i class="bi bi-plus"></i> Добавить
                </button>
                <label class="opt-row mt-2 mb-0">
                    <input type="checkbox" id="spam-clean-dups">
                    Чистить дубликаты в списке <span class="tt" data-tip="Выключено — список берётся как есть: если чат вписан дважды, он и попадёт в пул дважды (достанется двум разным аккаунтам). Включи, чтобы повторы схлопывались в один. Ставь галку ДО кнопки «Добавить».">?</span>
                </label>
                <div class="info-box fs-70 mt-2">
                    Список <b>распределится между выбранными аккаунтами</b> — каждый чат достанется одному акку (без двойной отправки). Если включена <b>цикличная рассылка</b>, на каждом круге чаты <b>ротируются</b> — чат берёт другой акк (анти-детект). Очисти список <i class="bi bi-trash"></i>, чтобы вернуться к режиму «каждый акк по своим группам».
                </div>
            </div>
            </div>

            <div class="rd-group"><div class="rd-group-title">ЛИМИТЫ И ОПЦИИ</div>
            <div class="d-flex align-center gap-2 mb-2 mt-2 flex-wrap">
                <label class="form-label" style="margin:0;font-size:0.78rem;">Лимит сообщений с одного акка <span class="tt" data-tip="Сколько сообщений максимум разрешено одному аккаунту в этой задаче. 0 — без лимита (акк льёт пока не получит спам-блок). 50–100 — щадящий режим для тёплых акков. 200+ — для прогретых.">?</span></label>
                <input type="number" class="form-control" id="spam-max-per-acc"
                       value="0" min="0" max="2000" step="1"
                       style="width:90px;font-size:0.8rem;padding:4px 8px;">
                <span class="text-sm text-muted fs-70">
                    0 = до спам-блока
                </span>
            </div>

            <div class="d-flex align-center gap-2 mb-2 flex-wrap">
                <label class="form-label" style="margin:0;font-size:0.78rem;">Сколько ошибок спам-блока пропускать <span class="tt" data-tip="Telegram иногда выдаёт ЛОЖНЫЙ спам-блок на конкретного получателя (а не на акк). Софт пропустит N таких ошибок подряд и продолжит к следующему чату. На (N+1)-м проверит акк через @SpamBot — если @SpamBot подтвердит что акк живой, остановит ТОЛЬКО этот акк и продолжит остальными. Дефолт 3.">?</span></label>
                <input type="number" class="form-control" id="spam-pf-tolerance"
                       value="3" min="0" max="20" step="1"
                       style="width:90px;font-size:0.8rem;padding:4px 8px;">
                <span class="text-sm text-muted fs-70">
                    0 = стопать на первом
                </span>
            </div>

            <label class="opt-row mb-2">
                <input type="checkbox" id="spam-no-dedup">
                Слать каждым аккаунтом во ВСЕ его чаты <span class="tt" data-tip="По умолчанию чаты РАСПРЕДЕЛЯЮТСЯ между аккаунтами: если два акка состоят в одном чате, шлёт только первый (нет двойной отправки). Включи — каждый акк отправит во все свои чаты, пересечения допускаются. ⚠ Один чат может получить сообщение от нескольких твоих акков сразу — заметнее, выше шанс спам-репорта.">?</span>
            </label>

            <label class="opt-row mb-2">
                <input type="checkbox" id="spam-auto-leave-no-write">
                Покидать чаты без права писать <span class="tt" data-tip="Каждый акк рассылает по СВОИМ чатам — они собираются автоматически на старте, кнопка «Найти чаты» не обязательна. С этой галкой акк перед рассылкой выходит из групп, где писать нельзя (только чтение / забанен). Выход идёт ДО отправки, поэтому чаты, куда уже слали, не покидаются никогда, и при спам-блоке тоже ничего не покидается.">?</span>
            </label>
            </div>


            <details class="ad-block">
                <summary><i class="bi bi-shield-check"></i> Защита аккаунта</summary>
                <div class="ad-body">
                    <label class="ad-check"><input type="checkbox" id="spam-pre-spam-check"> <span>Перед стартом проверить аккаунты на спам-блок<span class="ad-hint">Заблокированные пропустим, чисто-живые пойдут в работу</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="spam-solve-captcha"> <span>Решать капчу в чатах<span class="ad-hint">Если в чате есть бот-капча (Shieldy и др.) — попробуем нажать «я не бот»</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="spam-keep-online"> <span>Держать аккаунт онлайн во время работы<span class="ad-hint">Аккаунт показывается онлайн в Telegram пока идёт задача</span></span></label>
                </div>
            </details>

            <details class="ad-block">
                <summary><i class="bi bi-reply"></i> Автоответчик на входящие ЛС</summary>
                <div class="ad-body">
                    <div style="font-size:0.75rem;color:var(--text-muted);margin-bottom:10px;line-height:1.5;">
                        Кто увидит объявление и напишет акку в ЛС — получит автоответ (только в личке, не в группах). Один автоответчик на все модули — настраивается на отдельной странице, работает и во время, и после рассылки.
                    </div>
                    <label class="ad-check"><input type="checkbox" id="multi-spam-autoreply"> <span>Запустить автоответчик вместе с рассылкой<span class="ad-hint">Со стартом рассылки на этих же акках включится автоответ на входящие ЛС. Текст и настройки берутся со вкладки «Автоответчик» — заполни их там. Работает и во время, и после рассылки.</span></span></label>
                    <button type="button" onclick="showTab('autoreply')" class="btn btn-accent btn-sm" style="width:100%;">
                        <i class="bi bi-gear"></i> Открыть настройки автоответчика
                    </button>
                </div>
            </details>
        <!-- Тайминги рассылки по чатам -->
        <details class="ad-block">
            <summary>
                <i class="bi bi-clock"></i> Тайминги рассылки
                <span class="ts-sync-badge" title="Статус синхронизации с бэк-эндом — что реально записано в настройках">✓ сохранено</span>
            </summary>
            <div class="ad-body">
                <div class="info-box info-box--warning">
                    Чем короче паузы — тем выше шанс словить вечный спам-блок. Для новых акков ставьте паузы x2.
                </div>
                <div class="mb-2">
                    <button type="button" class="btn btn-outline btn-sm btn-preset" onclick="applyTimingPreset('spam')" data-tip="20-45с между сообщениями, длинная пауза 5-10 мин — заметно меньше спам-блоков. Для новых акков можно ещё медленнее."><i class="bi bi-shield-check" style="color:var(--success);"></i> Рекомендуемый (безопасный)</button>
                </div>
                <div class="grid-3 mb-2">
                    <div class="mb-2"><label class="form-label">Пауза между сообщениями, от (сек) <span class="tt" data-tip="Минимальная пауза между двумя сообщениями с одного акка. Софт ждёт случайное число секунд между «мин» и «макс» — выглядит менее как бот. Чем больше — тем меньше шанс вечный спам-блок.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-spam-min" min="0" step="1" value="20" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Пауза между сообщениями, до (сек) <span class="tt" data-tip="Максимальная пауза между сообщениями. Реальная задержка = случайное значение между «мин» и «макс». Если поставить «макс» = «мин» — поведение станет одинаковым каждый раз (палится).">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-spam-max" min="0" step="1" value="45" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Сообщений подряд, потом отдых (0 = выкл) <span class="tt" data-tip="Сколько сообщений подряд отправить, потом уйти в длинный отдых. Ровный поток без передышек Telegram видит хуже, чем работу с перерывами. 0 = отдых выключен.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-spam-burst" min="0" step="1" value="0" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Длинный отдых, от (сек) <span class="tt" data-tip="Минимальная длинная пауза — срабатывает после серии сообщений (см. «Сообщений подряд»). Софт ждёт случайное число между «мин» и «макс», потом продолжает. 120с = 2 минуты отдыха минимум.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-spam-burst-pause-min" min="0" step="1" value="300" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Длинный отдых, до (сек) <span class="tt" data-tip="Максимальная длинная пауза. Совмещает с «мин» — софт берёт случайное число секунд из этого диапазона. 240с = до 4 минут.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-spam-burst-pause-max" min="0" step="1" value="600" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Остановить акк, если Telegram просит ждать дольше (сек) <span class="tt" data-tip="Если Telegram попросил подождать N секунд — задача стопается только если N БОЛЬШЕ порога. Дефолт 300 (5 мин). Меньше — пережидаем и продолжаем. Поставь 600 чтобы дать больше шансов.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-spam-floodwait-stop" min="0" step="1" value="300" style="max-width:130px;"></div>
                </div>
            </div>
        </details>
        </div>
    </div>
            <div class="run-row">
            <div class="d-flex align-center justify-between">
                <span class="text-sm text-muted">
                    <i class="bi bi-chat-dots"></i> <span id="spam-count">0</span> чатов
                </span>
                <div class="d-flex gap-3 align-center">
                    <button class="btn btn-outline btn-sm" onclick="exportSpamResults()" data-tip="Выгрузка результатов: куда ушло / где не вышло (спам-блок, нет прав, флуд)">
                        <i class="bi bi-folder2-open"></i> Выгрузка
                    </button>
                    <button class="btn btn-outline btn-sm" onclick="retryFailedSpam()" data-tip="Запустить ещё раз только по тем чатам, где не получилось">
                        <i class="bi bi-arrow-counterclockwise"></i> Повторить
                    </button>
                    <label class="form-label m-0" data-tip="Сколько акков одновременно ведут рассылку. 0 = все выбранные параллельно. N = только N в работе, остальные ждут слот. Если у акка назначен прокси — идёт через него, нет — напрямую.">Потоки <span class="text-muted" style="font-size:0.7rem;">?</span></label>
                    <input type="number" class="form-control" id="spam-threads" value="0" min="0" max="100" style="width:70px;">
                    <label class="form-label m-0" style="display:flex;align-items:center;gap:4px;font-size:0.72rem;cursor:pointer;" data-tip="Тест-режим: НИЧЕГО не отправляется. Софт проходит по целям и показывает сколько и куда отправил бы — проверить кампанию перед реальным запуском."><input type="checkbox" id="spam-dry-run" style="margin:0;"> Тест</label>
                    <button class="btn btn-accent btn-sm" onclick="startSpam()" id="btn-spam"
                            data-tip="Выбери аккаунты и жми Старт — чаты каждого акка соберутся автоматически. «Найти чаты» не обязательна (только предпросмотр). Пределы Telegram: новым аккаунтам безопасно 5-10 сообщений в час, прогретым 30-50. Поймал спам-блок — 6 часов отдыха.">
                        <i class="bi bi-send"></i> Старт
                    </button>
                    <button class="btn btn-danger btn-sm" onclick="stopSpam()" id="btn-spam-stop" disabled data-tip="Остановить запущенную рассылку">
                        <i class="bi bi-stop-fill"></i> Стоп
                    </button>
                </div>
            </div>
            </div>
</div>

<!-- ═══ TAB: DM Рассылка ═══ -->
<div class="section" id="tab-dm">
    <div class="card mb-3">
        <div class="card-header">
            <i class="bi bi-person-lines-fill" style="color:var(--pink);"></i><div class="ch-text"><div class="ch-title">Рассылка в личные сообщения</div><div class="card-sub">по списку пользователей</div></div>
        </div>
        <div class="card-body">
            <!-- Убран acc-selector — только мульти-пикер -->
            <div class="d-flex align-center gap-2 mb-2 flex-wrap" style="font-size:0.78rem;">
                <button class="btn btn-accent btn-sm" onclick="openDmMultiPicker()" style="font-size:0.78rem;padding:5px 14px;">
                    <i class="bi bi-people"></i> Выбрать аккаунты
                </button>
                <span id="dm-multi-count" style="color:var(--text-muted);font-weight:700;">0</span>
            </div>
            <div class="info-box">
                Рассылка в ЛС по списку с каждого выбранного акка. Вставьте @username или загрузите .txt файл. Лимит и тайминги применяются к каждому акку.
            </div>
            <div class="rd-group"><div class="rd-group-title">СООБЩЕНИЕ</div>
            <div class="d-flex gap-2 align-center mb-1 flex-wrap">
                <label class="form-label m-0">Текст сообщения <span class="tt" data-tip="Формат текста в ЛС. «Обычный» — как есть. «Markdown» — поддержка **жирного**, *курсива*, [ссылок](url). «HTML» — теги <b>жирный</b>, <i>курсив</i>, <a href>ссылка</a>.">?</span></label>
                <select class="form-control" id="dm-parse-mode" style="width:auto;font-size:0.72rem;padding:3px 8px;">
                    <option value="">Обычный</option>
                    <option value="md">Markdown</option>
                    <option value="html">HTML</option>
                </select>
            </div>
            <textarea class="form-control mb-2" id="dm-tpl" rows="3"
                placeholder="Напишите текст для личных сообщений. Варианты: {привет|здравствуйте}. Имя получателя: %name%"></textarea>
            <div class="text-sm text-muted mb-2" style="font-size:0.78rem;">
                <i class="bi bi-person-badge"></i> Персонализация: <code>%name%</code> (имя получателя),
                <code>%username%</code>, <code>%first_name%</code>, <code>%fullname%</code> — подставятся под каждого.
                Пусто → <code>%name%</code> станет «друг».
            </div>
            <div class="d-flex gap-2 mb-2 flex-wrap">
                <button type="button" class="btn btn-outline btn-sm" onclick="spintaxPreview('dm-tpl','dm-tpl-preview')">
                    <i class="bi bi-eye"></i> Показать пример сообщения
                </button>
                <button type="button" class="btn btn-outline btn-sm" onclick="aiSpintaxGenerate('dm-tpl')" data-tip="Превратит твой шаблон в текст с вариантами в скобках через ваш AI-ключ (Настройки → AI)">
                    <i class="bi bi-magic"></i> AI-варианты
                </button>
            </div>
            <div id="dm-tpl-preview" class="spintax-preview" style="display:none;"></div>
            </div>

            <details class="ad-block">
                <summary><i class="bi bi-arrow-90deg-right"></i> Репост готового поста (вместо текста)</summary>
                <div class="ad-body">
                    <div class="grid-2 mb-2">
                        <input type="text" class="form-control" id="dm-forward-chat" placeholder="@channel или ID — откуда">
                        <input type="number" class="form-control" id="dm-forward-msg-id" placeholder="ID сообщения" min="1">
                    </div>
                    <label class="ad-check"><input type="checkbox" id="dm-forward-hide"> <span>Скрыть источник<span class="ad-hint">Отправит копией, без плашки «Переслано от …»</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="dm-forward-album"> <span>Альбом целиком<span class="ad-hint">Если пост — группа фото/видео, уйдут все</span></span></label>
                    <div class="info-box fs-70">Перешлёт указанный пост по личкам. Текст-шаблон выше можно оставить пустым.</div>
                </div>
            </details>

            <details class="ad-block">
                <summary><i class="bi bi-arrow-repeat"></i> Follow-up цепочка (догоняшки)</summary>
                <div class="ad-body">
                    <div class="info-box fs-70">Дожимай тех, кто не ответил: после основного ЛС софт через заданное время шлёт следующее сообщение. Опционально — до 5 шагов. Пусто = обычная разовая рассылка. Догоняшки летят отложенно (переживают перезапуск софта).</div>
                    <div id="dm-drip-steps"></div>
                    <button type="button" class="btn btn-outline btn-sm mt-2" onclick="addDripStep()"><i class="bi bi-plus-lg"></i> Добавить догоняшку</button>
                    <label class="ad-check mt-8"><input type="checkbox" id="dm-drip-stop-replied" checked> <span>Не догонять, если ответил<span class="ad-hint">Перед каждой догоняшкой софт проверяет: если получатель уже написал в ответ — цепочка для него останавливается.</span></span></label>
                </div>
            </details>

            <div class="rd-group"><div class="rd-group-title">ПОЛУЧАТЕЛИ</div>
            <label class="form-label">Кому отправить (@username, ID или ссылка t.me/)</label>
            <textarea class="form-control mb-2" id="dm-targets-input" rows="4"
                placeholder="@username1&#10;t.me/user3&#10;123456789&#10;+79991234567 — по номеру (найдём как в TG, если номер не скрыт)"
                oninput="_dmTargetsAutoload(this)"
                onblur="if(this.value.trim()) loadDmTargets();"></textarea>

            <div class="d-flex gap-2 mb-2 flex-wrap">
                <button class="btn btn-pink btn-sm" onclick="loadDmTargets()">
                    <i class="bi bi-search"></i> Загрузить
                </button>
                <label class="btn btn-outline btn-sm" style="cursor:pointer;margin:0;display:flex;align-items:center;">
                    <i class="bi bi-file-text"></i> .txt
                    <input type="file" accept=".txt" style="display:none" onchange="loadDmFile(this)">
                </label>
                <button class="btn btn-outline btn-sm" onclick="clearTargets('dm')">
                    <i class="bi bi-trash text-danger"></i>
                </button>
            </div>
            <label class="opt-row mb-2">
                <input type="checkbox" id="dm-clean-dups" onchange="loadDmTargets(true)">
                Чистить дубликаты в списке <span class="tt" data-tip="Выключено — список берётся как есть: кто вписан дважды, получит два сообщения. Включи, чтобы повторы схлопывались в один (один человек — одно сообщение, даже если он в списке и по @имени, и по ID).">?</span>
            </label>
            </div>

            <div id="dm-trigger-warn" style="display:none;" class="mb-2 text-sm text-warning">
                <i class="bi bi-exclamation-triangle"></i> <span id="dm-trigger-words"></span>
            </div>

            <div class="rd-group"><div class="rd-group-title">ЛИМИТЫ</div>
            <div class="d-flex align-center gap-2 mb-2 flex-wrap">
                <label class="form-label" style="margin:0;font-size:0.78rem;">Лимит сообщений с одного акка <span class="tt" data-tip="Сколько ЛС-сообщений максимум разрешено одному аккаунту. Дефолт 15 — безопасно под спам-блок: за 30+ ЛС незнакомым в час TG вешает спам-блок на переписку с чужими. Для прогретых поднимай до 30-80. 0 — без лимита (риск).">?</span></label>
                <input type="number" class="form-control" id="dm-max-per-acc"
                       value="15" min="0" max="2000" step="1"
                       style="width:90px;font-size:0.8rem;padding:4px 8px;">
                <span class="text-sm text-muted fs-70">
                    15 = безопасно. 0 = до спам-блока.
                </span>
            </div>

            <div class="d-flex align-center gap-2 mb-2 flex-wrap">
                <label class="form-label" style="margin:0;font-size:0.78rem;">Сколько ошибок спам-блока пропускать <span class="tt" data-tip="Telegram иногда выдаёт ЛОЖНЫЙ спам-блок на конкретного получателя (а не на акк). Софт пропустит N таких ошибок подряд и продолжит к следующему юзеру. На (N+1)-м проверит акк через @SpamBot — если @SpamBot подтвердит что акк живой, остановит ТОЛЬКО этот акк и продолжит остальными. Дефолт 3.">?</span></label>
                <input type="number" class="form-control" id="dm-pf-tolerance"
                       value="3" min="0" max="20" step="1"
                       style="width:90px;font-size:0.8rem;padding:4px 8px;">
                <span class="text-sm text-muted fs-70">
                    0 = стопать на первом
                </span>
            </div>
            </div>


            <details class="ad-block">
                <summary><i class="bi bi-shield-check"></i> Защита аккаунта</summary>
                <div class="ad-body">
                    <label class="ad-check"><input type="checkbox" id="dm-pre-spam-check"> <span>Перед стартом проверить аккаунты на спам-блок<span class="ad-hint">Заблокированные пропустим</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="dm-keep-online"> <span>Держать аккаунт онлайн во время работы</span></label>
                    <label class="ad-check"><input type="checkbox" id="dm-view-profile"> <span>Смотреть профиль перед отправкой<span class="ad-hint" style="color:#f59e0b">⚠ Включай только для прогретых акков. На свежих 10× view_profile к незнакомым целям подряд — bot-сигнатура для TG, рискует отзывом сессии.</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="dm-view-photo"> <span>Смотреть фото профиля<span class="ad-hint" style="color:#f59e0b">⚠ Та же история — на свежих акках усиливает риск закрытие входа.</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="dm-del-contact" checked> <span>Удалять контакт после отправки (для целей по номеру)<span class="ad-hint">Поиск по номеру добавляет контакт в книгу акка. Удаляем сразу после отправки — иначе акк копит чужие номера = сильный сигнал спам-фермы для Telegram.</span></span></label>
                </div>
            </details>
        <!-- Автоответчик — inline expandable секция в табе ЛС (вместо отдельной вкладки). -->
        <details class="ad-block">
            <summary>
                <i class="bi bi-reply"></i> Автоответчик на входящие ЛС
                <span class="ad-note">авто-ответ на каждое первое сообщение</span>
            </summary>
            <div class="ad-body">
                <div style="font-size:0.75rem;color:var(--text-muted);margin-bottom:12px;">
                    Один автоответ на юзера. Варианты в скобках <code>{Привет|Здравствуйте}</code>. Подробные настройки — на отдельной странице.
                </div>
                <label class="ad-check mb-2"><input type="checkbox" id="dm-autoreply"> <span>Запустить автоответчик вместе с рассылкой<span class="ad-hint">Со стартом рассылки на этих же акках включится автоответ на входящие ЛС. Текст и настройки берутся отсюда же (кнопка ниже). Работает и во время, и после рассылки — «Стоп» рассылки снимет только тот автоответчик, который она сама и подняла.</span></span></label>
                <button type="button" onclick="showTab('autoreply')" class="btn btn-accent" style="width:100%;">
                    <i class="bi bi-gear"></i> Открыть полные настройки автоответчика
                </button>
            </div>
        </details>
        <!-- Тайминги ЛС -->
        <details class="ad-block">
            <summary>
                <i class="bi bi-clock"></i> Тайминги ЛС
                <span class="ts-sync-badge" title="Статус синхронизации с бэк-эндом — что реально записано в настройках">✓ сохранено</span>
            </summary>
            <div class="ad-body">
                <div class="info-box info-box--warning">
                    В ЛС лимиты жёстче чем в чатах — Telegram быстро дает вечный спам-блок. Минимум 30+ сек паузы.
                </div>
                <div class="mb-2">
                    <button type="button" class="btn btn-outline btn-sm btn-preset" onclick="applyTimingPreset('dm')" data-tip="60-150с между ЛС, длинная пауза 10-20 мин — в ЛС лимиты жёстче, это заметно снижает риск вечного бана."><i class="bi bi-shield-check" style="color:var(--success);"></i> Рекомендуемый (безопасный)</button>
                </div>
                <div class="grid-3 mb-2">
                    <div class="mb-2"><label class="form-label">Пауза между сообщениями, от (сек) <span class="tt" data-tip="Минимальная пауза между двумя ЛС с одного акка. В ЛС лимиты жёстче чем в чатах — Telegram быстро банит за частую активность. Рекомендую 30+ секунд минимум.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-dm-min" min="0" step="1" value="60" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Пауза между сообщениями, до (сек) <span class="tt" data-tip="Максимальная пауза между ЛС. Софт берёт случайное число между «мин» и «макс» — не одинаковая задержка каждый раз. 90с — норм для ЛС, 60-180с безопаснее.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-dm-max" min="0" step="1" value="150" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Сообщений подряд, потом отдых (0 = выкл) <span class="tt" data-tip="Сколько сообщений подряд отправить, потом уйти в длинный отдых. Ровный поток без передышек Telegram видит хуже, чем работу с перерывами. 0 = отдых выключен.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-dm-burst" min="0" step="1" value="0" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Длинный отдых, от (сек) <span class="tt" data-tip="Минимальный длинный отдых после серии ЛС (см. «Сообщений подряд»). 300с = 5 минут отдыха минимум. В ЛС безопаснее 5-15 минут.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-dm-burst-pause-min" min="0" step="1" value="600" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Длинный отдых, до (сек) <span class="tt" data-tip="Максимальная длинная пауза. Случайное значение между «мин» и «макс». 600с = до 10 минут — типичная пауза для ЛС.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-dm-burst-pause-max" min="0" step="1" value="1200" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Остановить акк, если Telegram просит ждать дольше (сек) <span class="tt" data-tip="Если Telegram попросил подождать N секунд — задача стопается только если N БОЛЬШЕ порога. Дефолт 300 (5 мин). FW короче — пережидаем и продолжаем. В ЛС лимиты жёстче, можешь поставить 600.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-dm-floodwait-stop" min="0" step="1" value="300" style="max-width:130px;"></div>
                </div>
            </div>
        </details>
        </div>
    </div>
            <div class="run-row">
            <div class="d-flex align-center justify-between">
                <span class="text-sm text-muted">
                    <i class="bi bi-people"></i> <span id="dm-count">0</span> юзеров
                </span>
                <div class="d-flex gap-3 align-center">
                    <button class="btn btn-outline btn-sm" onclick="exportDmResults()" data-tip="Выгрузка результатов: кому дошло / кому не дошло (приватность/спам/не найден)">
                        <i class="bi bi-folder2-open"></i> Выгрузка
                    </button>
                    <button class="btn btn-outline btn-sm" onclick="retryFailedDm()" data-tip="Запустить ещё раз только по тем юзерам, где не получилось">
                        <i class="bi bi-arrow-counterclockwise"></i> Повторить
                    </button>
                    <label class="form-label m-0" style="display:flex;align-items:center;gap:4px;font-size:0.72rem;cursor:pointer;" data-tip="Тест-режим: НИЧЕГО не отправляется. Софт проходит по целям и показывает сколько и куда отправил бы — проверить кампанию перед реальным запуском."><input type="checkbox" id="dm-dry-run" style="margin:0;"> Тест</label>
                    <button class="btn btn-pink btn-sm" onclick="startDm()" id="btn-dm" disabled
                            data-tip="Пределы Telegram: новым аккаунтам безопасно 20-50 личных сообщений в день, прогретым 200-300. Поймал спам-блок — 6 часов отдыха.">
                        <i class="bi bi-send"></i> Старт
                    </button>
                    <button class="btn btn-danger btn-sm" onclick="stopDm()" id="btn-dm-stop" disabled data-tip="Остановить рассылку в ЛС">
                        <i class="bi bi-stop-fill"></i> Стоп
                    </button>
                </div>
            </div>
            </div>
</div>

<!-- ═══ TAB: Подписка ═══ -->
<div class="section" id="tab-join">
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-box-arrow-in-right text-success"></i><div class="ch-text"><div class="ch-title">Вступление в чаты и группы</div><div class="card-sub">массовое вступление в чаты</div></div></div>
        <div class="card-body">
            <!-- Убран acc-selector — только мульти-пикер -->
            <div class="rd-group"><div class="rd-group-title">АККАУНТЫ</div>
            <div class="d-flex align-center gap-2 mb-2 flex-wrap" style="font-size:0.78rem;">
                <button class="btn btn-accent btn-sm" onclick="openJoinMultiPicker()" style="font-size:0.78rem;padding:5px 14px;">
                    <i class="bi bi-people"></i> Выбрать аккаунты
                </button>
                <span id="join-multi-count" style="color:var(--text-muted);font-weight:700;">0</span>
            </div>
            </div>
            <div class="info-box info-box--success">
                Вступление в чаты по списку ссылок с каждого выбранного аккаунта. Лимит и паузы считаются отдельно для каждого аккаунта.
            </div>
            <div class="rd-group"><div class="rd-group-title">ИСТОЧНИК ССЫЛОК</div>
            <label class="form-label">Список ссылок (по одной на строке)</label>
            <textarea class="form-control mb-2" id="join-links" rows="5"
                placeholder="https://t.me/channel1&#10;https://t.me/+invite_hash&#10;https://t.me/addlist/folder — папка развернётся в чаты&#10;@username"
                oninput="updateJoinCount()"></textarea>
            <label class="opt-row mb-2">
                <input type="checkbox" id="join-clean-dups">
                Чистить дубликаты в списке <span class="tt" data-tip="Выключено — список берётся как есть. Включи, чтобы повторы ссылок схлопывались в одну.">?</span>
            </label>

            <div class="d-flex gap-2 mb-2 flex-wrap">
                <label class="btn btn-outline btn-sm" style="cursor:pointer;margin:0;display:flex;align-items:center;">
                    <i class="bi bi-file-text"></i> Загрузить .txt
                    <input type="file" accept=".txt" style="display:none" onchange="loadJoinFile(this)">
                </label>
                <button class="btn btn-outline btn-sm" onclick="document.getElementById('join-links').value='';">
                    <i class="bi bi-trash text-danger"></i>
                </button>
            </div>
            </div>

            <div class="rd-group"><div class="rd-group-title">ЛИМИТЫ И ОПЦИИ</div>
            <div class="d-flex align-center gap-2 mb-2 flex-wrap">
                <label class="form-label" style="margin:0;font-size:0.78rem;">Лимит подписок с одного акка <span class="tt" data-tip="Сколько РАБОЧИХ чатов должен набрать один аккаунт за задачу. Считаются чаты, где он сможет писать: вступления и «уже состоит». Заявки в закрытые группы и группы, где отправка запрещена настройками чата, место в лимите не занимают — но в отчёте их видно. Если в списке почти всё закрытое, аккаунт остановится раньше: обращений к Telegram вдвое больше заказанного — это уже риск суточного ограничения. 0 — без лимита: идёт до конца списка или пока Telegram не попросит подождать. Безопасно 20-30 для свежих аккаунтов, 50 и больше для прогретых.">?</span></label>
                <input type="number" class="form-control" id="join-max-per-acc"
                       value="0" min="0" max="2000" step="1"
                       style="width:90px;font-size:0.8rem;padding:4px 8px;">
                <span class="text-sm text-muted fs-70">
                    0 = без лимита
                </span>
            </div>

            <label class="opt-row mb-2">
                <input type="checkbox" id="join-only-chats">
                Только чаты/группы — каналы пропускать <span class="tt" data-tip="Если включено — из списка вступаем ТОЛЬКО в группы и чаты (обычные группы и супергруппы), а каналы-вещатели (broadcast) пропускаем. Работает и по ссылкам-приглашениям (t.me/+…), и по публичным @/ссылкам: тип определяется ДО вступления, лишний запрос на канал не тратится. Папки-подборки (t.me/addlist) этой галкой не фильтруются. Пропущенные каналы в историю не пишутся — снимешь галку, повторный запуск их подхватит.">?</span>
            </label>

            <label class="opt-row mb-2">
                <input type="checkbox" id="s-join-autopilot" checked>
                Пережидать паузы и дописывать остаток, но не бесконечно <span class="tt" data-tip="Рекомендуется. Telegram попросил подождать — аккаунт ждёт, сбавляет темп и дописывает оставшиеся ссылки. Есть предохранитель: после четырёх таких кругов задача останавливается и сохраняет остаток, чтобы аккаунт не разлогинился. Снять галку — аккаунт остановится после третьей паузы, остаток допишете вручную или другим аккаунтом.">?</span>
            </label>

            <label class="opt-row mb-2">
                <input type="checkbox" id="s-join-fw-wait">
                Не останавливаться никогда, сколько бы Telegram ни просил ждать <span id="s-join-fw-wait-note" class="text-muted" style="font-size:0.78rem;"></span> <span class="tt" data-tip="Опасный режим, по умолчанию выключен. Снимает ВСЕ предохранители сразу: и предыдущую галочку, и порог «остановить, если просят ждать дольше», и дневную норму аккаунта. Задача дожмёт список до конца, сколько бы ни ждала. Почему опасно: паузы растут лавиной — сначала 5 минут, потом 9, потом полчаса, и аккаунт может разлогиниться. Разница с галочкой выше: там предохранитель есть, здесь его нет.">?</span>
            </label>
            </div>
            <script>
            // «Ждать любой пауза от Telegram» теперь ПЕРЕОПРЕДЕЛЯЕТ авто-стопы (в т.ч.
            // Автопилот): в join.py при wait_continue=ON count-брейкер и реактивный
            // адаптив не стопят. Поэтому НЕ гасим чекбокс — он работает всегда.
            (function() {
                function _syncJoinFw() {
                    var ap = document.getElementById('s-join-autopilot');
                    var fw = document.getElementById('s-join-fw-wait');
                    var note = document.getElementById('s-join-fw-wait-note');
                    if(!ap || !fw) return;
                    var row = fw.closest('.opt-row');
                    fw.disabled = false;
                    if(row) row.style.opacity = '1';
                    if(note) note.textContent = fw.checked
                        ? (ap.checked ? '(переопределяет Автопилот — дожмёт весь список)'
                                      : '(не остановится: ни флуд, ни «дневная норма»)')
                        : '';
                }
                var ap = document.getElementById('s-join-autopilot');
                var fw = document.getElementById('s-join-fw-wait');
                if(ap) ap.addEventListener('change', _syncJoinFw);
                if(fw) fw.addEventListener('change', _syncJoinFw);
                _syncJoinFw();
                setTimeout(_syncJoinFw, 1500);
                window._syncJoinFw = _syncJoinFw;
            })();
            </script>


            <details class="ad-block">
                <summary><i class="bi bi-shield-check"></i> Защита аккаунта</summary>
                <div class="ad-body">
                    <label class="ad-check"><input type="checkbox" id="join-pre-spam-check"> <span>Перед стартом проверить аккаунты на спам-блок</span></label>
                    <label class="ad-check"><input type="checkbox" id="join-solve-captcha"> <span>Решать капчу-боты в чатах<span class="ad-hint">Shieldy / MissRose / Combot — нажмём «я не бот»</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="join-keep-online"> <span>Держать аккаунт онлайн во время работы</span></label>
                    <label class="ad-check"><input type="checkbox" id="join-auto-leave-no-write"> <span>Сразу выйти если в чате нельзя писать<span class="ad-hint">Broadcast-каналы без права писать / группы где запрещена отправка — выйдем сразу после вступления</span></span></label>
                </div>
            </details>
        <!-- Тайминги вкладки Подписка (раскрывашка) -->
        <details class="ad-block">
            <summary>
                <i class="bi bi-clock"></i> Тайминги подписки
                <span class="ts-sync-badge" title="Статус синхронизации с бэк-эндом — что реально записано в настройках">✓ сохранено</span>
            </summary>
            <div class="ad-body">
                <div class="info-box info-box--warning">
                    Чем быстрее тайминги — тем выше шанс бана. Для новых акков ставьте паузы x2.
                </div>
                <div class="mb-2">
                    <button type="button" class="btn btn-outline btn-sm btn-preset" onclick="applyTimingPreset('join')" data-tip="40±10с между подписками, длинная пауза 5-10 мин — Telegram любит неспешные вступления, меньше банов на свежих акках."><i class="bi bi-shield-check" style="color:var(--success);"></i> Рекомендуемый (безопасный)</button>
                </div>
                <div class="grid-3 mb-2">
                    <div class="mb-2"><label class="form-label">Пауза между (сек) <span class="tt" data-tip="Базовая пауза между двумя подписками с одного акка. Например 18 — после каждой подписки следующая через 18 секунд. Telegram любит подписки 30+ сек, новым аккам ставь 30-45с.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-join-interval" min="0" step="1" value="40" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Случайность ±сек <span class="tt" data-tip="Случайный разброс к базовой паузе. Если «Пауза между» = 18 и «Случайность» = 3 — реальная пауза будет от 18 до 21с (а не ровно 18 каждый раз). Делает поведение менее как у бота. 0 = всегда ровно 18с (хуже).">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-join-jitter" min="0" step="1" value="10" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Подписок подряд, потом длинный отдых <span class="tt" data-tip="После стольких подписок акк уходит в длинный отдых. Защита от заморозки свежих акков.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-join-max" min="0" step="1" value="10" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Длинный отдых, от (сек) <span class="tt" data-tip="Минимальный длинный отдых после серии подписок (включается каждые 10 подписок). 180с = 3 минуты отдыха минимум. Чем больше — тем безопаснее для свежего акка.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-join-break" min="0" step="1" value="300" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Длинный отдых, до (сек) <span class="tt" data-tip="Максимальная длинная пауза. Совмещает с «мин» — софт берёт случайное число секунд из этого диапазона. 360с = до 6 минут.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-join-break-max" min="0" step="1" value="600" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Остановить акк, если Telegram просит ждать дольше (сек) <span class="tt" data-tip="Если Telegram попросил подождать N секунд — задача останавливается только если N БОЛЬШЕ этого порога. Дефолт 300 (5 мин). пауза от Telegram короче — просто пережидаем и продолжаем. пауза от Telegram меньше 5 минут — это обычный пейсинг Telegram, а не повод паниковать. Поставь 600 если хочешь дать больше шансов; 60 — старое жёсткое поведение (стоп при любом FW > 1 мин).">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-join-floodwait-stop" min="0" step="1" value="300" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">Макс. отдых автопилота (сек) <span class="tt" data-tip="Когда акк упирается в дневной лимит Telegram, автопилот уводит его в ДЛИННЫЙ отдых (по умолчанию до 4 часов) — это не «Длинный отдых» выше, а отдельная защита от разлогина. Здесь можно урезать этот отдых: 14400 = дефолт (до 4 часов), 3600 = максимум один час. Ставить мало рискованно: короткий отдых в «горячем окне» наблюдения Telegram повышает шанс разлогина акка. Реальный лимит Telegram пережидается всегда, независимо от этого поля.">?</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="s-join-ap-maxrest" min="60" step="60" value="14400" style="max-width:130px;"></div>
                </div>
            </div>
        </details>
        </div>
    </div>
            <div class="run-row">
            <div class="d-flex align-center justify-between">
                <span class="text-sm text-muted">
                    <i class="bi bi-link-45deg"></i> <span id="join-count">0</span> ссылок
                </span>
                <div class="d-flex gap-3 align-center">
                    <button class="btn btn-outline btn-sm" onclick="exportJoinResults()" data-tip="Выгрузка результатов последней подписки: отдельно подписавшиеся и отдельно ошибки — для перезапуска на другом аккаунте">
                        <i class="bi bi-folder2-open"></i> Выгрузка
                    </button>
                    <button class="btn btn-outline btn-sm" onclick="retryFailedJoin()" data-tip="Подставить в список только те ссылки, где не вышло — и нажать Старт на выбранном аккаунте">
                        <i class="bi bi-arrow-counterclockwise"></i> Повторить
                    </button>
                    <label class="form-label m-0" data-tip="Сколько акков одновременно подписываются. 0 = все выбранные параллельно. N = только N в работе.">Потоки <span class="text-muted" style="font-size:0.7rem;">?</span></label>
                    <input type="number" class="form-control" id="join-threads" value="0" min="0" max="100" style="width:70px;">
                    <button class="btn btn-success btn-sm" onclick="startJoin()" id="btn-join" disabled
                            data-tip="Лимиты Telegram: подписка ~50 чатов/час безопасно, ChannelsTooMuch при ~500 общем числе чатов на акке (надо чистить).">
                        <i class="bi bi-play-fill"></i> Старт
                    </button>
                    <button class="btn btn-danger btn-sm" onclick="stopJoin()" id="btn-join-stop" disabled data-tip="Остановить вступление">
                        <i class="bi bi-stop-fill"></i> Стоп
                    </button>
                </div>
            </div>
            </div>
</div>

<!-- ═══ TAB: Инвайтер ═══ -->
<div class="section" id="tab-invite">
    <div style="display:flex;gap:8px;flex-wrap:wrap;margin-bottom:14px;">
        <button class="btn btn-outline btn-sm" onclick="inviteShowSubtab('main')" id="inv-sub-main" style="font-weight:500;"><i class="bi bi-list-ul"></i> Список чатов <span id="inv-chats-cnt" class="badge ml-1">0</span></button>
        <button class="btn btn-outline btn-sm" onclick="inviteShowSubtab('userdb')" data-tip="Кому уже отправляли инвайты — чтобы не звать повторно"><i class="bi bi-people"></i> История приглашённых <span id="inv-userdb-cnt" class="badge ml-1">0</span></button>
        <button class="btn btn-outline btn-sm" onclick="inviteShowSubtab('reports')"><i class="bi bi-clipboard-data"></i> Отчёты</button>
    </div>

    <!-- ── Sub-tab: Список чатов ── -->
    <div id="inv-tab-main">
        <div class="card mb-3">
            <div class="card-body">
                <div class="info-box info-box--warning" style="margin-bottom:14px;font-size:0.78rem;">
                    Акки сами вступают в чат при старте и выходят после завершения.
                </div>

            <div class="rd-group"><div class="rd-group-title">РЕЖИМ И ЦЕЛЬ</div>
                <label class="form-label">Режим работы <span class="tt" data-tip="Обычный — аккаунты-инвайтеры уже состоят в чате и приглашают сами по очереди. Через админку — главный аккаунт временно даёт остальным права администратора (на инвайт), потом снимает обратно. Полезно для свежих акков и для чатов где у обычных юзеров нет прав приглашать.">?</span></label>
                <select class="form-control mb-3" id="inv-mode" onchange="inviteToggleAdminBlock()">
                    <option value="direct">Обычный (без админки)</option>
                    <option value="via_admin">Через админку</option>
                </select>

                <label class="form-label">Целевой чат / канал <span class="tt" data-tip="Сюда инвайтим юзеров. Можно: @username (только для публичных чатов), числовой ID вида -1001234567890, или ссылку https://t.me/...">?</span></label>
                <input type="text" class="form-control mb-3" id="invite-chat"
                    placeholder="@chatname или -1001234567890 или https://t.me/chatname">

                <div id="inv-admin-block" style="display:none;">
                    <div class="callout callout-info mb-3" style="background:rgba(139,92,246,0.08);border-left:3px solid var(--accent-light);padding:12px 14px;border-radius:4px;font-size:0.74rem;line-height:1.6;">
                        <div style="font-weight:600;color:var(--accent-light);margin-bottom:6px;"><i class="bi bi-diagram-3"></i> Как работает «через админку»</div>
                        <div style="color:var(--text-secondary);">
                            <b>1.</b> Главный админ <b>уже в чате</b> и имеет право «Добавлять администраторов».<br>
                            <b>2.</b> Софт автоматически промоутит первых 3 акка в seed-админов (с правом промоутить других) — это нужно чтобы дальше нагрузка распределилась.<br>
                            <b>3.</b> Seed-админы по очереди промоутят остальных акков в простых админов с правом инвайта.<br>
                            <b>4.</b> Каждый промоутнутый акк инвайтит свою порцию юзеров.<br>
                            <b>5.</b> После инвайта софт <b>сам</b> снимает админку с акка (демоут).<br>
                            <b>Плюс режима:</b> работает даже если у обычных юзеров чата отключено право приглашать, плюс свежие акки выживают дольше (Telegram мягче к админам).<br>
                            <b>Минус:</b> главный админ должен быть надёжным акком в чате, и Telegram имеет лимит ~50 админов на чат — если уже близко, режим не сработает.
                        </div>
                    </div>
                    <label class="form-label">Главный админ <span class="tt" data-tip="Аккаунт который выдаст права остальным. Должен УЖЕ быть в чате и иметь право «Добавлять администраторов». Достаточно одного на всю задачу.">?</span></label>
                    <input type="text" class="form-control mb-3" id="inv-main-admin"
                        placeholder="79xxxxxxxxx — номер акка-главного-админа">
                </div>
            </div>

            <div class="rd-group"><div class="rd-group-title">КОГО ИНВАЙТИМ</div>
                <label class="form-label">Кого приглашаем (@юзернейм или числовой ID, по одному на строку)</label>
                <textarea class="form-control mb-2" id="invite-targets" rows="6"
                    placeholder="@user1&#10;123456789&#10;+79991234567 — по номеру (найдём как в TG, если номер не скрыт)"></textarea>
                <div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
                    <button type="button" class="btn btn-outline btn-sm fs-72" onclick="loadInviteFromParser()"><i class="bi bi-magic"></i> Из парсинга</button>
                    <button type="button" class="btn btn-outline btn-sm fs-72" onclick="document.getElementById('invite-targets-file').click()"><i class="bi bi-file-earmark-text"></i> Из .txt</button>
                    <button type="button" class="btn btn-outline btn-sm fs-72" onclick="loadInviteFromUserdb()"><i class="bi bi-database"></i> Из базы юзеров</button>
                    <input type="file" id="invite-targets-file" accept=".txt,.csv" style="display:none" onchange="onInviteTargetsFile(event)">
                    <span id="invite-targets-count" style="margin-left:auto;font-size:0.72rem;color:var(--text-muted);"></span>
                </div>
                <label class="ad-check" style="margin-bottom:12px;"><input type="checkbox" id="invite-del-contact" checked> <span>Удалять контакт после инвайта (для целей по номеру)<span class="ad-hint">Поиск по номеру добавляет контакт в книгу акка. Удаляем после инвайта — иначе акк копит чужие номера = сигнал спам-фермы для Telegram.</span></span></label>
            </div>

                <details class="ad-block" open>
                    <summary>
                        <i class="bi bi-people-fill"></i> Аккаунты-инвайтеры
                    </summary>
                    <div class="ad-body">
                        <div class="d-flex align-center gap-2 mb-2">
                            <button type="button" class="btn btn-accent btn-sm" onclick="openInviteAccPopup()" id="btn-invite-acc-pick" style="font-size:0.78rem;padding:5px 14px;">
                                <i class="bi bi-people"></i> Выбрать аккаунты
                            </button>
                            <span id="invite-acc-count" style="color:var(--text-muted);font-weight:700;">все живые</span>
                            <span class="tt" data-tip="Если ничего не выбрано — софт автоматически использует ВСЕХ живых акков (не мёртвые, не замороженные). Если выбрал несколько — будет идти только по ним. Кнопка «Сбросить» снимает выбор → опять всех живых.">?</span>
                            <button type="button" class="btn btn-outline btn-sm" style="margin-left:auto;font-size:0.66rem;" onclick="clearInviteAccs()">
                                <i class="bi bi-x"></i> Сбросить (=все живые)
                            </button>
                        </div>
                        <div id="invite-acc-list" class="d-flex flex-wrap gap-2 mb-2" style="display:none;"></div>
                        <div style="font-size:0.66rem;color:var(--text-muted);line-height:1.5;">
                            Если ничего не выбрано — софт распределит инвайт по всем живым аккам автоматически.
                        </div>
                    </div>
                </details>
            </div>
        </div>

        <!-- Тайминги -->
        <div class="card mb-3">
            <div class="card-header"><i class="bi bi-sliders"></i><div class="ch-text"><div class="ch-title">Тайминги и лимиты</div><div class="card-sub">добавление людей в ваши чаты</div></div></div>
            <div class="card-body">
                <div class="grid-2 mb-2">
                    <div>
                        <label class="form-label fs-72">Пауза между инвайтами, от (сек) <span class="tt" data-tip="Минимальная пауза между двумя инвайтами с одного акка. Каждый раз софт берёт случайное значение между «мин» и «макс». Чем больше пауза — тем меньше риск спам-блока. Рекомендую минимум 30 секунд.">?</span></label>
                        <input type="number" class="form-control" id="invite-pause-min" value="60" min="5" max="600">
                    </div>
                    <div>
                        <label class="form-label fs-72">Пауза между инвайтами, до (сек) <span class="tt" data-tip="Максимальная пауза. Случайный разброс между «мин» и «макс» делает поведение менее похожим на бота. На практике пауза от 120с заметно безопаснее, чем 30–70с.">?</span></label>
                        <input type="number" class="form-control" id="invite-pause-max" value="120" min="6" max="900">
                    </div>
                </div>
                <div class="grid-2 mb-2">
                    <div>
                        <label class="form-label fs-72">Лимит успешных инвайтов с акка подряд <span class="tt" data-tip="После N успешных инвайтов с этого акка софт переключается на следующий из пула, чтобы не сжечь его в вечный спам-блок. По умолчанию 20-40, для очень свежих акков понизь до 10.">?</span></label>
                        <input type="number" class="form-control" id="invite-max-per-acc" value="40" min="1" max="500">
                    </div>
                    <div>
                        <label class="form-label fs-72">Отдых акка после спам-блока: <span class="tp-sec-hint" data-for="invite-flood-cooldown-sec"></span> <span class="tt" data-tip="Акк словил спам-блок на инвайтах (спам-блок) — столько он не используется. По умолчанию 86400 сек = 24 часа: Telegram обычно снимает блок за 24-72 часа, а повторная попытка через час ловит второй блок и сжигает акк насовсем. Жёстче — поставь 259200 (3 суток).">?</span></label>
                        <div style="display:flex;gap:6px;align-items:center;">
                            <!-- Границы = ровно то, что принимает бэкенд
                                 (invite/routes.py: 360..4320 мин), иначе UI обещал бы
                                 диапазон, который сервер молча обрежет. -->
                            <input type="number" class="form-control tp-sec" id="invite-flood-cooldown-sec" value="86400" min="21600" max="259200" step="3600">
                            <span style="font-size:0.72rem;color:var(--text-muted);">сек</span>
                        </div>
                    </div>
                </div>
                <div class="grid-2 mb-2">
                    <div>
                        <label class="form-label fs-72">Ежечасный лимит на акк <span class="tt" data-tip="Максимум инвайтов с одного акка за последний час. Хорошая защита от спам-блока — софт считает скользящее окно за час и не трогает акк, пока лимит не освободится.">?</span></label>
                        <input type="number" class="form-control" id="invite-hourly-limit" value="40" min="1" max="200">
                    </div>
                    <div>
                        <label class="form-label fs-72">Стоп после N подряд privacy <span class="tt" data-tip="Если N подряд юзеров отказали по приватности — задача останавливается. Полезно если список плохой (все стоят с приватностью «не разрешать инвайты») — лучше остановить и попробовать другой источник юзеров. 0 = не останавливать.">?</span></label>
                        <input type="number" class="form-control" id="invite-stop-on-privacy" value="0" min="0" max="100">
                    </div>
                </div>
            </div>
        </div>

        <!-- Доп опции -->
        <div class="card mb-3">
            <div class="card-header cursor-pointer" onclick="this.nextElementSibling.style.display = this.nextElementSibling.style.display==='none'?'':'none'">
                <i class="bi bi-three-dots"></i> Дополнительные опции
            </div>
            <div class="card-body" style="display:none;">
                <div class="grid-2 mb-2">
                    <div>
                        <label class="form-label fs-72">Сколько спамблоков пропускать с акка <span class="tt" data-tip="После N подряд вечный спам-блок от одного акка софт окончательно помечает его «сожжённым» и переносит в папку «После инвайта/Спамблок». Дефолт 1 = после первого вечный спам-блок переносим. Если поставить 3 — даём акку 3 шанса (но это редко имеет смысл, после первого спамблока он уже не работает).">?</span></label>
                        <input type="number" class="form-control" id="inv-spamblock-skip" value="1" min="0" max="100">
                    </div>
                    <div>
                        <label class="form-label fs-72">Лимит «списаний» на акк <span class="tt" data-tip="«Списание» = после инвайта юзер мгновенно вылетает из чата (Telegram отбрасывает за защиту от спама). Telegram отвечает софту что инвайт прошёл, но юзера в чате нет. Если N таких списаний на одном акке — пометить его как сжёгся. По умолчанию 999 = практически выкл.">?</span></label>
                        <input type="number" class="form-control" id="inv-chargeback" value="999" min="1" max="100000">
                    </div>
                </div>
                <div class="grid-2 mb-2">
                    <div>
                        <label class="form-label fs-72">Лимит больших задержек в чате <span class="tt" data-tip="Когда акк получает большую флуд-блок (часы/сутки) — это часто значит что что-то не так с самим чатом (Telegram считает его проблемным). Если в одном чате накопилось N таких задержек, инвайт в этот чат останавливается. По умолчанию 9999 = выкл.">?</span></label>
                        <input type="number" class="form-control" id="inv-big-fw" value="9999" min="1" max="100000">
                    </div>
                    <div>
                        <label class="form-label fs-72">Пауза между вступлениями акков в чат (сек) <span class="tt" data-tip="Каждый аккаунт вступает в чат по очереди — пауза между вступлениями случайная в этом диапазоне. Растягиваем массовое вступление чтобы не словить флуд-блок и не показывать «волну» новых участников. По умолчанию 7-15 сек.">?</span></label>
                        <div class="row-gap-6" >
                            <input type="number" class="form-control flex-1" id="inv-delay-join-min" value="7" min="0" max="600">
                            <input type="number" class="form-control flex-1" id="inv-delay-join-max" value="15" min="1" max="900">
                        </div>
                    </div>
                </div>
                <div class="grid-2 mb-2">
                    <div>
                        <label class="form-label fs-72">Пауза между выдачей прав и инвайтом (сек) <span class="tt" data-tip="В режиме «Через админку» — пауза между выдачей прав каждому акку. И во всех режимах — пауза после выдачи прав, перед началом приглашений. Слишком быстро — главный акк может схлопотать флуд-блок.">?</span></label>
                        <div class="row-gap-6" >
                            <input type="number" class="form-control flex-1" id="inv-delay-promote-min" value="5" min="0" max="600">
                            <input type="number" class="form-control flex-1" id="inv-delay-promote-max" value="12" min="1" max="900">
                        </div>
                    </div>
                    <div>
                        <label class="form-label fs-72">Помощников у главного админа <span class="tt" data-tip="Только в режиме «Через админку». Главный админ выдаст права на «добавление админов» сразу нескольким аккам — они станут помощниками и помогут раздавать права остальным. 1 = всех делает один главный (медленно для 30+ акков). 3-5 — оптимально. Больше — главный риск переутомить себя и схлопотать флуд-блок.">?</span></label>
                        <input type="number" class="form-control" id="inv-cascade-seed" value="3" min="1" max="20">
                    </div>
                </div>
                <label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:0.78rem;margin-bottom:8px;">
                    <input type="checkbox" id="inv-set-spamblock" checked> Запоминать кому уже отправляли инвайты <span class="tt" data-tip="После инвайта юзер попадает в базу с пометкой (приглашён / приватность / спам-блок). В следующий раз инвайтер пропустит таких — не спам ему повторно.">?</span>
                </label>
                <label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:0.78rem;margin-bottom:8px;">
                    <input type="checkbox" id="inv-skip-chatinvalid" checked> Пропускать ошибки прав в чате <span class="tt" data-tip="Если у акка нет прав в чате — Telegram возвращает ошибку. Включено: софт пропускает и идёт дальше. Выключено: останавливается на первой такой ошибке.">?</span>
                </label>
                <label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:0.78rem;margin-bottom:8px;">
                    <input type="checkbox" id="inv-leave-worker" checked> Выходить из группы после инвайта (обычным аккам) <span class="tt" data-tip="После завершения задачи акки-инвайтеры покидают чат — чтобы их не было видно среди участников. Главного админа это не касается (у него отдельная настройка ниже).">?</span>
                </label>
                <label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:0.78rem;margin-bottom:8px;">
                    <input type="checkbox" id="inv-leave-admin"> Выходить из группы после инвайта (главному админу) <span class="tt" data-tip="Применимо только в режиме «Через админку». Обычно главный админ остаётся в чате (он же и так твой основной), но если ты хочешь чтобы и он вышел — включи.">?</span>
                </label>
                <label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:0.78rem;margin-bottom:8px;">
                    <input type="checkbox" id="inv-archive"> Добавлять группу в архив и отключать оповещения <span class="tt" data-tip="Применяется к каждому акку-инвайтеру: после инвайта чат уйдёт в архив и звуки в нём отключатся. Полезно если акк остаётся в чате — чтобы не получать оттуда уведомлений.">?</span>
                </label>
            </div>
        </div>

        <!-- Настройки прав -->
        <div class="card mb-3">
            <div class="card-header cursor-pointer" onclick="this.nextElementSibling.style.display = this.nextElementSibling.style.display==='none'?'':'none'">
                <i class="bi bi-shield-check"></i> Настройки прав (для инвайта через админку)
            </div>
            <div class="card-body" style="display:none;">
                <div style="background:var(--surface-info-bg);border:1px solid var(--surface-info-border);border-radius:4px;padding:10px;margin-bottom:12px;font-size:0.7rem;color:var(--text-muted);">
                    Это права, которые главный админ выдаёт инвайтящим аккам. Чтобы он мог их выдать — он должен сам ими обладать.
                </div>
                <label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:0.78rem;margin-bottom:6px;"><input type="checkbox" id="inv-r-changeinfo"> Изменение профиля группы</label>
                <label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:0.78rem;margin-bottom:6px;"><input type="checkbox" id="inv-r-deletemsg"> Удаление сообщений</label>
                <label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:0.78rem;margin-bottom:6px;"><input type="checkbox" id="inv-r-banusers"> Блокировка участников</label>
                <label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:0.78rem;margin-bottom:6px;"><input type="checkbox" id="inv-r-managecall"> Управление видеочатами</label>
                <label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:0.78rem;margin-bottom:6px;"><input type="checkbox" id="inv-r-pin"> Закрепление сообщений</label>
                <label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:0.78rem;margin-bottom:6px;"><input type="checkbox" id="inv-r-anon" checked> Анонимность</label>
            </div>
        </div>

        <!-- Папки -->
        <div class="card mb-3">
            <div class="card-header cursor-pointer" onclick="this.nextElementSibling.style.display = this.nextElementSibling.style.display==='none'?'':'none'">
                <i class="bi bi-folder2-open"></i> Настройки папок
            </div>
            <div class="card-body" style="display:none;">
                <label class="form-label fs-72">Папка для аккаунтов, получивших спамблок <span class="tt" data-tip="Куда переехать акку после получения вечный спам-блок (с учётом «Сколько спамблоков пропускать»). Папка создаётся автоматически если её нет. Путь относительно корня клиента, должен начинаться с «Аккаунты/».">?</span></label>
                <input type="text" class="form-control mb-2" id="inv-folder-spamblock" value="Аккаунты/После инвайта/Спамблок">
                <label class="form-label fs-72">Папка для слишком свежих аккаунтов <span class="tt" data-tip="В режиме «Через админку» Telegram не разрешает выдавать админ-права акку младше 24 часов. Такие аккаунты софт переместит сюда — пусть полежат сутки, потом попробуй снова.">?</span></label>
                <input type="text" class="form-control mb-2" id="inv-folder-fresh" value="Аккаунты/После инвайта/Слишком свежая сессия для изменения прав">
                <label class="form-label fs-72">Папка для аккаунтов, получивших лимит на поиск <span class="tt" data-tip="Telegram иногда временно запрещает аккам резолвить юзеров по @username (поиск). Если такое случилось — акк переезжает сюда, чтобы не тратить его в дальнейшем. Лимит сбрасывается через сутки-двое.">?</span></label>
                <input type="text" class="form-control mb-2" id="inv-folder-search" value="Аккаунты/После инвайта/Лимит на поиск по номерам">
            </div>
        </div>

        <details class="ad-block">
            <summary><i class="bi bi-shield-check"></i> Защита аккаунта</summary>
            <div class="ad-body">
                <label class="ad-check"><input type="checkbox" id="inv-pre-spam-check"> <span>Перед стартом проверить аккаунты на спам-блок<span class="ad-hint">Заблокированные пропустим</span></span></label>
                <label class="ad-check"><input type="checkbox" id="inv-solve-captcha"> <span>Решать капчу-боты в чатах<span class="ad-hint">Если в чате есть антиспам-бот — нажмём «я не бот»</span></span></label>
                <label class="ad-check"><input type="checkbox" id="inv-keep-online"> <span>Держать аккаунт онлайн во время работы</span></label>
                <label class="ad-check"><input type="checkbox" id="inv-view-profile"> <span>Смотреть профиль цели перед инвайтом<span class="ad-hint">Имитация — открыть профиль как живой человек</span></span></label>
                <label class="ad-check"><input type="checkbox" id="inv-view-photo"> <span>Смотреть фото профиля цели</span></label>
            </div>
        </details>


        <div id="invite-progress" style="display:none;">
            <div style="background:var(--surface-info-bg);border-radius:5px;padding:12px;margin-bottom:8px;">
                <div style="display:flex;justify-content:space-between;font-size:0.78rem;margin-bottom:6px;">
                    <span><b id="invite-status-label">—</b></span>
                    <span id="invite-elapsed" style="color:var(--text-muted);font-size:0.7rem;">—</span>
                </div>
                <div class="progress mb-2"><div class="progress-bar" id="invite-bar" style="width:0%;"></div></div>
                <div id="invite-counts" style="display:flex;gap:14px;flex-wrap:wrap;font-size:0.74rem;"></div>
            </div>
        </div>
        <div class="run-row">
        <div class="d-flex gap-2 mb-3">
        <button class="btn btn-accent" onclick="startInvite()" id="btn-invite-start"
                data-tip="Пределы Telegram: 50 приглашений в сутки — мягкий, 200 — жёсткий, дальше Telegram надолго просит подождать. Лимит общий на акк (на все каналы суммарно). Жалоба на 1 канал владельца снижает лимиты на ВСЕ его каналы.">
            <i class="bi bi-play-fill"></i> Старт инвайта
        </button>
        <button class="btn btn-outline" onclick="saveInviteSettings()"><i class="bi bi-save"></i> Сохранить настройки</button>
        <button class="btn btn-danger" onclick="stopInvite()" id="btn-invite-stop" style="display:none;"><i class="bi bi-stop-fill"></i> Стоп</button>
        <button class="btn btn-outline" onclick="exportInviteResults()" id="btn-invite-export" style="display:none;"><i class="bi bi-download"></i> Скачать отчёт</button>
        </div>
        </div>
    </div>

    <!-- ── Sub-tab: История приглашённых ── -->
    <div id="inv-tab-userdb" style="display:none;">
        <div class="card">
            <div class="card-body">
                <div class="info-box note-row">
                    Тут хранятся юзеры, кому уже отправляли инвайты — чтобы не приглашать их повторно. Каждый помечен тегом: <b>«приглашён»</b>, <b>«приватность»</b>, <b>«спам-блок»</b>. Можно импортировать готовый список из .txt и пометить вручную.
                </div>
                <div style="display:flex;gap:8px;margin-bottom:10px;flex-wrap:wrap;">
                    <input type="text" class="form-control" id="inv-userdb-search" placeholder="Поиск по @username или id" style="flex:1;min-width:160px;" oninput="loadInviteUserdb()">
                    <button class="btn btn-outline btn-sm" onclick="document.getElementById('inv-userdb-import').click()"><i class="bi bi-cloud-upload"></i> Импорт .txt</button>
                    <button class="btn btn-outline btn-sm" onclick="exportInviteUserdb()"><i class="bi bi-download"></i> Экспорт</button>
                    <button class="btn btn-danger btn-sm" onclick="clearInviteUserdb()"><i class="bi bi-trash"></i> Очистить</button>
                    <input type="file" id="inv-userdb-import" accept=".txt,.csv" style="display:none" onchange="onInviteUserdbImport(event)">
                </div>
                <div id="inv-userdb-list" style="max-height:520px;overflow-y:auto;font-family:monospace;font-size:0.78rem;background:var(--bg-input);border:1px solid var(--border);border-radius:5px;padding:8px;">Загрузка…</div>
            </div>
        </div>
    </div>

    <!-- ── Sub-tab: Отчёты ── -->
    <div id="inv-tab-reports" style="display:none;">
        <div class="card">
            <div class="card-body">
                <div id="inv-reports-list" style="font-size:0.85rem;">Запусков ещё не было — отчёты появятся после первого инвайта</div>
            </div>
        </div>
    </div>
</div>

<div class="section" id="tab-accounts">
    <!-- Баннер с реальным путём к папке Аккаунты — показывает куда класть .session/.json. -->
    <div id="accounts-path-banner" class="accounts-path-banner">
        <i class="bi bi-folder2-open"></i>
        <span>Папка аккаунтов: <code id="accounts-path-value">загрузка…</code></span>
    </div>

    <!-- Предупреждение: на машине запущено >1 копии TelePush. Каждая читает СВОЮ
         папку — показываем какая где и сколько аккаунтов, чтобы юзер не потерял акки. -->
    <div id="multicopy-banner" class="multicopy-banner" style="display:none;">
        <i class="bi bi-exclamation-triangle-fill"></i>
        <div class="mc-body">
            <div class="mc-title">Запущено <span id="mc-count">2</span> копии TelePush — каждая со своей папкой аккаунтов</div>
            <div id="mc-list" class="mc-list"></div>
        </div>
    </div>

    <!-- Карточка «Добавить аккаунт» убрана по решению владельца 12.08.2026:
         вход по номеру, по QR и списком номеров сняты целиком. Аккаунты
         добавляются готовыми парами через папку «В работе» — кнопка
         «Обновить» осталась в панели действий ниже. -->

    <!-- Статус-фильтр (живой/мёртвый/заморожен/спам) -->
    <!-- status chips удалены: папки сверху фильтруют по локации, статус виден badge'ом в строке акка. -->
    <div id="acc-status-row" style="display:none;"></div>

    <!-- Статистика аккаунтов (динамические фильтры по папкам) -->
    <div class="acc-stats-row mb-3 flex-wrap" id="acc-stats-row"></div>

    <!-- Панель действий. Раскладка — в .acc-toolbar (style.css): кнопки тут
         разной ширины, и на узком окне ряд рвался рваными интервалами, а счётчик
         справа улетал на отдельную строку к самому краю. -->
    <div class="acc-toolbar mb-2">
        <div class="acc-toolbar__main">
            <button class="btn btn-outline btn-sm" onclick="checkAllSpam()" id="btn-check-all-spam">
                <i class="bi bi-shield-check"></i> Проверить спам <span class="tt" data-tip="Если в таблице ничего не отмечено — проверим все аккаунты. Если есть галки — проверим только их.">?</span>
            </button>
            <!-- Настройка потоков прямо рядом, не в раскрывашке -->
            <label style="display:flex;align-items:center;gap:4px;font-size:0.72rem;color:var(--text-muted);" data-tip="Сколько акков проверять одновременно. 0 = авто: подбирается по размеру пула прокси (до 24), без прокси — 8, чтобы не палить burst с одного IP. Своё число уважаем как есть.">
                Потоков:
                <input type="number" class="form-control" id="acc-spam-threads" min="0" max="200" value="5" placeholder="5" style="width:56px;padding:5px 8px;font-size:0.72rem;" onchange="localStorage.setItem('tp_spam_threads', this.value)">
            </label>
            <button class="btn btn-outline btn-sm" onclick="syncAndReload()" data-tip="Синхронизировать с папкой">
                <i class="bi bi-arrow-clockwise"></i>
            </button>
            <button class="btn btn-outline btn-sm" onclick="showAccountsActivity()" data-tip="Показать, какие аккаунты сейчас чем заняты — сгруппировано по задачам (рассылка, прогрев, мониторинг и т.д.).">
                <i class="bi bi-activity"></i> Кто чем занят
            </button>
            <select id="acc-select-by-type" class="form-control" style="width:186px;padding:5px 10px;font-size:0.75rem;" onchange="selectAccountsByType(this.value); this.value='';"
                    data-tip="Отмечает СРАЗУ ВСЕ аккаунты нужного типа — вместо того чтобы тыкать галки по одной. Работает по тому, что сейчас видно в таблице (учитывает вкладку, поиск и фильтр тегов). Дальше жми «Перенести».">
                <option value="">Выделить разом…</option>
                <option value="unchecked">Не проверялся</option>
                <option value="spam">Со спам-блоком</option>
                <option value="dead">Мёртвые (подтверждённые)</option>
                <option value="frozen">Заморозка</option>
                <option value="clean">Проверенные чистые</option>
                <option value="invert">Инвертировать</option>
                <option value="none">Снять выделение</option>
            </select>
            <button class="btn btn-outline btn-sm" onclick="moveSelectedToFolder()" data-tip="Переместить отмеченные аккаунты в другую папку">
                <i class="bi bi-box-arrow-right"></i> Перенести
            </button>
            <button class="btn btn-outline btn-sm" onclick="open2faModal()" data-tip="Поставить / сменить / снять облачный пароль (2FA) у отмеченных аккаунтов. Текущий пароль для смены берётся из .json пары.">
                <i class="bi bi-shield-lock"></i> 2FA
            </button>
            <button class="btn btn-outline btn-sm" onclick="resetProxySelected()" data-tip="Снять закрепление прокси с отмеченных аккаунтов — вернутся к раздаче по номеру.">
                <i class="bi bi-hdd-network"></i> Сбросить прокси
            </button>
            <div class="acc-toolbar__find">
                <input type="text" class="form-control" id="acc-search" placeholder="Поиск..." style="padding:5px 10px;font-size:0.75rem;" oninput="filterAccountsTable()">
                <select id="acc-tag-filter" class="form-control" style="width:140px;padding:5px 10px;font-size:0.75rem;" onchange="filterAccountsTable()">
                    <option value="">Все теги</option>
                </select>
            </div>
        </div>
        <div class="acc-toolbar__aside">
            <span class="text-xs text-muted">Показано: <span id="acc-shown">0</span> / <span id="acc-total">0</span></span>
            <span class="text-xs text-muted" id="acc-heartbeat-summary" style="display:none;"></span>
            <select id="acc-page-size" class="form-control" onchange="accChangePageSize()" style="width:100px;padding:4px 8px;font-size:0.72rem;">
                <option value="30">30</option>
                <option value="100">100</option>
                <option value="500" selected>500</option>
                <option value="0">Все</option>
            </select>
            <div class="d-flex gap-1 align-center" id="acc-pager" style="display:none;">
                <button class="btn btn-outline btn-sm" onclick="accPrevPage()" style="padding:4px 8px;"><i class="bi bi-chevron-left"></i></button>
                <span class="text-xs text-muted" id="acc-page-info">1 / 1</span>
                <button class="btn btn-outline btn-sm" onclick="accNextPage()" style="padding:4px 8px;"><i class="bi bi-chevron-right"></i></button>
            </div>
        </div>
    </div>

    <!-- Таблица аккаунтов -->
    <style>
      /* table-layout:fixed + клиппинг ячеек: таблица всегда влезает в окно,
         заголовки и значения не налезают друг на друга, длинный текст → «…». */
      #accounts-table { table-layout:fixed; width:100%; }
      #accounts-table th, #accounts-table td {
        overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
        vertical-align:middle;
      }
      #accounts-table th { padding-left:6px; padding-right:2px; font-size:0.64rem; letter-spacing:0; }
      /* колонка # — узкий padding, чтобы трёхзначный номер (до 252) не обрезался в «2…» */
      #accounts-table th:nth-child(2), #accounts-table td:nth-child(2) { padding-left:2px; padding-right:2px; }
      /* колонка Статус (5) — бейджи, перенос вместо ellipsis (overflow:hidden наследуется),
         иначе бейдж дорисовывался «...». */
      #accounts-table td:nth-child(5) { white-space:normal; }
      #accounts-table th .sort-arrow { margin-left:1px; }
      /* Короткие колонки (#, Гео, Статус, Отлёжка, Теги) — значения и заголовки
         по центру. Телефон/Прокси/Имя — слева (длинный текст), Действия — справа.
         Колонки: 1=cb 2=# 3=Телефон 4=Гео 5=Статус 6=Прокси 7=Отлёжка 8=Имя 9=Теги 10=Действия. */
      #accounts-table th:nth-child(2), #accounts-table td:nth-child(2),
      #accounts-table th:nth-child(4), #accounts-table td:nth-child(4),
      #accounts-table th:nth-child(5), #accounts-table td:nth-child(5),
      #accounts-table th:nth-child(7), #accounts-table td:nth-child(7),
      #accounts-table th:nth-child(9), #accounts-table td:nth-child(9) { text-align:center; }
      #accounts-table .acc-actions { display:flex; gap:2px; justify-content:center; flex-wrap:nowrap; }
      #accounts-table .acc-actions .btn, #accounts-table .acc-actions .btn-tg-open {
        padding:2px 5px; font-size:0.62rem; flex:0 0 auto;
      }
    </style>
    <div class="card">
        <div class="card-body" style="padding:0;">
            <table class="table" id="accounts-table">
                <thead>
                    <tr>
                        <th style="width:28px;"><input type="checkbox" id="acc-check-all" onchange="toggleAllAccChecks(this)" ></th>
                        <th style="width:40px;text-align:center;">#</th>
                        <th class="sortable-th" data-sort-key="phone" onclick="setAccSort('phone')" style="width:134px;">Телефон <span class="sort-arrow"></span></th>
                        <th class="sortable-th" data-sort-key="geo" onclick="setAccSort('geo')" style="width:54px;">Гео <span class="sort-arrow"></span></th>
                        <th class="sortable-th" data-sort-key="status" onclick="setAccSort('status')" style="width:124px;">Статус <span class="sort-arrow"></span></th>
                        <th style="width:118px;">Прокси</th>
                        <th class="sortable-th col-age" data-sort-key="age" onclick="setAccSort('age')" style="width:96px;">Отлежка <span class="sort-arrow"></span></th>
                        <th class="sortable-th" data-sort-key="name" onclick="setAccSort('name')" style="min-width:90px;">Имя <span class="sort-arrow"></span></th>
                        <th style="width:52px;">Теги</th>
                        <th style="text-align:center;width:158px;">Действия</th>
                    </tr>
                </thead>
                <tbody id="accounts-list">
                    <tr><td colspan="9" style="text-align:center;padding:32px;color:var(--text-muted);">
                        <i class="bi bi-inbox" style="font-size:1.5rem;display:block;margin-bottom:8px;"></i>Нет аккаунтов
                    </td></tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

<!-- ═══ TAB: Прокси ═══ -->
<div class="section" id="tab-proxy">
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-shield-lock" style="color:#06b6d4;"></i><div class="ch-text"><div class="ch-title">Прокси</div><div class="card-sub">пул прокси для аккаунтов</div></div></div>
        <div class="card-body">
            <div class="rd-group"><div class="rd-group-title">ПРОТОКОЛ</div>
            <div class="mb-3" style="max-width:280px;">
                <label class="form-label">Протокол прокси <span class="tt" data-tip="Если в строке нет socks5:// или http:// — берётся отсюда. «Определять автоматически» проверяет прокси при добавлении и запоминает рабочий протокол сам. Ставьте вручную, только если знаете точно: неверный протокол = таймаут подключения на каждом аккаунте.">?</span></label>
                <select class="form-control" id="proxy-type-default">
                    <option value="auto" selected>Определять автоматически</option>
                    <option value="socks5">SOCKS5</option>
                    <option value="http">HTTP</option>
                </select>
            </div>
            </div>
            <div class="rd-group"><div class="rd-group-title">РАЗДАЧА</div>
            <div class="mb-3" style="max-width:280px;">
                <label class="form-label">Порядок раздачи прокси по аккаунтам</label>
                <select class="form-control" id="proxy-order" onchange="saveProxyOrder()">
                    <option value="sequential" selected>По порядку (равномерно по пулу)</option>
                    <option value="random">Случайный</option>
                </select>
            </div>
            <div class="mb-3" style="max-width:280px;">
                <label class="form-label">Максимум аккаунтов на один прокси <span class="tt" data-tip="0 = авто (равномерно по пулу). 1 = свой прокси на каждый акк. N = не более N аккаунтов делят один прокси.">?</span></label>
                <input type="number" class="form-control" id="proxy-max-per-proxy" value="0" min="0" max="999" onchange="saveProxyMaxPerProxy()">
                
            </div>
            </div>

            <!-- Список прокси -->
            <div class="rd-group"><div class="rd-group-title">СПИСОК ПРОКСИ</div>
            <label class="form-label">Список прокси (по одному на строке)</label>
            <div style="background:var(--bg-input);border:1px solid var(--border);border-radius:5px;padding:4px;margin-bottom:8px;">
                <textarea class="form-control" id="proxy-input" rows="5" style="border:none;background:transparent;font-family:monospace;font-size:0.8rem;" onblur="autoSaveProxies()"
                    placeholder="ip:port&#10;ip:port:login:password&#10;login:password@ip:port&#10;socks5://ip:port:login:password"></textarea>
            </div>
            <div style="font-size:0.65rem;color:var(--text-muted);margin-bottom:8px;">
                Прокси сохраняются автоматически, как только уведёшь курсор из поля — кнопка «Добавить» не нужна.<br>
                Допустимые форматы записи:
                <code>ip:port</code> · <code>ip:port:логин:пароль</code> · <code>логин:пароль@ip:port</code>
            </div>
            </div>

            <div id="proxy-list"></div>
        </div>
    </div>
            <div class="run-row">
            <div class="d-flex gap-2" style="align-items:center;flex-wrap:wrap;">
                <button class="btn btn-accent btn-sm" onclick="checkAllProxies()"
                        data-tip="Проверяет каждый прокси дважды: сначала отвечает ли он вообще, потом доходит ли через него до Telegram. Второе важнее: часть прокси отвечает, но до Telegram не пускает, и аккаунт молча висит на подключении.">
                    <i class="bi bi-check2-all"></i> Проверить прокси
                </button>
                <button class="btn btn-outline btn-sm" onclick="clearAllProxies()"
                        style="border-color:var(--danger);color:var(--danger);"
                        data-tip="Удалить все прокси из списка">
                    <i class="bi bi-trash"></i> Удалить все
                </button>
                <span class="text-sm text-muted self-center" id="proxy-count-label"></span>
            </div>
            </div>

            <div class="card" style="margin-top:14px;">
                <div class="card-header"><i class="bi bi-hdd-network text-accent"></i> Статистика подключений к прокси</div>
                <div class="card-body">
                    <div style="overflow-x:auto;">
                        <div id="proxy-stats"><div style="color:var(--text-muted);font-size:0.75rem;padding:6px 2px;">Открой вкладку — загрузится статистика…</div></div>
                    </div>
                </div>
            </div>
    <!-- Подключение аккаунтов -->
    <details class="ad-block" id="settings-connection">
        <summary>
            <i class="bi bi-plug"></i> Подключение аккаунтов
            <span class="ad-note">паузы и таймауты коннекта через прокси</span>
        </summary>
        <div class="ad-body">
            <div class="rd-group"><div class="rd-group-title">ПАУЗЫ ПОДКЛЮЧЕНИЯ</div>
            <div class="grid-2 mb-3" style="max-width:500px;">
                <div>
                    <label class="form-label">Таймаут подключения к прокси (сек) <span class="tt" data-tip="Сколько ждать одно подключение. Рабочий прокси отвечает за доли секунды: по нашим замерам треть подключений укладывается в 0.4 секунды, половина — в 3. Поэтому предел здесь 5 секунд: не ответил — идёт следующая попытка, их число задаётся ниже. Если прокси очень медленный (резидентный, мобильный) и вы видите «прокси не ответил» на рабочем прокси — поднимите до 10–15 или добавьте попыток.">?</span></label>
                    <div class="d-flex align-center gap-2">
                        <input type="number" class="form-control w-100px" id="s-proxy-timeout" value="5" min="1" max="120">
                        <span class="text-sm text-muted">сек</span>
                    </div>
                </div>
                <div>
                    <label class="form-label">Быстрый отсев на первых попытках (сек) <span class="tt" data-tip="Отдельный, более короткий предел для первых попыток — нужен был, когда общий таймаут был большим. Теперь общий и так 5 секунд, поэтому по умолчанию здесь ноль: все попытки идут по одному пределу. Поставьте своё число, только если общий таймаут подняли.">?</span></label>
                    <div class="d-flex align-center gap-2">
                        <input type="number" class="form-control w-100px" id="s-connect-attempt-timeout" value="0" min="0" max="120">
                        <span class="text-sm text-muted">сек</span>
                    </div>
                </div>
                <div>
                    <label class="form-label">Сколько раз пробовать подключиться '
     <span class="tt" data-tip="Сколько попыток сделать, прежде чем пометить аккаунт «не смог подключиться». Две попытки по 5 секунд с секундной паузой — на мёртвый прокси программа тратит около 11 секунд и идёт дальше. Больше — терпеливее к нестабильным прокси, но каждый аккаунт занимает дольше.">?</span></label>
                    <input type="number" class="form-control w-100px" id="s-connect-retries" value="2" min="1" max="10">
                </div>
            </div>
            <div>
                <label class="form-label">Пауза между подключениями аккаунтов (сек) <span class="tt" data-tip="При старте задачи аккаунты подключаются не разом, а по очереди с этой паузой. Четыре и больше одновременных подключения с одного адреса Telegram принимает за ферму ботов и закрывает входы. 3 секунды — норма, осторожнее — 5. Ноль означает «все сразу» и это риск.">?</span></label>
                <input type="number" class="form-control w-100px" id="s-connect-delay" value="3" min="0" max="60">
            </div>

            <div class="mt-3" style="border-top:1px solid var(--border);padding-top:12px;">
                <label class="form-label"><i class="bi bi-clock-history"></i> Паузы для защиты аккаунтов (0 = выключить) <span class="tt" data-tip="Эти паузы программа делает сама, чтобы аккаунты не поймали блокировку. Можно настроить под себя или выключить, поставив ноль. Когда подождать просит сам Telegram, программа слушается его всегда — на эти поля это не влияет.">?</span></label>
                <div class="d-flex gap-3 flex-wrap">
                    <div>
                        <label class="form-label" style="font-size:0.72rem;">Пауза между кругами рассылки, не меньше: <span class="tp-sec-hint" data-for="s-loop-pause-min"></span> <span class="tt" data-tip="Работает, когда включена рассылка по кругу: между кругами пауза не меньше этого времени. Ноль — без паузы, аккаунты при таком темпе быстро ловят блокировку.">?</span></label>
                        <input type="number" class="form-control tp-sec w-100px" id="s-loop-pause-min" value="60" min="0" max="604800" step="10">
                    </div>
                    <div>
                        <label class="form-label" style="font-size:0.72rem;">Отдых после спам-блока: <span class="tp-sec-hint" data-for="s-peerflood-cooldown"></span> <span class="tt" data-tip="Если Telegram пометил аккаунт спамом, программа даст ему отдохнуть перед следующей работой. По умолчанию 6 часов. Ноль — не давать отдых.">?</span></label>
                        <input type="number" class="form-control tp-sec w-100px" id="s-peerflood-cooldown" value="21600" min="0" max="259200" step="3600">
                    </div>
                    <div>
                        <label class="form-label" style="font-size:0.72rem;">Отдых после лимита поиска по номеру: <span class="tp-sec-hint" data-for="s-phone-import-rest"></span> <span class="tt" data-tip="В приглашениях: когда аккаунт исчерпал дневной лимит поиска людей по номеру телефона, программа даст ему отдохнуть. По умолчанию 6 часов. Ноль — не давать отдых.">?</span></label>
                        <input type="number" class="form-control tp-sec w-100px" id="s-phone-import-rest" value="21600" min="0" max="259200" step="3600">
                    </div>
                </div>
            </div>
            </div>
            <div class="rd-group"><div class="rd-group-title">ЗАЩИТА</div>
            <div class="mt-3" style="border-top:1px solid var(--border);padding-top:10px;">
                <label class="form-label">Прогрев свежезарегистрированных акков (сек) <span class="tp-sec-hint" data-for="s-warmup-duration-sec"></span> <span class="tt" data-tip="После добавления акка по SMS / 2FA через нашу форму — софт держит акк online указанное время. Это снижает риск что Telegram примет свежезарегистрированный акк за бота. По умолчанию 0 (выключено) — клиент сам решает когда начать работу с акком. Если ставишь > 0 — будет только passive online + GetMe, без резких действий, которые сами могут привести к закрытию входа. Аккаунты, купленные готовыми, не прогреваются — они уже прогреты там, откуда пришли.">?</span></label>
                <input type="number" class="form-control w-100px tp-sec" id="s-warmup-duration-sec" value="0" min="0" max="3600" step="60">
                
            </div>
            <div class="mt-3" style="border-top:1px solid var(--border);padding-top:10px;">
                <label class="d-flex align-center gap-2" style="cursor:pointer;font-size:0.78rem;" data-tip="Если ВКЛ — при большом пауза от Telegram у акка софт сам поставит ему другой живой прокси из пула. По умолчанию OFF — софт ничего не трогает, акк просто помечается disabled.">
                    <input type="checkbox" class="form-check-input" id="s-auto-rotate-proxy">
                    <span><b>Менять прокси</b>, если Telegram просит долго ждать <span style="color:var(--text-muted);">(по умолчанию выключено)</span></span>
                </label>
            </div>
            <div class="mt-3" style="border-top:1px solid var(--border);padding-top:10px;">
                <label class="d-flex align-center gap-2" style="cursor:pointer;font-size:0.78rem;" data-tip="Если ВКЛ — софт НЕ даст 3+ разным аккам отправить ОДИН И ТОТ ЖЕ текст за 24ч в прогреве/рассылке (Telegram видит такой паттерн как бот-сеть → заморозки). По умолчанию OFF — твой выбор, что и сколько слать.">
                    <input type="checkbox" class="form-check-input" id="s-warmup-watchdog">
                    <span><b>Защита от паттерна одинаковых текстов</b> в прогреве/рассылке <span style="color:var(--text-muted);">(opt-in)</span></span>
                </label>
                <div class="d-flex align-center gap-2 mt-2" style="font-size:0.76rem;color:var(--text-muted);padding-left:26px;">
                    <span>Порог: блокировать если</span>
                    <input type="number" class="form-control" id="s-warmup-watchdog-threshold" min="2" max="50" placeholder="3" style="width:60px;padding:2px 6px;font-size:0.76rem;">
                    <span>+ акков слали один текст за 24ч</span>
                </div>
            </div>
            </div>
        </div>
    </details>

</div>

<!-- TAB «Шаблоны» удалён. Прогревовые шаблоны остаются как настройка во вкладке «Прогрев». -->

<!-- ═══ TAB: Парсинг юзеров ═══ -->
<div class="section" id="tab-parser">
    <!-- Аккаунт для парсинга -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-search" style="color:#f472b6;"></i><div class="ch-text"><div class="ch-title">Парсинг</div><div class="card-sub">сбор чатов и участников</div></div></div>
        <div class="card-body">
            <div class="acc-selector mb-3" id="acc-selector-parser"></div>

            <!-- Режим парсинга — единый дропдаун. Каждая функция = отдельный пункт;
                 «Аудитория» разворачивает чекбоксы союза; «Досье» — accountless-режим. -->
            <div class="rd-group"><div class="rd-group-title">РЕЖИМ</div>
            <label class="form-label">Режим парсинга</label>
            <select class="form-control mb-2 js-fancy-select" id="parser-mode-select" onchange="onParserModeSelect(this.value)">
                <optgroup label="Из чата">
                    <option value="audience" selected>Аудитория из чата — участники / писавшие / реакции / опросы</option>
                    <option value="links">Сборщик ссылок — t.me из сообщений и описаний</option>
                </optgroup>
                <optgroup label="Найти чаты / каналы">
                    <option value="keyword_global">Слово везде — найти чаты по слову (без акка)</option>
                    <option value="keyword">По словам — в МОИХ чатах (через акк)</option>
                    <option value="search">Глоб. поиск — найти чаты</option>
                    <option value="user_chats">Чаты юзера — найти чаты/каналы, где состоит @юзернейм</option>
                </optgroup>
                <optgroup label="Проверка">
                    <option value="user_check">Чекер юзов — валидность + онлайн</option>
                    <option value="link_check">Чекер ссылок — валидность t.me</option>
                </optgroup>
            </select>

            <!-- Аудитория: кнопки-чекбоксы союза (видны только в режиме «Аудитория») -->
            <div class="parser-modes mb-2" id="parser-audience-combo">
                <button class="parser-mode-btn active" id="pm-members" onclick="setParserMode('members')">
                    <i class="bi bi-people"></i>
                    <span>Участники</span>
                    <small>Из списка чата</small>
                </button>
                <button class="parser-mode-btn" id="pm-writers" onclick="setParserMode('writers')">
                    <i class="bi bi-chat-text"></i>
                    <span>Писавшие</span>
                    <small>Кто писал в чат</small>
                </button>
                <button class="parser-mode-btn" id="pm-reactions" onclick="setParserMode('reactions')">
                    <i class="bi bi-heart"></i>
                    <span>Реакции</span>
                    <small>Кто реагировал на посты</small>
                </button>
                <button class="parser-mode-btn" id="pm-polls" onclick="setParserMode('polls')">
                    <i class="bi bi-bar-chart"></i>
                    <span>Опросы</span>
                    <small>Кто голосовал</small>
                </button>
            </div>

            <!-- Связка аудитории: подсказка мульти-выбора + тоггл пересечения -->
            <div id="parser-audience-hint" style="font-size:0.7rem;color:var(--text-muted);margin:-4px 0 10px;">
                <i class="bi bi-info-circle"></i> Участники / Писавшие / Реакции / Опросы можно отметить ВМЕСТЕ — соберём за один проход в одну базу (дубли убираются, видно источник).
            </div>
            <div id="parser-audience-intersect-row" style="display:none;margin-bottom:12px;">
                <label class="d-flex align-center gap-2" style="cursor:pointer;margin-bottom:0;">
                    <input type="checkbox" class="form-check-input" id="parser-audience-intersect">
                    <span style="font-size:0.82rem;">Только те, кто во ВСЕХ выбранных источниках <span style="color:var(--text-muted);">(пересечение — напр. И писал И реагировал = самые активные)</span></span>
                </label>
            </div>
            </div>

            <!-- Блок ввода для «Чекер юзов» -->
            <div id="parser-user-check-row" style="display:none;" class="mb-3">
                <label class="form-label">Список юзеров (по одному на строке)</label>
                <textarea class="form-control" id="parser-user-check-list" rows="6"
                          placeholder="@username1&#10;@username2&#10;123456789&#10;https://t.me/username3"
                          style="font-family:monospace;font-size:0.78rem;"></textarea>
                <div style="font-size:0.7rem;color:var(--text-muted);margin-top:6px;">
                    Можно вставить @username, числовой ID или ссылку t.me/. По каждому будет видно: <b>валиден</b> (есть в Telegram), <b>онлайн</b> (если статус публичный), <b>когда был</b> (недавно / неделя / месяц / давно). Скрытые статусы = «приватность». Отдельная пометка <b>«?»</b> — проверить не вышло (Telegram попросил паузу или оборвалась связь): такого юзера из базы выбрасывать не надо, просто повторите позже. Числовой ID проверяется только у тех, кого аккаунт уже видел, — так устроен Telegram.
                </div>
                <div class="mt-2" style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;">
                    <label class="form-label m-0" style="font-size:0.78rem;">Оставить только активных
                        <span class="tt" data-tip="После проверки отсеять тех, кто давно не в сети. Требуется аккаунт — HTTP-чек без акка онлайн не видит. Бакеты грубые: Telegram сам прячет точное время для «недавно/неделя/месяц», берётся верхняя граница периода.">?</span>
                    </label>
                    <select class="form-control" id="parser-user-check-period" style="width:auto;font-size:0.78rem;">
                        <option value="all">Все (не фильтровать)</option>
                        <option value="online">Онлайн сейчас</option>
                        <option value="recently">Недавно (1–2 дня)</option>
                        <option value="week">За неделю</option>
                        <option value="month">За месяц</option>
                    </select>
                </div>
            </div>

            <!-- Чекер ссылок: список t.me-ссылок (виден только для 'link_check') -->
            <div id="parser-link-check-row" style="display:none;" class="mb-3">
                <label class="form-label">Список ссылок (по одной на строке)</label>
                <textarea class="form-control" id="parser-link-check-list" rows="6"
                          placeholder="https://t.me/channel&#10;@group_username&#10;https://t.me/+AbCdEf123456&#10;t.me/joinchat/XXXXXXXX"
                          style="font-family:monospace;font-size:0.78rem;"></textarea>
                <div style="font-size:0.7rem;color:var(--text-muted);margin-top:6px;">
                    Проверка ссылок t.me <b>без аккаунта</b>: канал / группа / бот / юзер / <b>приватный инвайт (t.me/+…)</b> — название и число подписчиков. Подключишь акк сверху — быстрее, точнее для приватных инвайтов (напрямую, <b>без вступления</b>) и показывает <b>гео</b> у публичных гео-каналов/групп. Ссылки <code>t.me/c/…</code> — только с акком-участником. Число ссылок не ограничено. Те, что проверить не вышло (Telegram попросил паузу, оборвалась связь), помечаются отдельно — это не значит «ссылка мёртвая», просто повторите позже.
                </div>
            </div>

            <!-- Общая опция обоих чекеров -->
            <div id="parser-check-accs-row" style="display:none;" class="mb-3">
                <label class="opt-row">
                    <input type="checkbox" id="parser-check-all-accs" checked> Проверять всеми аккаунтами <span style="color:var(--text-muted);font-size:0.72rem;">— от 30 строк список делится между аккаунтами: быстрее в разы, а попавший в паузу аккаунт передаёт свою строку следующему</span>
                </label>
            </div>

            <!-- Блок ввода слова (виден только для режима 'keyword_global') -->
            <div id="parser-keyword-global-row" class="mb-3" style="display:none;">
                <label class="form-label">Слово или фраза</label>
                <input type="text" class="form-control" id="parser-keyword-global" placeholder="например: ДОМ или 'аренда квартир'">
                <div class="row g-2 mt-3">
                    <div class="col-md-6">
                        <label class="form-label" style="font-size:0.8rem;">Язык текста</label>
                        <select class="form-control" id="parser-kg-lang">
                            <option value="">Любой</option>
                            <option value="ru">Русский</option>
                            <option value="uk">Українська</option>
                            <option value="be">Беларуская</option>
                            <option value="kk">Қазақ</option>
                            <option value="en">English</option>
                        </select>
                        <div style="font-size:0.7rem;color:var(--text-muted);margin-top:3px;">по языку сообщений канала</div>
                    </div>
                    <div class="col-md-6">
                        <label class="form-label" style="font-size:0.8rem;">Регион канала</label>
                        <select class="form-control" id="parser-kg-region">
                            <option value="">Любой</option>
                            <option value="ru">Россия</option>
                            <option value="ua">Украина</option>
                            <option value="by">Беларусь</option>
                            <option value="kz">Казахстан</option>
                        </select>
                        <div style="font-size:0.7rem;color:var(--text-muted);margin-top:3px;">по имени канала и привязкам (Минск/Київ/Алматы)</div>
                    </div>
                </div>
                <label class="form-label mt-3" style="font-size:0.8rem;">TGStat token (необязательно, для полного охвата)</label>
                <input type="text" class="form-control" id="parser-kg-tgstat-token" placeholder="токен с api.tgstat.ru → раздел API → скопировать">
            </div>

            <!-- Блок ввода юзернейма (виден только для режима 'user_chats') -->
            <div id="parser-user-row" class="mb-3" style="display:none;">
                <label class="form-label">Юзернейм или ID</label>
                <input type="text" class="form-control" id="parser-target-user" placeholder="@username или 1234567 или https://t.me/username">
            </div>

            <!-- Выбор чатов -->
            <div class="rd-group" id="parser-source-group"><div class="rd-group-title">ИСТОЧНИК ЧАТОВ</div>
            <div id="parser-chat-row" class="mb-3">
                <!-- Кнопка «Сканировать все чаты» — только для режима «Ссылки».
                     Для «Участники»/«Писавшие» это бессмысленно: нужен конкретный чат,
                     иначе прогон по всем группам даст миллионы записей и флуд-блок за 2 минуты. -->
                <div id="parser-scan-all-wrap" style="display:none;">
                    <button class="btn btn-accent" onclick="scanAllChatsOneClick()" id="btn-scan-all-chats"
                            style="width:100%;padding:12px 16px;margin-bottom:10px;font-size:0.95rem;font-weight:600;">
                        <i class="bi bi-search" style="margin-right:6px;"></i> Сканировать все чаты
                    </button>
                    <div style="font-size:0.68rem;color:var(--text-muted);margin-bottom:10px;text-align:center;">
                        — или выберите конкретные чаты ниже —
                    </div>
                </div>
                <div class="d-flex align-center justify-between mb-2">
                    <label class="form-label m-0">Чаты для парсинга</label>
                    <div class="d-flex gap-2">
                        <button class="btn btn-outline btn-sm" onclick="toggleParserInputMode()" id="btn-parser-input-mode" style="font-size:0.7rem;padding:2px 8px;">
                            <i class="bi bi-link-45deg"></i> Ввести ссылки
                        </button>
                        <button class="btn btn-accent btn-sm" onclick="scanParserChats()" id="btn-parser-scan" style="font-size:0.7rem;padding:2px 10px;">
                            <i class="bi bi-arrow-clockwise"></i> Обновить список чатов
                        </button>
                    </div>
                </div>
                <div id="parser-all-chats-banner" style="display:none;margin-bottom:8px;padding:6px 10px;background:rgba(52,211,153,0.08);border:1px solid rgba(52,211,153,0.3);border-radius:4px;font-size:0.72rem;color:var(--success);">
                    <i class="bi bi-check-circle"></i> Парсим <b>все</b> чаты/каналы аккаунта. Выбор ниже игнорируется.
                </div>
                <!-- Режим 1: выбор из списка (мульти) -->
                <div id="parser-chat-select-mode">
                    <div class="row-flex gap-2 mb-2">
                        <i class="bi bi-search text-muted"></i>
                        <input type="search" class="form-control flex-1 fs-78" id="parser-chat-search"
                               placeholder="Поиск чата по названию..." oninput="filterParserChats()" autocomplete="off">
                    </div>
                    <select class="form-control flex-1" id="parser-chat">
                        <option value="">Загрузите чаты...</option>
                    </select>
                    <div id="parser-selected-chats" style="margin-top:8px;display:flex;flex-wrap:wrap;gap:4px;"></div>
                    <button class="btn btn-outline btn-sm" onclick="addParserChat()" style="margin-top:6px;font-size:0.7rem;padding:2px 10px;">
                        <i class="bi bi-plus"></i> Добавить чат
                    </button>
                </div>
                <!-- Режим 2: ввод ссылок (акк зайдёт и спарсит) -->
                <div id="parser-links-mode" style="display:none;">
                    <textarea class="form-control" id="parser-chat-links" rows="4" placeholder="Вставьте ссылки на чаты/каналы (по одной на строке):&#10;https://t.me/chatname&#10;https://t.me/+invitehash&#10;@username"></textarea>
                    <div style="font-size:0.68rem;color:var(--text-muted);margin-top:4px;">Аккаунт зайдёт в чат и выполнит парсинг. Поддерживаются: t.me ссылки, @username, инвайт-хеши</div>
                </div>
                <!-- Превью выбранного чата -->
                <div id="parser-chat-preview" class="parser-chat-preview" style="display:none;"></div>
            </div>
            </div>

            <!-- Описания режимов -->
            <div id="parser-mode-desc" class="info-box" style="padding:var(--space-3) var(--space-4);"></div>

            <!-- Фильтр реакций по эмодзи — только для режима «Реакции» -->
            <div id="parser-reactions-row" class="mb-3" style="display:none;">
                <label class="form-label">Фильтр реакций <span style="color:var(--text-muted);font-weight:400;">(пусто = собирать все реакции)</span></label>
                <div id="parser-reaction-emojis" class="d-flex" style="flex-wrap:wrap;gap:6px;"></div>
            </div>

            <!-- Глубина + порог — для «Реакции» и «Опросы» -->
            <div id="parser-engagement-row" class="grid-2 mb-3" style="display:none;">
                <div>
                    <label class="form-label">Сканировать постов <span style="color:var(--text-muted);font-weight:400;">(глубина)</span></label>
                    <input type="number" class="form-control" id="parser-scan-posts" value="300" min="10">
                </div>
                <div>
                    <label class="form-label" id="parser-min-engagement-label">Мин. реакций на посте <span style="color:var(--text-muted);font-weight:400;">(0 = все)</span></label>
                    <input type="number" class="form-control" id="parser-min-engagement" value="0" min="0">
                </div>
            </div>

            <!-- Настройки для юзеров (members/writers) -->
            <div id="parser-opts-users" class="mb-3">
                <!-- Быстрые пресеты активности -->
                <label class="form-label fs-72">Быстрый выбор активности</label>
                <div class="d-flex flex-wrap gap-1 mb-2" id="parser-activity-presets">
                    <button type="button" class="btn btn-outline btn-sm btn-preset" onclick="applyActivityPreset('online')"><i class="bi bi-circle-fill" style="color:var(--success);font-size:0.55rem;vertical-align:middle;"></i> Онлайн</button>
                    <button type="button" class="btn btn-outline btn-sm btn-preset" onclick="applyActivityPreset('hours', 1)">1ч</button>
                    <button type="button" class="btn btn-outline btn-sm btn-preset" onclick="applyActivityPreset('hours', 3)">3ч</button>
                    <button type="button" class="btn btn-outline btn-sm btn-preset" onclick="applyActivityPreset('hours', 24)">24ч</button>
                    <button type="button" class="btn btn-outline btn-sm btn-preset" onclick="applyActivityPreset('hours', 72)">3д</button>
                    <button type="button" class="btn btn-outline btn-sm btn-preset" onclick="applyActivityPreset('hours', 168)">7д</button>
                    <button type="button" class="btn btn-outline btn-sm btn-preset" onclick="applyActivityPreset('hours', 720)">30д</button>
                    <button type="button" class="btn btn-outline btn-sm btn-preset" onclick="applyActivityPreset('all')"><i class="bi bi-list-ul"></i> Все</button>
                </div>
                <div class="grid-2 mb-2">
                    <div>
                        <label class="form-label">Фильтр активности</label>
                        <select class="form-control" id="parser-filter">
                            <option value="all">Все с юзернеймом</option>
                            <option value="online">Только онлайн</option>
                            <option value="hours">Были за N часов</option>
                        </select>
                    </div>
                    <div>
                        <label class="form-label">Часов</label>
                        <input type="number" class="form-control" id="parser-hours" value="24" min="1" max="720">
                    </div>
                </div>
                <!-- Min. сообщений + период — ТОЛЬКО для режима «Писавшие» -->
                <div class="grid-2 mb-2" id="parser-writers-extra" style="display:none;">
                    <div>
                        <label class="form-label">Минимум сообщений от юзера</label>
                        <select class="form-control" id="parser-min-messages">
                            <option value="1">≥1 сообщ</option>
                            <option value="2">≥2 сообщ</option>
                            <option value="3">≥3 сообщ</option>
                            <option value="5">≥5 сообщ</option>
                            <option value="10">≥10 сообщ</option>
                            <option value="25">≥25 сообщ</option>
                        </select>
                    </div>
                    <div>
                        <label class="form-label">Период сканирования</label>
                        <select class="form-control" id="parser-period-preset" onchange="applyPeriodPreset(this.value)">
                            <option value="0">Вся история</option>
                            <option value="1">Последний 1 день</option>
                            <option value="3">Последние 3 дня</option>
                            <option value="7" selected>Последние 7 дней</option>
                            <option value="14">Последние 14 дней</option>
                            <option value="30">Последние 30 дней</option>
                        </select>
                    </div>
                </div>
                <div class="d-flex gap-3 flex-wrap">
                    <label class="opt-row" >
                        <input type="checkbox" id="parser-skip-admins"> Пропустить админов
                    </label>
                    <label class="opt-row" >
                        <input type="checkbox" id="parser-skip-bots" checked> Пропустить ботов <span class="tt" data-tip="ON (дефолт) — боты не попадают в результаты. OFF — боты тоже соберутся (нужно для редких сценариев когда хочешь собрать список ботов чата).">?</span>
                    </label>
                    <label class="opt-row" >
                        <input type="checkbox" id="parser-strict"> Строгая активность (без «был недавно»)
                    </label>
                </div>

                <!-- Расширенные фильтры -->
                <details class="ad-block">
                    <summary><i class="bi bi-funnel"></i> Расширенные фильтры</summary>
                    <div class="ad-body">
                        <div class="grid-2 mb-2" style="margin-top:6px;">
                            <div>
                                <label class="form-label">Что сохранять</label>
                                <select class="form-control" id="parser-save-mode">
                                    <option value="usernames">Только юзернеймы</option>
                                    <option value="usernames_ids">Юзернеймы + ID</option>
                                </select>
                                <div style="font-size:12px;color:var(--text-muted);margin-top:4px;line-height:1.4;">
                                    «+ ID» добавит в список участников без @юзера как числовой ID. Прямую рассылку по такому списку Telegram не разрешит, но ID пригодится для аналитики, выгрузки в Excel и для последующего поиска этих юзеров в общих чатах.
                                </div>
                            </div>
                            <div>
                                <label class="form-label">Кого парсить (роли)</label>
                                <select class="form-control" id="parser-roles">
                                    <option value="users">Только обычные пользователи</option>
                                    <option value="admins">Только админы</option>
                                    <option value="all">Все</option>
                                </select>
                            </div>
                        </div>
                        <div class="grid-2 mb-2">
                            <div>
                                <label class="form-label">Доступ к ЛС</label>
                                <select class="form-control" id="parser-dm-access">
                                    <option value="all">Парсить всех</option>
                                    <option value="open">Только с открытыми ЛС</option>
                                    <option value="closed">Только с закрытыми ЛС</option>
                                </select>
                            </div>
                            <div>
                                <label class="form-label">Минимум часов с последнего онлайна</label>
                                <input type="number" class="form-control" id="parser-online-min" min="0" max="999999" value="0">
                            </div>
                        </div>
                        <div class="grid-2 mb-2">
                            <div>
                                <label class="form-label">Максимум часов с последнего онлайна</label>
                                <input type="number" class="form-control" id="parser-online-max" min="0" max="999999" value="99999">
                            </div>
                            <div></div>
                        </div>
                        <div class="d-flex gap-3 flex-wrap mt-2">
                            <label class="opt-row" >
                                <input type="checkbox" id="parser-only-avatar"> Только с аватарками
                            </label>
                            <label class="opt-row" >
                                <input type="checkbox" id="parser-only-premium"> Только с премиумом
                            </label>
                            <label class="opt-row" >
                                <input type="checkbox" id="parser-include-poll-voters"> Парсить голосовавших в опросах
                            </label>
                            <label class="opt-row" >
                                <input type="checkbox" id="parser-recent-only"> Только активные за ~6 мес <span class="tt" data-tip="Парсит через ChannelParticipantsRecent — отдаёт топ активных юзеров чата (~20-30% от всех, но они писали в чат за последние ~6 мес). Конверсия в DM выше чем по «всем». Используют Apify и коммерческие скраперы для скрытых каналов.">?</span>
                            </label>
                        </div>
                    </div>
                </details>
            </div>

            <!-- Настройки для ссылок -->
            <div id="parser-opts-links" style="display:none;" class="mb-3">
                <div class="grid-2 mb-2">
                    <div>
                        <label class="form-label">Тип ссылок</label>
                        <select class="form-control" id="parser-link-type">
                            <option value="all">Все (инвайты + публичные)</option>
                            <option value="invites">Только инвайты (t.me/+...)</option>
                            <option value="public">Только публичные (t.me/channel)</option>
                        </select>
                    </div>
                    <div>
                        <label class="form-label">Период сканирования сообщений</label>
                        <select class="form-control" id="parser-links-period" onchange="applyLinksPeriodPreset(this.value)">
                            <option value="0">Вся история</option>
                            <option value="1">Последний 1 день</option>
                            <option value="3">Последние 3 дня</option>
                            <option value="7" selected>Последние 7 дней</option>
                            <option value="14">Последние 14 дней</option>
                            <option value="30">Последние 30 дней</option>
                        </select>
                    </div>
                </div>
                <label class="opt-row" >
                    <input type="checkbox" id="parser-unwrap"> Разворачивать короткие URL (bit.ly, telegra.ph)
                </label>
                <!-- Откуда брать ссылки. По умолчанию оба источника: из сообщений
                     + из описания и closed-link чатов (часто там лежит invite-ссылка). -->
                <label class="form-label mt-2">Откуда брать ссылки</label>
                <select class="form-control" id="parser-link-source">
                    <option value="both" selected>Сообщения + описания чатов</option>
                    <option value="messages">Только из сообщений (как раньше)</option>
                    <option value="meta">Только из описаний/закреплённой ссылки чата</option>
                </select>
                <div style="font-size:0.7rem;color:var(--text-muted);margin-top:4px;">
                    «Описание» — текст «About» чата + публичный @username + закреплённая invite-ссылка из настроек чата.
                </div>
            </div>

            <!-- Настройки для глобального поиска -->
            <div id="parser-opts-search" style="display:none;" class="mb-3">
                <!-- ИИ: тема словами → поисковые запросы -->
                <div class="mb-2" style="background:var(--bg-card-hover);border-radius:4px;padding:8px 10px;">
                    <label class="form-label" style="font-size:0.8rem;"><i class="bi bi-stars text-purple"></i> Подобрать запросы по теме (ИИ)</label>
                    <div class="d-flex gap-2" style="flex-wrap:wrap;align-items:flex-start;">
                        <input type="text" class="form-control" id="parser-ai-topic-search" placeholder="напиши тему словами: продажа авто Киев" style="flex:1;min-width:180px;">
                        <button class="btn btn-outline btn-sm" onclick="aiParserSuggest(this,'parser-ai-topic-search','parser-search-query','queries')" style="border-color:var(--accent);color:var(--accent);white-space:nowrap;">
                            <i class="bi bi-magic"></i> Подобрать
                        </button>
                    </div>
                    <div style="font-size:0.66rem;color:var(--text-muted);margin-top:4px;">ИИ добавит поисковые запросы по теме в поле ниже. Нужен ключ: Настройки → ИИ.</div>
                </div>
                <label class="form-label">Пул запросов <span style="font-size:0.7rem;color:var(--text-muted);">(по одному на строке, макс 50)</span></label>
                <textarea class="form-control mb-2" id="parser-search-query" rows="3" placeholder="крипто&#10;заработок&#10;NFT&#10;трейдинг"></textarea>
                <div style="background:var(--bg-card-hover);border-radius:4px;padding:8px 10px;margin-bottom:10px;font-size:0.7rem;color:var(--text-muted);">
                    Каждая строка — отдельный запрос (макс 50). Как именно искать по многословному запросу — задаётся ниже в «Как искать».
                </div>
                <div class="grid-2 mb-2">
                    <div>
                        <label class="form-label">Источник</label>
                        <select class="form-control" id="parser-search-source">
                            <option value="telegram">Telegram</option>
                            <option value="tgstat">TGStat</option>
                            <option value="both">Оба</option>
                        </select>
                    </div>
                    <div>
                        <label class="form-label">TGStat Token <span style="font-size:0.65rem;color:var(--text-muted);font-weight:400;">(только если источник = TGStat)</span></label>
                        <input type="text" class="form-control" id="parser-tgstat-token" placeholder="Токен API TGStat">
                        <div style="font-size:0.66rem;color:var(--text-muted);margin-top:4px;">
                            Где взять: <a class="text-purple" href="https://api.tgstat.ru/" target="_blank" rel="noopener">api.tgstat.ru</a> → регистрация → раздел API → скопировать токен.
                        </div>
                    </div>
                </div>
                <div class="grid-2 mb-2">
                    <div>
                        <label class="form-label">Мин. участников</label>
                        <input type="number" class="form-control" id="parser-min-members" value="0" min="0" max="1000000" placeholder="0 = без фильтра">
                    </div>
                    <div>
                        <label class="form-label">Как искать</label>
                        <select class="form-control" id="parser-search-mode" onchange="updateSearchModeHint()">
                            <option value="phrase" selected>Точная фраза</option>
                            <option value="all_words">Все слова</option>
                            <option value="any_word">Любое слово</option>
                            <option value="raw">Как ввёл (без обработки)</option>
                        </select>
                    </div>
                </div>
                <div id="parser-search-mode-hint" style="background:var(--bg-card-hover);border-radius:4px;padding:8px 10px;margin-bottom:10px;font-size:0.7rem;color:var(--text-muted);line-height:1.5;">
                    <b style="color:var(--text);">Точная фраза</b> — ищет фразу целиком, оставляет только чаты, где есть <b>все</b> слова. «Москва барахолка» → только московские барахолки, без мусора из других городов.
                </div>
                <label class="opt-row" >
                    <input type="checkbox" id="parser-search-all-accs"> Искать со всех аккаунтов <span style="color:var(--text-muted);font-size:0.72rem;">— запросы раскидываются по пулу акков (быстрее, нагрузка делится, дохлый акк пропускается)</span>
                </label>
                <label class="opt-row" >
                    <input type="checkbox" id="parser-search-deep" checked> Копать глубже <span style="color:var(--text-muted);font-size:0.72rem;">— Telegram отдаёт на один запрос не больше сотни чатов, и одинаково всем аккаунтам. Программа смотрит, что нашлось, и доспрашивает уточнениями: «подработка» → «подработка киев», «подработка вакансии». Дольше, зато чатов в разы больше</span>
                </label>
            </div>

            <!-- Настройки для поиска по словам -->
            <div id="parser-opts-keyword" style="display:none;" class="mb-3">
                <!-- ИИ: тема словами → ключевые слова -->
                <div class="mb-2" style="background:var(--bg-card-hover);border-radius:4px;padding:8px 10px;">
                    <label class="form-label" style="font-size:0.8rem;"><i class="bi bi-stars text-purple"></i> Подобрать ключевые слова по теме (ИИ)</label>
                    <div class="d-flex gap-2" style="flex-wrap:wrap;align-items:flex-start;">
                        <input type="text" class="form-control" id="parser-ai-topic-keyword" placeholder="напиши тему словами: аренда квартир Одесса" style="flex:1;min-width:180px;">
                        <button class="btn btn-outline btn-sm" onclick="aiParserSuggest(this,'parser-ai-topic-keyword','parser-keywords','keywords')" style="border-color:var(--accent);color:var(--accent);white-space:nowrap;">
                            <i class="bi bi-magic"></i> Подобрать
                        </button>
                    </div>
                    <div style="font-size:0.66rem;color:var(--text-muted);margin-top:4px;">ИИ добавит ключевые слова по теме в поле ниже. Нужен ключ: Настройки → ИИ.</div>
                </div>
                <label class="form-label">Ключевые слова (по одному на строке)</label>
                <textarea class="form-control mb-2" id="parser-keywords" rows="3" placeholder="заработок&#10;крипто&#10;вакансия"></textarea>
                <div style="background:var(--bg-card-hover);border-radius:4px;padding:8px 10px;margin-bottom:10px;font-size:0.7rem;color:var(--text-muted);line-height:1.5;">
                    ⏱ Сканирование всех чатов аккаунта занимает 3-10 минут (на аккаунт с 500+ чатами — до 15 мин).
                    Не закрывайте окно. Прогресс: «Сканирую X/Y чатов» в строке статуса.
                </div>
                <div class="grid-2">
                    <div>
                        <label class="form-label">Искать в</label>
                        <select class="form-control" id="parser-kw-scope">
                            <option value="all">Все чаты</option>
                            <option value="groups">Только группы</option>
                            <option value="channels">Только каналы</option>
                        </select>
                    </div>
                    <div>
                        <label class="form-label">Собирать</label>
                        <select class="form-control" id="parser-kw-collect">
                            <option value="links">Ссылки</option>
                            <option value="usernames">Юзернеймы</option>
                            <option value="both">Всё</option>
                        </select>
                    </div>
                </div>
            </div>

            <!-- Лимит -->
            <div class="rd-group" id="parser-limit-group"><div class="rd-group-title">ЛИМИТ</div>
            <div class="mb-3" id="parser-limit-row">
                <label class="form-label">Лимит результатов</label>
                <input type="number" class="form-control" id="parser-limit" value="20000" min="100" style="max-width:200px;">
            </div>
            <div class="mb-3" id="parser-pause-row">
                <label class="form-label">Пауза между запросами, сек <span class="tt" data-tip="0 — работать с той скоростью, которую разрешает сам Telegram: его паузы софт соблюдает полностью, своих не добавляет. Поставьте 0.5–2, если бережёте свежий аккаунт: сбор пойдёт медленнее, зато мягче.">?</span></label>
                <input type="number" class="form-control" id="parser-pause" value="0" min="0" max="10" step="0.1" style="max-width:200px;">
            </div>
            </div>

            <!-- Пресеты для режима «Ссылки»: быстрый выбор готовых конфигураций -->
            <div class="mb-3" id="parser-presets" style="display:none;">
                <div style="font-size:0.72rem;color:var(--text-muted);margin-bottom:6px;">Быстрые пресеты (задают период + тип ссылок + лимит одним кликом):</div>
                <button class="btn btn-outline btn-sm btn-preset" onclick="applyParserPreset('basic')">
                    Базовый <span class="tt" data-tip="Период: последние 7 дней. Типы ссылок: все (приглашения в приватные чаты + публичные каналы). Лимит: 3000 ссылок. Короткие ссылки (bit.ly, telegra.ph) не разворачиваются — для быстрого сбора за неделю.">?</span>
                </button>
                <button class="btn btn-outline btn-sm btn-preset" onclick="applyParserPreset('full')">
                    Полный <span class="tt" data-tip="Период: вся история чата. Все типы ссылок. Лимит: 10000. Короткие ссылки разворачиваются в полные (bit.ly → реальный URL, telegra.ph → исходный). Максимальный сбор, может занять долго.">?</span>
                </button>
                <button class="btn btn-outline btn-sm btn-preset" onclick="applyParserPreset('invites')">
                    Инвайты <span class="tt" data-tip="Только приглашения в приватные чаты (вид t.me/+hash). Период: вся история. Лимит: 5000. С разворачиванием коротких ссылок. Для сбора именно приватных приглашений без публичных каналов.">?</span>
                </button>
                <div style="font-size:0.66rem;color:var(--text-muted);margin-top:4px;font-style:italic;">
                    Наведите на «?» рядом с кнопкой — там написано, что она делает. Любую настройку сверху можно потом поправить руками.
                </div>
            </div>


            <!-- Прогресс -->
            <div id="parser-progress" style="display:none;">
                <div class="progress mb-2"><div class="progress-bar" id="parser-bar" style="width:0%;"></div></div>
                <div class="text-sm text-muted" id="parser-status-text">Парсинг...</div>
            </div>

            <!-- Результат -->
            <div id="parser-result" style="display:none;" class="mt-3">
                <div class="info-box info-box--success" style="padding:var(--space-4) var(--space-5);">
                    <div class="d-flex align-center mb-2" style="gap:10px;flex-wrap:wrap;">
                        <span class="fw-bold" style="font-size:0.95rem;flex-shrink:0;" id="parser-count">0 юзернеймов</span>
                        <!-- Экспорт-кнопки: иконка + текст. Раньше были только
                             иконки — клиент не понимал что это, плюс тултип уходил
                             за viewport. -->
                        <div class="d-flex" style="gap:4px;flex-shrink:0;flex-wrap:wrap;">
                            <button class="btn btn-outline btn-sm" onclick="exportParser('txt')" data-tip="Список строк в .txt"><i class="bi bi-filetype-txt"></i> TXT</button>
                            <button class="btn btn-outline btn-sm" onclick="exportParser('xlsx')" data-tip="Таблица Excel .xlsx"><i class="bi bi-file-earmark-excel"></i> Excel</button>
                            <button class="btn btn-outline btn-sm" onclick="exportParser('spintax')" data-tip="Формат с альтернативами для рассылки"><i class="bi bi-braces"></i> Spintax</button>
                            <button class="btn btn-outline btn-sm" onclick="exportParserByFolders()" data-tip="Каналы / группы / инвайты в отдельные файлы" style="border-color:var(--accent);color:var(--accent);"><i class="bi bi-folder-plus"></i> По папкам</button>
                            <button class="btn btn-outline btn-sm" onclick="copyParserPreview()" data-tip="Скопировать список в буфер обмена"><i class="bi bi-clipboard"></i> Копировать</button>
                            <button class="btn btn-outline btn-sm" onclick="openExportFolder()" data-tip="Открыть папку «Экспорт» в проводнике"><i class="bi bi-folder2-open"></i> Папка</button>
                        </div>
                        <!-- Основные actions с текстом — справа -->
                        <div class="d-flex" style="gap:6px;margin-left:auto;flex-shrink:0;">
                            <button class="btn btn-pink btn-sm" onclick="useParserForDm()" style="white-space:nowrap;">
                                <i class="bi bi-person-lines-fill"></i> В ЛС
                            </button>
                            <button class="btn btn-success btn-sm" onclick="useParserForJoin()" style="white-space:nowrap;">
                                <i class="bi bi-box-arrow-in-right"></i> В подписку
                            </button>
                        </div>
                    </div>
                    <!-- ИИ-ранжирование найденных чатов (видно только для результата-чатов) -->
                    <div id="parser-ai-rank-row" class="d-flex gap-2 mb-2" style="display:none;flex-wrap:wrap;align-items:center;">
                        <input type="text" class="form-control" id="parser-ai-rank-topic" placeholder="Тема для оценки чатов: крипто-обмен" style="flex:1;min-width:180px;max-width:340px;">
                        <button class="btn btn-outline btn-sm" onclick="aiRankChats(this)" style="border-color:var(--accent);color:var(--accent);white-space:nowrap;">
                            <i class="bi bi-sort-down"></i> Ранжировать ИИ
                        </button>
                        <span class="text-xs text-muted">ИИ оценит чаты 0-100 по релевантности и отсортирует. Ключ: Настройки → ИИ.</span>
                    </div>
                    <div id="parser-stats" class="text-xs text-muted mb-2"></div>
                </div>
                <!-- Chip-фильтр результатов парсинга (тип/категория). Показывается
                     только когда есть смысл фильтровать — режим user_chats или
                     смешанные юзернеймы+ID. См. _renderParserResultChips в app.js. -->
                <div id="parser-result-chips" class="multi-folder-bar" style="display:none;margin-bottom:8px;"></div>
                <textarea class="form-control" id="parser-preview" rows="8" readonly style="font-family:monospace;font-size:0.75rem;background:var(--bg-input);"></textarea>
            </div>
        </div>
    </div>
            <div class="run-row">
            <div class="d-flex gap-2 mb-3 flex-wrap">
                <button class="btn btn-accent btn-cta-lg" onclick="startParser()" id="btn-parser">
                    <i class="bi bi-play-fill"></i> Начать парсинг
                </button>
                <button class="btn btn-danger btn-cta-lg" onclick="stopParser()" id="btn-parser-stop" style="display:none;">
                    <i class="bi bi-stop-fill"></i> Остановить
                </button>
            </div>
            </div>
</div>

<!-- ═══ TAB: Профили ═══ -->
<div class="section" id="tab-profiles">
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-person-badge text-purple"></i><div class="ch-text"><div class="ch-title">Заполнение профилей</div><div class="card-sub">автозаполнение профилей</div></div></div>
        <div class="card-body">
            <div class="info-box">
                Обновляет имя, фамилию, био и аватарку выбранного аккаунта.<br>
                <b class="text-accent" >Ко всем</b> — каждому аккаунту поставит разные данные (генерация/варианты в скобках).<br>
                Варианты в скобках: <code>{вариант1|вариант2}</code> — случайный вариант для каждого акка.
            </div>

            <div class="acc-selector mb-3" id="acc-selector-profiles"></div>

            <div class="rd-group"><div class="rd-group-title">ИМЯ И ФАМИЛИЯ</div>
            <!-- Генерация имён -->
            <div class="d-flex gap-3 mb-3 flex-wrap align-center">
                <label class="opt-row" >
                    <input type="checkbox" id="pf-gen-name" onchange="toggleGenName()" >
                    Автогенерация имени
                </label>
                <label class="opt-row" >
                    <input type="checkbox" id="pf-gen-surname" onchange="toggleGenSurname()" >
                    Автогенерация фамилии
                </label>
                <button class="btn btn-outline btn-sm" onclick="previewGenName()" style="padding:3px 10px;font-size:0.65rem;">
                    <i class="bi bi-dice-3"></i> Превью
                </button>
                <span id="pf-gen-preview" class="text-xs text-accent ml-1"></span>
            </div>

            <div style="font-size:0.72rem;color:var(--text-muted);margin-bottom:8px;padding:6px 10px;background:rgba(106,178,242,.08);border-left:3px solid var(--accent-light);border-radius:4px;">
                <i class="bi bi-info-circle"></i> Любое поле которое тронул — отправится в TG. Пустое поле = ОЧИСТИТЬ в профиле (стереть фамилию/username/био). Не трогал поле = оставить в TG как было.
            </div>

            <div class="grid-2 mb-3">
                <div>
                    <label class="form-label">Имя</label>
                    <input type="text" class="form-control" id="pf-firstname" placeholder="Имя или {Имя1|Имя2}" oninput="this.dataset.touched='1'">
                </div>
                <div>
                    <label class="form-label">Фамилия</label>
                    <input type="text" class="form-control" id="pf-lastname" placeholder="Фамилия или {Фам1|Фам2}" oninput="this.dataset.touched='1'">
                    <label class="opt-row" style="margin-top:4px;font-size:0.7rem;color:var(--text-muted);">
                        <input type="checkbox" id="pf-clear-lastname">
                        <span data-tip="Снять старую фамилию у всех выбранных аккаунтов в TG. Полезно когда раньше ставил фамилии (или их прислал поставщик) и теперь хочешь чистое имя без хвоста.">Очистить фамилию у всех</span>
                    </label>
                </div>
            </div>
            </div>

            <div class="rd-group"><div class="rd-group-title">USERNAME</div>
            <!-- Автогенерация username -->
            <div class="d-flex gap-3 mb-2 flex-wrap align-center">
                <label class="opt-row" >
                    <input type="checkbox" id="pf-gen-username" onchange="toggleGenUsername()">
                    Автогенерация username
                </label>
                <button class="btn btn-outline btn-sm btn-preset" onclick="previewGenUsername()">
                    <i class="bi bi-dice-3"></i> Превью
                </button>
                <span id="pf-gen-username-preview" class="text-xs" style="color:var(--accent-light);margin-left:4px;"></span>
            </div>
            <label class="form-label">Username (@ в начале не нужен)</label>
            <textarea class="form-control" id="pf-username" rows="2" placeholder="один username — на всех; или несколько (каждый с новой строки / через запятую) — раздам по аккам без повторов; пусто = стереть" oninput="this.dataset.touched='1'"></textarea>
            <div class="text-xs" style="color:var(--text-muted);margin-top:2px;">Несколько юзиков — по одному в строке (или через запятую): раздаю 1:1 по аккам. Автогенерация проверяет занятость и берёт свободный.</div>
            <label class="opt-row mb-3" style="margin-top:4px;font-size:0.7rem;color:var(--text-muted);">
                <input type="checkbox" id="pf-clear-username">
                <span data-tip="Снять @username у всех выбранных аккаунтов в TG. После этого в профиле будет «без юзернейма».">Очистить имя пользователя у всех</span>
            </label>
            </div>

            <div class="rd-group"><div class="rd-group-title">БИО</div>
            <label class="form-label">Био (описание профиля)</label>
            <textarea class="form-control mb-2" id="pf-about" rows="2" placeholder="Описание профиля (до 70 символов, варианты в скобках поддерживается)" maxlength="70" oninput="this.dataset.touched='1'"></textarea>
            <label class="opt-row mb-2" style="font-size:0.7rem;color:var(--text-muted);">
                <input type="checkbox" id="pf-clear-about">
                <span data-tip="Снять био у всех выбранных аккаунтов в TG.">Очистить описание у всех</span>
            </label>
            <button type="button" class="btn btn-outline btn-sm mb-3" onclick="spintaxPreview('pf-about','pf-about-preview')">
                <i class="bi bi-eye"></i> Предпросмотр варианты в скобкаха
            </button>
            <div id="pf-about-preview" class="spintax-preview" style="display:none;"></div>
            </div>

            <div class="rd-group"><div class="rd-group-title">АВАТАРКА</div>
            <label class="form-label">Аватарка</label>
            <div class="d-flex gap-2 mb-2 flex-wrap align-center">
                <label class="btn btn-outline btn-sm" style="cursor:pointer;margin:0;display:flex;align-items:center;">
                    <i class="bi bi-image"></i> Выбрать фото
                    <input type="file" accept="image/*" style="display:none" id="pf-avatar-input" onchange="previewAvatar(this)">
                </label>
                <label class="opt-row" >
                    <input type="checkbox" id="pf-avatar-emoji" onchange="toggleEmojiAvatar()">
                    Эмодзи-аватарка
                </label>
                <span class="text-sm text-muted self-center" id="pf-avatar-name">Не выбрано</span>
            </div>
            <div id="pf-emoji-row" class="mb-2" style="display:none;font-size:0.7rem;color:var(--text-muted);">
                Кастомный эмодзи (оставь пусто для случайного): <input type="text" id="pf-avatar-emoji-char" maxlength="4" placeholder="🎭" style="width:60px;padding:3px 6px;font-size:1.1rem;text-align:center;background:var(--bg-input);border:1px solid var(--border);border-radius:4px;color:var(--text);">
                <span style="margin-left:8px;">Цвет фона: <input type="color" id="pf-avatar-emoji-bg" value="#3b82f6" style="width:32px;height:24px;vertical-align:middle;border:none;cursor:pointer;"></span>
            </div>

            <!-- Импорт фото из папки — для тех у кого есть заготовленная папка с аватарками.
                 Программа сама возьмёт случайное фото из указанной папки. При применении
                 «Ко всем аккаунтам» — каждому аккаунту разное фото (без повторов пока папка
                 не закончится). -->
            <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:0.75rem;color:var(--text-muted);margin-bottom:6px;">
                <input type="checkbox" id="pf-avatar-folder-enabled" onchange="toggleFolderAvatar()">
                Случайное фото из папки
            </label>
            <div id="pf-folder-row" class="mb-2" style="display:none;">
                <div class="d-flex gap-2 align-center">
                    <input type="text" class="form-control flex-1" id="pf-avatar-folder" placeholder="C:\Users\...\Profile pics\  (папка с jpg/png)">
                    <button class="btn btn-outline btn-sm" onclick="openAvatarFolder()" data-tip="Открыть папку в Проводнике">
                        <i class="bi bi-folder2-open"></i>
                    </button>
                    <button class="btn btn-outline btn-sm" onclick="scanAvatarFolder()">
                        <i class="bi bi-search"></i> Проверить
                    </button>
                </div>
                <div id="pf-folder-info" style="font-size:0.68rem;color:var(--text-muted);margin-top:4px;">
                    Укажи путь к папке с .jpg / .png файлами. Нажми «Проверить» — увидишь сколько файлов.
                </div>
            </div>
            <div id="pf-avatar-preview" style="display:none;margin-bottom:12px;">
                <img id="pf-avatar-img" style="width:64px;height:64px;border-radius:50%;object-fit:cover;border:2px solid var(--accent);">
            </div>
            </div>

            <div class="d-flex gap-2">
                <button class="btn btn-accent btn-sm" onclick="applyProfile()">
                    <i class="bi bi-check2"></i> Применить к выбранному
                </button>
                <button class="btn btn-outline btn-sm" onclick="applyProfileAll()">
                    <i class="bi bi-people"></i> Ко всем аккаунтам
                </button>
                <button class="btn btn-outline btn-sm" id="pf-stop-btn" onclick="stopProfileFill()" style="display:none;border-color:var(--danger);color:var(--danger);">
                    <i class="bi bi-stop-circle"></i> Стоп
                </button>
            </div>
            <div id="pf-result" style="display:none;" class="mt-3 text-sm"></div>
        </div>
    </div>

    <!-- ── Массовое заполнение из папки с материалами ── -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-folder-fill text-accent"></i> Массовое заполнение из материалов</div>
        <div class="card-body">
            <div class="info-box mb-3">
                Альтернатива ручному вводу — даёшь софту папку с материалами, и каждый акк получает свой комплект из пула. Структура папки:
                <pre style="background:var(--bg-input);padding:8px 10px;margin-top:6px;border-radius:4px;font-size:0.7rem;color:var(--text-muted);line-height:1.5;">Заполнение профилей/
├── Женские/        ← опционально
│   ├── Имена.txt      (список имён, по одному на строку)
│   ├── Фамилии.txt
│   ├── Юзернеймы.txt  (варианты в скобках: {trade|crypto}_{bot|hub}; занятый — подберётся свободный)
│   ├── Био.txt        (можно несколько строк — рандом)
│   ├── Аватарки/      (jpg/png)
│   └── Сторис/        (опционально, jpg/png/mp4)
└── Мужские/           ← аналогично</pre>
                Каждый акк получает <b>случайные</b> данные из своего пула (Ж или М). Если папка одного пола пустая — берётся из общей.
            </div>

            <div class="d-flex gap-2 mb-3 align-center flex-wrap">
                <label class="form-label" style="margin-bottom:0;">Папка с материалами:</label>
                <input type="text" class="form-control" id="bf-materials-path" style="flex:1;min-width:280px;" placeholder="C:\Users\...\Заполнение профилей">
                <button class="btn btn-outline btn-sm" onclick="bfScanMaterials()" style="font-size:0.7rem;padding:5px 12px;">
                    <i class="bi bi-search"></i> Проверить
                </button>
                <button class="btn btn-outline btn-sm" onclick="bfOpenMaterials()" style="font-size:0.7rem;padding:5px 12px;">
                    <i class="bi bi-folder2-open"></i>
                </button>
            </div>
            <div id="bf-scan-result" style="font-size:0.7rem;color:var(--text-muted);margin-bottom:12px;line-height:1.6;"></div>

            <label class="form-label">Аккаунты для заполнения</label>
            <div class="acc-selector mb-3" id="acc-selector-bulk-fill"></div>

            <details class="ad-block" open>
                <summary><i class="bi bi-list-check"></i> Что обновлять</summary>
                <div class="ad-body">
                    <label class="ad-check"><input type="checkbox" id="bf-do-name" checked> <span>Обновлять имя/фамилию<span class="ad-hint">Берёт случайные из Имена.txt и Фамилии.txt</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="bf-do-username"> <span>Обновлять юзернейм<span class="ad-hint">Случайная строка из Юзернеймы.txt (варианты в скобках). Занятый @ — подберётся свободный; повторы между акками исключаются (база использованных)</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="bf-do-bio" checked> <span>Обновлять био<span class="ad-hint">Случайная строка из Био.txt (макс 70 символов)</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="bf-do-avatar" checked> <span>Обновлять аватарку<span class="ad-hint">Случайное фото из папки Аватарки/</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="bf-do-stories"> <span>Загрузить сторис<span class="ad-hint">Из папки Сторис/. Будет загружено 1-3 случайных истории</span></span></label>
                </div>
            </details>

            <details class="ad-block">
                <summary><i class="bi bi-gear"></i> Дополнительные опции</summary>
                <div class="ad-body">
                    <label class="ad-check"><input type="checkbox" id="bf-avatar-once" checked> <span>Использовать аватарки по одному разу<span class="ad-hint">Использованные фото переезжают в подпапку used/ — не достанутся другому акку</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="bf-delete-old"> <span>Удалить старые аватарки перед установкой<span class="ad-hint">У акка останется только новая фотка, старые удалятся</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="bf-move-processed"> <span>Перемещать обработанные аккаунты<span class="ad-hint">После заполнения акк переедет в указанную папку — удобно отделять «готовые»</span></span></label>
                    <div style="margin-left:24px;margin-top:6px;display:flex;gap:8px;align-items:center;">
                        <label class="form-label" style="margin-bottom:0;font-size:0.7rem;">Куда перемещать: <span class="tt" data-tip="Дубли не будут — общая память внутри пула отсеивает повторные алерты на одно сообщение, даже если 2 акка сидят в одном чате.">?</span></label>
                        <input type="text" class="form-control" id="bf-target-folder" placeholder="например: Аккаунты/Готовые" style="font-size:0.72rem;flex:1;">
                    </div>
                </div>
            </details>

            <div id="bf-progress" style="display:none;margin-top:8px;">
                <div class="progress mb-2-x">
                    <div class="progress-bar" id="bf-progress-bar" style="width:0%;"></div>
                </div>
                <div style="font-size:0.74rem;color:var(--text-muted);" id="bf-progress-text">—</div>
            </div>
        </div>
    </div>
    <div class="run-row">
    <div class="d-flex gap-2 mb-2 align-center flex-wrap">
        <label class="form-label m-0" data-tip="Сколько аккаунтов обрабатывается одновременно. 1 = по очереди, 5-10 = быстрее в 5-10 раз. У кого задан прокси — идёт через него.">Потоки <span class="text-muted" style="font-size:0.7rem;">?</span></label>
        <input type="number" class="form-control" id="bf-threads" value="1" min="1" max="100" style="width:70px;">
        <button class="btn btn-accent" onclick="bfStart()" id="btn-bf-start">
            <i class="bi bi-play-fill"></i> Заполнить выбранные
        </button>
        <button class="btn btn-danger" onclick="bfStop()" id="btn-bf-stop" style="display:none;">
            <i class="bi bi-stop-fill"></i> Остановить
        </button>
        <span id="bf-status-label" class="text-xs text-muted tag-right"></span>
    </div>
    </div>
</div>

<!-- ═══ TAB: Мониторинг чатов ═══ -->
<div class="section" id="tab-monitor">
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-broadcast" style="color:#ef4444;"></i><div class="ch-text"><div class="ch-title">Мониторинг чатов в реальном времени</div><div class="card-sub">отслеживание новых сообщений</div></div></div>
        <div class="card-body">
            <div style="background:var(--surface-danger-bg);border:1px solid var(--surface-danger-border);border-radius:5px;padding:10px 14px;margin-bottom:12px;font-size:0.72rem;color:var(--text-muted);line-height:1.6;">
                Выбранный <b>один аккаунт</b> сидит в указанных чатах и при появлении ключевого слова в сообщении шлёт уведомление в «Сохранённые» (или в указанный чат/юзера).<br>
                Аккаунт должен <b>состоять в этих чатах</b> — инвайт-ссылки программа пройдёт сама, если есть свободный лимит вступлений.<br>
                <b>Мульти-аккаунтный мониторинг есть</b> (блок ниже), но это риск: Telegram банит за несколько сессий, слушающих одно и то же. Безопаснее один акк — он потянет 500+ чатов, просто добавь их все в список.
            </div>

            <div class="rd-group"><div class="rd-group-title">АККАУНТ</div>
            <label class="form-label fs-72">Аккаунт для мониторинга</label>
            <div class="acc-selector mb-3" id="acc-selector-monitor"></div>
            </div>

            <!-- Multi-acc мониторинг: несколько акков на одних/разных чатах -->
            <details class="ad-block">
                <summary>
                    <i class="bi bi-people-fill"></i> Мульти-аккаунтный мониторинг (несколько акков)
                </summary>
                <div class="ad-body">
                    <label class="form-label fs-70">Дополнительные акки (по одному номеру на строке)</label>
                    <textarea class="form-control mb-2" id="monitor-extra-phones" rows="3"
                        placeholder="79xxxxxxxxx&#10;37xxxxxxxxx&#10;Оставь пусто чтобы юзать одиночный режим"></textarea>
                    <label class="form-label fs-70">Режим распределения чатов</label>
                    <select class="form-control mb-2 fs-78" id="monitor-multi-mode">
                        <option value="redundant">Redundant — все акки во всех чатах (надёжнее, при бане одного остальные продолжат)</option>
                        <option value="split">Split — чаты делятся между акками поровну (быстрее, меньше нагрузки)</option>
                    </select>
                    
                </div>
            </details>

            <div style="background:var(--surface-info-bg);border:1px solid var(--border-accent);border-radius:4px;padding:8px 12px;margin-top:-8px;margin-bottom:12px;font-size:0.68rem;color:var(--text-muted);line-height:1.5;">
                <i class="bi bi-folder2-open text-accent"></i> <b>Совет:</b> закинь файлы акка <code>{phone}.session</code> и <code>{phone}.json</code> в папку <code>Аккаунты/Мониторинг/</code> — софт сам подхватит этот акк для мониторинга, даже если кэш настроек слетит после обновы.
            </div>

            <div class="rd-group"><div class="rd-group-title">ЧАТЫ И СЛОВА</div>
            <label class="form-label">Чаты для мониторинга (по одной ссылке/юзернейму на строке)</label>
            <textarea class="form-control mb-3" id="monitor-chats" rows="6"
                placeholder="@chatname&#10;https://t.me/chatname&#10;https://t.me/+invitehash"></textarea>

            <label class="form-label">Ключевые слова (через запятую или с новой строки)</label>
            <textarea class="form-control mb-3" id="monitor-keywords" rows="3"
                placeholder="ищу, ищю, выйду, куплю"></textarea>

            <label class="form-label">Стоп-слова — пропускать сообщения с ними <span style="color:var(--text-muted);font-weight:normal;font-size:0.7rem;">(через запятую или с новой строки)</span> <span class="tt" data-tip="Кнопочный бот: старт/итог задач + live-потоки + Стоп/Пауза прямо из Telegram. Следи за фермой удалённо (нужны ключ бота + Chat ID выше).">?</span></label>
            <textarea class="form-control mb-3" id="monitor-ignore-words" rows="2"
                placeholder="реклама, casino, ставки, продаю — если в сообщении есть любое из этих слов, алерта не будет"></textarea>

            <label class="d-flex align-center gap-2 mb-3" style="cursor:pointer;font-size:0.78rem;" data-tip="Если включено — на одного человека уведомление придёт только один раз. Если ВЫКЛ — каждое новое сообщение от того же юзера в чатах мониторинга тригерит алерт заново. Хранится в data/monitor_contacted.json — список можно посмотреть/очистить ниже.">
                <input type="checkbox" class="form-check-input" id="monitor-dedupe" onchange="saveSettings()" checked>
                <span><b>Один человек — одно уведомление</b> <span style="color:var(--text-muted);">— повторные сообщения того же человека пропускаем</span></span>
            </label>
            </div>

            <!-- Bot API режим (рекомендуемый способ) -->
            <div style="background:var(--surface-info-bg);border:1px solid var(--border-accent);border-radius:5px;padding:10px 14px;margin-bottom:12px;">
                <div style="font-weight:600;color:var(--accent-light);margin-bottom:6px;font-size:0.82rem;">
                    <i class="bi bi-robot"></i> Куда слать уведомления — через своего бота <span style="color:var(--success);font-size:0.7rem;font-weight:normal;">(рекомендуется)</span>
                </div>
                <div style="font-size:0.68rem;color:var(--text-muted);line-height:1.6;margin-bottom:10px;">
                    <b class="text-accent" >Общий шаг:</b> у <a class="text-accent" href="https://t.me/BotFather" target="_blank">@BotFather</a> отправь <code>/newbot</code> → получи <b>ключ бота</b>, вставь в поле слева.<br><br>
                    <b class="text-accent" >Вариант 1 — в ЛС с ботом</b> (только для тебя):<br>
                    <b>a)</b> Найди своего нового бота в Telegram со <b>личного аккаунта</b> → напиши <code>/start</code>.<br>
                    <b>b)</b> Нажми <b>«Определить Chat ID»</b> ниже — софт достанет твой id. <b>В чат добавлять не надо.</b><br>
                    <b>c)</b> Нажми <b>«Тест бота»</b> — придёт в ЛС с ботом.<br><br>
                    <b class="text-accent" >Вариант 2 — в общий чат</b> (если хочешь чтобы видела вся команда):<br>
                    <b>a)</b> Создай группу в Telegram → добавь туда бота → сделай его <b>админом</b> с правом писать (опция «Разрешить постинг»).<br>
                    <b>b)</b> В группе напиши <code>/start@имя_твоего_бота</code> (или любое сообщение).<br>
                    <b>c)</b> Нажми <b>«Определить Chat ID»</b> — софт возьмёт id группы (будет отрицательное число вида <code>-1001234567890</code>).<br>
                    <b>d)</b> Нажми <b>«Тест бота»</b> — придёт в группу.<br><br>
                    <span class="text-warning" ><i class="bi bi-info-circle"></i></span> Если нужен ID вручную — напишите <a class="text-accent" href="https://t.me/userinfobot" target="_blank">@userinfobot</a> с нужного аккаунта. Но кнопка «Определить» находит его сама — и для лички, и для групп.
                </div>
                <div class="grid-2">
                    <div>
                        <label class="form-label fs-70">ключ бота <span style="color:var(--text-muted);font-weight:normal;">(от @BotFather)</span></label>
                        <input type="password" class="form-control" id="monitor-bot-token"
                            placeholder="123456789:AA..." autocomplete="new-password">
                        <div id="monitor-bot-token-saved" style="font-size:0.62rem;color:var(--success);margin-top:2px;display:none;">✓ токен сохранён — оставь пустым чтобы не менять</div>
                    </div>
                    <div>
                        <label class="form-label fs-70">Chat ID <span style="color:var(--text-muted);font-weight:normal;">(ЛС бота с тобой)</span></label>
                        <input type="text" class="form-control" id="monitor-bot-chat-id"
                            placeholder="например 123456789">
                    </div>
                </div>
                <div style="font-size:0.65rem;color:var(--text-muted);margin-top:8px;display:flex;align-items:center;gap:8px;flex-wrap:wrap;">
                    <button type="button" class="btn btn-accent btn-sm" style="padding:3px 10px;font-size:0.7rem;" onclick="detectChatId()" data-tip="Найдёт ваш ID по сообщению /start, которое вы отправили боту">
                        <i class="bi bi-magic"></i> Определить Chat ID
                    </button>
                    <button type="button" class="btn btn-outline btn-sm" style="padding:3px 10px;font-size:0.7rem;" onclick="testMonitorBot()" data-tip="Отправить тестовое сообщение — проверит, что бот и адрес правильно связаны">
                        <i class="bi bi-send-check"></i> Тест бота
                    </button>
                    <span style="flex:1;min-width:160px;text-align:right;">Уведомления придут в <b>ЛС с ботом</b> (в твой личный Telegram).</span>
                </div>
                <label class="d-flex align-center gap-2" style="cursor:pointer;margin-top:10px;background:var(--surface-success-bg);border:1px solid var(--surface-success-border);border-radius:5px;padding:8px 12px;">
                    <input type="checkbox" id="monitor-bot-reports" onchange="toggleBotReports(this.checked)" style="width:17px;height:17px;">
                    <div style="flex:1;">
                        <div style="font-weight:600;font-size:0.8rem;color:var(--text-primary);">Отчёты о работе фермы в бот</div>
                        
                    </div>
                </label>
            </div>

            <!-- Fallback через аккаунт-мониторщик (если бот не настроен) -->
            <details class="ad-block" id="monitor-fallback-wrap">
                <summary>
                    <i class="bi bi-person-check"></i> Альтернатива: слать от лица аккаунта-мониторщика (если не хочешь настраивать бота)
                </summary>
                <div class="ad-body">
                    <label class="form-label">Куда слать (fallback, если бот не задан) <span class="tt" data-tip="me = Сохранённые этого же аккаунта. Можно указать @username другого аккаунта или канала. Используется только если ключ бота выше не задан.">?</span></label>
                    <input type="text" class="form-control" id="monitor-target" value="me"
                        placeholder="me = Сохранённые / @username / id чата / t.me/chat">
                    
                </div>
            </details>

            <label class="form-label">Автосообщение в ЛС автору совпавшего коммента (опционально)</label>
            <textarea class="form-control mb-2" id="monitor-auto-dm" rows="3"
                placeholder="{Привет|Здравствуйте}! Видел ваш комментарий. Могу помочь — напишите что интересует."></textarea>
            <div style="background:var(--surface-info-bg);border:1px solid var(--surface-info-border);border-radius:4px;padding:8px 12px;margin-bottom:12px;font-size:0.68rem;color:var(--text-muted);line-height:1.5;">
                <b style="color:#fbbf24;"><i class="bi bi-exclamation-triangle-fill"></i> Один человек — одно уведомление:</b> после первого совпадения он попадает в <b>список исключений</b>, и следующие его сообщения (в любом чате, с любого твоего акка) <b>не будут</b> триггерить ни уведомление, ни авто-сообщение в личку. Хранится в <code>data/monitor_contacted.json</code>, переживает обновления и рестарты софта.<br>
                Варианты в скобках <code>{привет|здравствуйте}</code> поддерживается. Задержка 3-10с перед отправкой.<br>
                <div style="display:flex;gap:6px;margin-top:6px;flex-wrap:wrap;align-items:center;">
                    <input type="text" id="monitor-ignore-input" placeholder="@юзернейм или числовой ID"
                        style="flex:1;min-width:180px;padding:3px 8px;font-size:0.7rem;background:var(--bg-input);border:1px solid var(--border);border-radius:4px;color:var(--text-primary);">
                    <button type="button" class="btn btn-outline btn-sm" style="padding:2px 10px;font-size:0.65rem;" onclick="addToIgnoreList()"><i class="bi bi-plus-circle"></i> В игнор</button>
                    <button type="button" class="btn btn-outline btn-sm" style="padding:2px 8px;font-size:0.65rem;" onclick="openIgnoreDb()"><i class="bi bi-database"></i> База</button>
                    <button type="button" class="btn btn-outline btn-sm" style="padding:2px 8px;font-size:0.65rem;" onclick="resetContactedList()"><i class="bi bi-trash"></i> Сбросить все</button>
                    <span class="ml-auto" id="monitor-contacted-count"></span>
                </div>
            </div>

            <details class="ad-block">
                <summary><i class="bi bi-shield-check"></i> Защита аккаунта</summary>
                <div class="ad-body">
                    <label class="ad-check"><input type="checkbox" id="monitor-solve-captcha"> <span>Решать капчу-боты в чатах<span class="ad-hint">Если в мониторимом чате антиспам-бот попросит подтвердить — нажмём «я не бот»</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="monitor-keep-online"> <span>Держать аккаунт онлайн во время мониторинга</span></label>
                </div>
            </details>


            <div id="monitor-status" style="display:none;background:var(--surface-info-bg);border:1px solid var(--surface-info-border);border-radius:5px;padding:10px 14px;font-size:0.75rem;">
                <div class="d-flex align-center justify-between mb-1">
                    <span class="fw-bold text-accent-base"><i class="bi bi-record-circle"></i> Работает</span>
                    <span id="monitor-matched" class="text-muted">Алертов: 0</span>
                </div>
                <div id="monitor-info" class="text-muted text-xs"></div>
            </div>
        </div>
    </div>
            <div class="run-row">
            <div class="d-flex gap-2 mb-3">
                <button class="btn btn-accent" onclick="startMonitor()" id="btn-monitor-start">
                    <i class="bi bi-play-fill"></i> Старт мониторинга
                </button>
                <button class="btn btn-outline" onclick="resumeMonitor()" id="btn-monitor-resume"
                        data-tip="Восстановить мониторинг из сохранённого конфига (после перезапуска софта он не возобновляется сам)">
                    <i class="bi bi-arrow-clockwise"></i> Восстановить
                </button>
                <button class="btn btn-danger" onclick="stopMonitor()" id="btn-monitor-stop" style="display:none;">
                    <i class="bi bi-stop-fill"></i> Стоп
                </button>
                <button class="btn btn-outline" onclick="openMonitorLog()" data-tip="Открыть лог всех попаданий по ключам (файл .txt)">
                    <i class="bi bi-file-earmark-spreadsheet"></i> Лог матчей
                </button>
            </div>
            </div>
</div>

<!-- TAB «Досье» удалён: Досье теперь режим в дропдауне Парсинга (#parser-dossier-block). -->

<!-- ═══ TAB: Автоответчик ═══ -->
<div class="section" id="tab-autoreply">
    <!-- Живая лента: владелец 12.08.2026 — «хочу видеть, что тебе на АО пишется,
         кому, что и какой номер». Дописывается сама, пока вкладка открыта. -->
    <div class="card mb-3" style="border-left:3px solid #34d399;">
        <div class="card-header">
            <i class="bi bi-broadcast" style="color:#34d399;"></i>
            <div class="ch-text">
                <div class="ch-title">Что происходит сейчас</div>
                <div class="card-sub">кто написал, каким аккаунтом ответили и что именно</div>
            </div>
        </div>
        <div class="card-body">
            <div class="d-flex gap-3 align-center flex-wrap" style="margin-bottom:10px;">
                <span class="text-sm" id="ar-feed-state" style="color:var(--text-muted);">Слежу за перепиской…</span>
                <button class="btn btn-outline btn-sm" onclick="arFeedClear()" style="font-size:0.7rem;padding:5px 12px;">
                    <i class="bi bi-eraser"></i> Очистить
                </button>
            </div>
            <div id="ar-feed" style="max-height:340px;overflow-y:auto;border:1px solid var(--border);border-radius:6px;padding:8px;background:#14141e;">
                <div class="text-xs text-muted" id="ar-feed-empty">
                    Пока тихо. Как только кто-то напишет в личку аккаунту с включённым автоответчиком — строка появится здесь.
                </div>
            </div>
        </div>
    </div>
    <div class="card mb-3" style="border-left:3px solid #a78bfa;">
        <div class="card-header"><i class="bi bi-person-lines-fill" style="color:#a78bfa;"></i><div class="ch-text"><div class="ch-title">Собранные лиды</div><div class="card-sub">автоответы в личных сообщениях</div></div></div>
        <div class="card-body">
            <div style="font-size:0.75rem;color:var(--text-muted);margin-bottom:10px;">
                Кто сам написал в ЛС и получил автоответ — тёплые контакты (человек уже проявил интерес). Выгрузи в Excel или списком .txt и дорабатывай вручную или рассылкой.
            </div>
            <div class="d-flex gap-3 align-center flex-wrap">
                <span class="text-sm"><i class="bi bi-people"></i> Лидов собрано: <b id="ar-leads-count">—</b></span>
                <button class="btn btn-outline btn-sm" onclick="arLoadLeads()" style="font-size:0.7rem;padding:5px 12px;"><i class="bi bi-arrow-clockwise"></i> Обновить</button>
                <button class="btn btn-accent btn-sm" onclick="arExportLeads()" style="font-size:0.7rem;padding:5px 12px;"><i class="bi bi-download"></i> Выгрузить (Excel + txt)</button>
            </div>
            <div id="ar-leads-preview" style="font-size:0.7rem;color:var(--text-muted);margin-top:10px;line-height:1.7;"></div>
            <div class="d-flex gap-3 align-center flex-wrap" style="margin-top:14px;padding-top:12px;border-top:1px solid var(--border);">
                <span class="text-sm"><i class="bi bi-chat-dots"></i> Живых чатов собрано: <b id="lc-count">—</b></span>
                <button class="btn btn-outline btn-sm" onclick="lcLoad()" style="font-size:0.7rem;padding:5px 12px;"><i class="bi bi-arrow-clockwise"></i> Обновить</button>
                <button class="btn btn-accent btn-sm" onclick="lcOpen()" style="font-size:0.7rem;padding:5px 12px;"><i class="bi bi-folder2-open"></i> Открыть файл</button>
            </div>
            <div style="font-size:0.7rem;color:var(--text-muted);margin-top:6px;">
                Собираются <b>автоматически во время рассылки</b> — не нужно ничего включать. Живым чат считается, когда после твоего сообщения человек <b>пишет акку в ЛС</b> или <b>отвечает прямо в группе</b>: значит там реальные активные люди. Копятся в <b>Экспорт/Живые_чаты.txt</b> (дедуп) — готовый список для Подписки/рассылки. Приватные группы без ссылки пишутся по id (годны для рассылки).
            </div>
        </div>
    </div>
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-reply" style="color:#34d399;"></i> Автоответчик на входящие ЛС</div>
        <div class="card-body">
            <div style="font-size:0.75rem;color:var(--text-muted);margin-bottom:12px;">
                Автоответ на входящие ЛС. Один ответ на юзера. Варианты в скобках: <code>{Привет|Здравствуйте}</code>.
            </div>

            <div class="acc-selector mb-3" id="acc-selector-autoreply"></div>

            <div class="rd-group"><div class="rd-group-title">ТЕКСТ ОТВЕТА</div>
            <label class="form-label">Текст автоответа (поддерживает варианты в скобках)</label>
            <textarea class="form-control mb-2" id="ar-text" rows="3" placeholder="{Привет|Здравствуйте}! Спасибо за сообщение. {Напишите ваш вопрос|Чем могу помочь?}"></textarea>
            <button type="button" class="btn btn-outline btn-sm mb-3" onclick="spintaxPreview('ar-text','ar-text-preview')">
                <i class="bi bi-eye"></i> Предпросмотр варианты в скобкаха
            </button>
            <div id="ar-text-preview" class="spintax-preview" style="display:none;"></div>
            </div>

            <div class="rd-group"><div class="rd-group-title">ЛИМИТЫ</div>
            <div class="grid-3 mb-3">
                <div>
                    <label class="form-label">Мин. задержка (сек) <span class="tt" data-tip="Минимальная задержка перед ответом. Реальная задержка — случайное значение между «мин» и «макс», чтобы не отвечать мгновенно (палится как бот). 3-8с выглядит как «человек прочитал и набрал ответ».">?</span></label>
                    <input type="number" class="form-control" id="ar-delay-min" value="3" min="1" max="60">
                </div>
                <div>
                    <label class="form-label">Макс. задержка (сек) <span class="tt" data-tip="Максимальная задержка перед ответом. Бот ответил через ровно 3с на 50 сообщений подряд — заметно. Разброс «мин-макс» делает паттерн естественным.">?</span></label>
                    <input type="number" class="form-control" id="ar-delay-max" value="8" min="2" max="120">
                </div>
                <div>
                    <label class="form-label">Подхватить ответы за N ч <span class="tt" data-tip="Сколько часов назад искать пропущенные ЛС при старте автоответчика. 0 — отвечаем только на новые, на старые молчим. 24 — отыграем последние сутки. 0 безопаснее: старое сообщение + внезапный ответ выглядит подозрительно.">?</span></label>
                    <input type="number" class="form-control" id="ar-backfill-hours" value="0" min="0" max="48" step="1">
                </div>
            </div>
            </div>

            <div class="rd-group"><div class="rd-group-title">СТОП-СЛОВА</div>
            <label class="form-label">Стоп-слова (через запятую, ответ не отправится если в сообщении есть)</label>
            <input type="text" class="form-control mb-3" id="ar-stop-words" placeholder="отстань, стоп, спам, не пиши">
            </div>

            <details class="ad-block">
                <summary><i class="bi bi-shield-check"></i> Поведение «как живой человек»</summary>
                <div class="ad-body">
                    <label class="ad-check"><input type="checkbox" id="ar-simulate-typing"> <span>Имитация набора (показывать «печатает...» перед ответом)<span class="ad-hint">Перед ответом покажет «печатает…» — выглядит как живой человек</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="ar-mark-as-read"> <span>Отмечать входящее сразу прочитанным<span class="ad-hint">Без этого у юзера висит непрочитанный счётчик — выдаёт автоответ</span></span></label>
                </div>
            </details>


            <!-- Статус -->
            <div id="ar-status"></div>
        </div>
    </div>
            <div class="run-row">
            <div class="d-flex gap-2 mb-3">
                <button class="btn btn-success btn-sm" onclick="startAutoReply()" id="btn-ar-start">
                    <i class="bi bi-play-fill"></i> Запустить
                </button>
                <button class="btn btn-danger btn-sm" onclick="stopAutoReply()" id="btn-ar-stop" style="display:none;">
                    <i class="bi bi-stop-fill"></i> Остановить
                </button>
            </div>
            </div>
</div>

<!-- ═══ TAB: Аналитика ═══ -->
<div class="section" id="tab-analytics">
    <div class="d-flex gap-2 mb-3 flex-wrap">
        <div class="stat-card cell-input-lg">
            <div class="stat-value fs-130" id="stat-sent">0</div>
            <div class="stat-label"><i class="bi bi-send"></i> Отправлено</div>
        </div>
        <div class="stat-card cell-input-lg">
            <div class="stat-value fs-130" id="stat-joined">0</div>
            <div class="stat-label"><i class="bi bi-box-arrow-in-right"></i> Вступлений</div>
        </div>
        <div class="stat-card cell-input-lg">
            <div class="stat-value fs-130" id="stat-blocked">0</div>
            <div class="stat-label"><i class="bi bi-shield-x"></i> Заблокировано</div>
        </div>
        <div class="stat-card cell-input-lg">
            <div class="stat-value fs-130" id="stat-errors">0</div>
            <div class="stat-label"><i class="bi bi-x-circle"></i> Ошибок</div>
        </div>
    </div>
    <div class="card">
        <div class="card-header">
            <i class="bi bi-graph-up" style="color:#14b8a6;"></i><div class="ch-text"><div class="ch-title">Активность по дням</div><div class="card-sub">динамика задач по дням</div></div>
            <button class="btn btn-outline btn-sm ml-auto" onclick="exportExcel()">
                <i class="bi bi-download"></i> Excel
            </button>
        </div>
        <div class="card-body p-4">
            <canvas id="analytics-chart" height="120"></canvas>
        </div>
    </div>

    <!-- Anti-detect статистика (с момента старта программы) -->
    <div class="card mb-3" style="margin-top:12px;">
        <div class="card-header">
            <i class="bi bi-shield-check text-success"></i> Защита аккаунтов — статистика
            <span class="text-xs text-muted ml-auto">с запуска программы</span>
        </div>
        <div class="card-body">
            <div class="d-flex gap-2 flex-wrap">
                <div class="stat-card cell-input">
                    <div class="stat-value" style="font-size:1.15rem;" id="ad-stat-precheck-runs">0</div>
                    <div class="stat-label fs-70"><i class="bi bi-shield-check"></i> Проверок перед стартом</div>
                </div>
                <div class="stat-card cell-input">
                    <div class="stat-value" style="font-size:1.15rem;color:var(--warning);" id="ad-stat-precheck-blocked">0</div>
                    <div class="stat-label fs-70"><i class="bi bi-slash-circle"></i> Найдено в спам-блоке</div>
                </div>
                <div class="stat-card cell-input">
                    <div class="stat-value" style="font-size:1.15rem;color:#a78bfa;" id="ad-stat-captcha">0</div>
                    <div class="stat-label fs-70"><i class="bi bi-puzzle"></i> Капч решено</div>
                </div>
                <div class="stat-card cell-input">
                    <div class="stat-value" style="font-size:1.15rem;color:#5db7ff;" id="ad-stat-profiles">0</div>
                    <div class="stat-label fs-70"><i class="bi bi-person"></i> Профилей просмотрено</div>
                </div>
                <div class="stat-card cell-input">
                    <div class="stat-value" style="font-size:1.15rem;color:#5db7ff;" id="ad-stat-photos">0</div>
                    <div class="stat-label fs-70"><i class="bi bi-image"></i> Фото просмотрено</div>
                </div>
                <div class="stat-card cell-input">
                    <div class="stat-value" style="font-size:1.15rem;color:var(--success);" id="ad-stat-reads">0</div>
                    <div class="stat-label fs-70"><i class="bi bi-eye"></i> Сообщений прочитано</div>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- ═══ TAB: Прогрев ═══ -->
<div class="section" id="tab-warmup">

    <div class="card mb-3" style="border-left:4px solid var(--accent-light); background: rgba(99,102,241,0.07);">
        <div class="card-body" style="padding:12px 16px;">
            <div style="display:flex;align-items:center;gap:8px;margin-bottom:4px;">
                <i class="bi bi-magic" style="color:var(--accent-light);"></i>
                <strong>Хочешь максимум защиты от бана?</strong> Включи AI-генерацию пулов
            </div>
            <div class="text-hint" style="font-size:0.76rem;line-height:1.45;">
                Имена чатов, юзернеймы, приветствия и тексты дневников будут сгенерированы AI индивидуально для тебя. Telegram не сможет палить шаблоны — у каждого клиента TelePush свой набор. Стоит ~$0.05-0.15 одноразово, нужен ключ от любого AI-провайдера (OpenRouter / DeepSeek / OpenAI).
                <br><a class="text-accent" style="font-size:0.76rem;" href="javascript:showTab('settings');setTimeout(function(){var el=document.getElementById('settings-ai');if(el)el.style.display='block';var c=document.getElementById('chev-settings-ai');if(c)c.style.transform='rotate(180deg)';},150);">→ Открыть Настройки → AI</a>
                · <span id="warmup-ai-pool-hint" style="font-size:0.74rem;color:var(--text-muted);">проверка статуса...</span>
            </div>
        </div>
    </div>

    <!-- Аналитика + Отчёт по аккам — кнопки и карточки -->
    <div class="d-flex align-center justify-between mb-2" style="gap:8px;flex-wrap:wrap;">
        <div></div>
        <div class="d-flex" style="gap:8px;flex-wrap:wrap;">
            <button class="btn btn-outline btn-sm" onclick="loadWarmupAnalytics()">
                <i class="bi bi-graph-up-arrow"></i> Аналитика
            </button>
            <button class="btn btn-outline btn-sm" onclick="loadWarmupReport()">
                <i class="bi bi-bar-chart"></i> Отчёт по аккаунтам
            </button>
        </div>
    </div>
    <div id="warmup-analytics" style="display:none;" class="card mb-3">
        <div class="card-header"><i class="bi bi-graph-up-arrow text-accent"></i><div class="ch-text"><div class="ch-title">Аналитика прогрева</div><div class="card-sub">оживление аккаунтов перед работой</div></div></div>
        <div class="card-body" id="warmup-analytics-body">
            <div class="text-muted text-sm">Загрузка...</div>
        </div>
    </div>
    <div id="warmup-report" style="display:none;" class="card mb-3">
        <div class="card-header"><i class="bi bi-bar-chart text-orange"></i> Отчёт по прогреву</div>
        <div class="card-body">
            <div id="warmup-report-summary" class="mb-2 text-sm"></div>
            <div id="warmup-report-table" style="max-height:400px;overflow:auto;font-size:0.75rem;"></div>
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-fire text-orange"></i> Прогрев аккаунтов</div>
        <div class="card-body">
            <!-- Компактный info-блок вместо длинной портянки. -->
            <div class="info-box" style="font-size:0.78rem;line-height:1.55;">
                Акки переписываются между собой, подписываются на каналы и ставят реакции — как живые. Активность плавно растёт 7-21 день.
                Безопасный пресет включён по умолчанию; кому нужны тонкие настройки — раскройте «Расширенные опции» ниже.
            </div>

            <!-- Блоки «Рекомендации» и «Ожидаемый результат» удалены. -->

            <!-- «Безопасный пресет» — большая галка сверху, ставит консервативные дефолты:
                 1 поток, задержка 120-300с, classic режим, тихие часы 23-7 ВКЛ, только DM-сценарий. -->
            <label class="d-flex align-center gap-2 mb-3" style="cursor:pointer;background:var(--surface-success-bg);border:1px solid var(--surface-success-border);border-radius:5px;padding:10px 14px;">
                <input type="checkbox" id="warmup-safe-preset" checked onchange="onWarmupSafePresetChange(this.checked)" style="width:18px;height:18px;">
                <div style="flex:1;">
                    <div style="font-weight:600;font-size:0.85rem;color:var(--text-primary);">Безопасный пресет</div>
                    <div style="font-size:0.7rem;color:var(--text-muted);margin-top:2px;">1 поток, задержки 120-300с, тихие часы 23-7, только переписка между акками. Кликни чтоб поменять — все настройки разблокируются.</div>
                </div>
            </label>

            <!-- Status banner -->
            <div id="warmup-status-banner" style="display:none;" class="mb-3"></div>

            <!-- Schedule progress -->
            <div id="warmup-schedule" style="display:none;" class="mb-3">
                <div class="d-flex align-center justify-between mb-1">
                    <span id="warmup-stage-text" class="text-sm fw-600"></span>
                    <span id="warmup-day-text" class="text-xs text-muted"></span>
                </div>
                <div class="progress" style="height:8px;"><div class="progress-bar" id="warmup-progress-bar" style="width:0%;background:linear-gradient(90deg,#f97316,#ef4444);"></div></div>
                <div class="d-flex justify-between mt-1">
                    <span class="text-xs text-muted">Сообщений сегодня: <b id="warmup-msgs-today">0</b>/<span id="warmup-msgs-limit">0</span></span>
                    <span class="text-xs text-muted">Всего: <b id="warmup-msgs-total">0</b></span>
                </div>
            </div>

            <!-- Простой ряд контролов. Поля «старт с дня» и «сообщений/день» (override)
                 перенесены в «Расширенные опции» ниже — это edge-case настройки. -->
            <div class="rd-group"><div class="rd-group-title">ПАРАМЕТРЫ ЗАПУСКА</div>
            <div class="d-flex gap-2 mb-2 flex-wrap align-center">
                <label class="form-label m-0">Длительность</label>
                <select class="form-control" id="warmup-days" style="width:auto;">
                    <option value="7">7 дней</option>
                    <option value="14">14 дней</option>
                    <option value="21" selected>21 день</option>
                    <option value="30">30 дней</option>
                </select>
                <!-- Видимое поле «С какого дня». Backend принимает start_day. -->
                <label class="form-label m-0" data-tip="С какого дня плана прогрева стартовать. Если акк уже частично прогретый — пропусти первые N дней. Дефолт 1 = с нуля.">Старт с дня <span class="text-muted" style="font-size:0.7rem;">?</span></label>
                <input type="number" class="form-control" id="warmup-start-day" value="1" min="1" max="30" style="width:70px;">
                <label class="form-label m-0" data-tip="Сколько пар прогрева работает одновременно. 1 = строго по очереди (тихо), 5-10 = быстрее в 5-10 раз. Каждая пара через свой акк, акк не используется в двух парах одновременно.">Потоки <span class="text-muted" style="font-size:0.7rem;">?</span></label>
                <input type="number" class="form-control" id="warmup-threads" value="1" min="1" max="100" style="width:70px;">
                <label class="form-label m-0" data-tip="Баланс «реакции / тексты» для сценариев, где акк ведёт свой канал. 70% — чаще ставит реакции (быстрее и безопаснее, меньше текста), 30% — чаще пишет посты. 0 = только тексты, 100 = только реакции.">Реакции, % <span class="text-muted" style="font-size:0.7rem;">?</span></label>
                <input type="number" class="form-control" id="warmup-reaction-share" value="70" min="0" max="100" style="width:70px;">
            </div>
            </div>
            <!-- warmup-start-day стал видимым (выше). Здесь остаётся только warmup-msgs-override (темп сообщений/день). -->
            <input type="hidden" id="warmup-msgs-override" value="0">

            <!-- «Защита аккаунта» вынесена из flex-row кнопок старта (раскрытие внутри ряда ломало layout). -->
            <details class="ad-block">
                <summary><i class="bi bi-shield-check"></i> Защита аккаунта</summary>
                <div class="ad-body">
                    <label class="ad-check"><input type="checkbox" id="warmup-pre-spam-check"> <span>Перед стартом проверить аккаунты на спам-блок</span></label>
                    <!-- «Решать капчу» удалена — капча-боты логируют, потенциальный флаг. -->
                    <input type="hidden" id="warmup-solve-captcha">
                    <label class="ad-check"><input type="checkbox" id="warmup-keep-online"> <span>Держать аккаунт онлайн во время прогрева</span></label>
                    <label class="ad-check"><input type="checkbox" id="warmup-read-msgs"> <span>Читать входящие сообщения<span class="ad-hint">Имитация — открываем чат, скроллим</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="warmup-mark-read"> <span>Отмечать прочитанным</span></label>
                    <label class="ad-check"><input type="checkbox" id="warmup-view-profile"> <span>Смотреть профили партнёров по прогреву</span></label>
                    <label class="ad-check"><input type="checkbox" id="warmup-view-photo"> <span>Смотреть фото профилей</span></label>
                </div>
            </details>

            <!-- Picker: выбор подмножества акков для прогрева. Пусто = все из «Прогрев». -->
            <div class="rd-group"><div class="rd-group-title">АККАУНТЫ</div>
            <div class="d-flex align-center gap-2 mb-2 flex-wrap">
                <label class="form-label m-0">Кого прогревать <span class="tt" data-tip="По умолчанию прогрев работает на ВСЕХ акках из папки «Прогрев». Если выберешь подмножество — будут прогреваться только эти, остальные в папке отдыхают.">?</span></label>
                <div class="acc-selector" id="acc-selector-warmup"></div>
            </div>

            <!-- Accounts table -->
            <h6 style="color:var(--text-muted);font-size:0.8rem;margin-bottom:6px;">Аккаунты в прогреве</h6>
            <div style="max-height:250px;overflow-y:auto;margin-bottom:12px;">
                <table class="table table-sm">
                    <thead><tr>
                        <th>Телефон</th><th>Имя</th><th>Возраст</th>
                        <th>Премиум</th><th>Прокси</th><th>Папка</th><th></th>
                    </tr></thead>
                    <tbody id="warmup-accounts-table">
                        <tr><td colspan="7" style="text-align:center;color:var(--text-muted);padding:16px;">Загрузка...</td></tr>
                    </tbody>
                </table>
            </div>

            <!-- Active pairs -->
            <div id="warmup-pairs-section" style="display:none;">
                <h6 style="color:var(--text-muted);font-size:0.8rem;margin-bottom:6px;">Активные пары</h6>
                <div id="warmup-pairs-list" style="max-height:200px;overflow-y:auto;margin-bottom:12px;"></div>
            </div>
            </div>

            <!-- Инлайн «Лог» убран. Прогрев пишет в единый поток логов (окно «Логи работы»). -->
            <div style="font-size:0.72rem;color:var(--text-muted);margin-top:6px;">
                <i class="bi bi-info-circle"></i> События прогрева идут в окно <b>«Логи работы»</b> — открой кнопкой внизу-слева.
            </div>
        </div>
    </div>

    <!-- «Настройки прогрева» + «Сценарии прогрева» свёрнуты в один expandable «Расширенные опции».
         По умолчанию закрыт — клиенты запускают на дефолтных безопасных настройках. -->
    <details class="ad-block">
        <summary>
            <i class="bi bi-sliders"></i> Расширенные опции
            <span class="ad-note">режим, AI, шаблоны, тихие часы, сценарии</span>
        </summary>
        <div class="ad-body">

    <!-- Warmup Settings -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-gear text-muted"></i> Настройки прогрева</div>
        <div class="card-body" style="display:flex;flex-direction:column;gap:10px;">
            <!-- Gemini Key -->
            <div>
                <label class="form-label">Gemini API Key <span class="text-xs text-muted">(бесплатно на <a href="https://aistudio.google.com/apikey" target="_blank" style="color:var(--accent-light);text-decoration:underline;">aistudio.google.com</a>)</span></label>
                <div class="d-flex gap-2">
                    <input type="password" class="form-control flex-1" id="warmup-gemini-key" placeholder="AIza...">
                    <button class="btn btn-outline btn-sm" onclick="checkGeminiKey()" style="white-space:nowrap;">Проверить</button>
                </div>
            </div>
            <!-- Row: Режим + Генерация + Часы + Задержка (CSS Grid — всё выровнено по единой сетке) -->
            <div class="rd-group"><div class="rd-group-title">РЕЖИМ И ТАЙМИНГ</div>
            <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;align-items:start;">
                <!-- Режимы Hub-акк и Chat-flow удалены (опасные для акков). Остался только Classic (пары в ЛС). -->
                <input type="hidden" id="warmup-mode" value="classic">
                <div id="warmup-hub-wrap" style="display:none;">
                    <select id="warmup-hub-phone" style="display:none;"></select>
                </div>
                <div>
                    <label class="form-label d-flex align-center gap-1">Генерация текстов
                        <span class="tt" data-tip="Шаблоны — фиксированный набор готовых фраз (бесплатно, без AI-ключа). AI — тексты пишутся нейросетью под тему диалога (требуется настроенный ключ в Настройках → AI). Тратится $ от твоего AI-аккаунта.">
                            <svg class="icon-inline" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
                        </span>
                    </label>
                    <select class="form-control" id="warmup-gen-mode" onchange="onWarmupGenModeChange()">
                        <option value="templates" selected>Шаблоны (бесплатно, без AI)</option>
                        <option value="ai">AI / нейросеть (платный ключ)</option>
                    </select>
                </div>
                <div>
                    <label class="form-label d-flex align-center gap-1">Активные часы
                        <span class="tt" data-tip="Окно когда прогрев разрешён писать сообщения. Внутри окна паузы случайные (60–600 сек), не идёт «лента в одно время». Снаружи окна — тишина, никаких действий. Дефолт 9–22 имитирует активность живого человека.">?</span>
                    </label>
                    <div class="d-flex gap-1 align-center">
                        <input type="number" class="form-control" id="warmup-hours-start" value="9" min="0" max="23" style="width:60px;">
                        <span class="text-muted">—</span>
                        <input type="number" class="form-control" id="warmup-hours-end" value="22" min="0" max="23" style="width:60px;">
                    </div>
                </div>
                <!-- Тихие часы всегда ВКЛ 23-7 без UI (ночная активность — флаг bot-detect). -->
                <input type="hidden" id="warmup-quiet-enabled" value="on" checked>
                <input type="hidden" id="warmup-quiet-start" value="23">
                <input type="hidden" id="warmup-quiet-end" value="7">
                <div>
                    <label class="form-label d-flex align-center gap-1">Задержка между сообщениями (сек)
                        <span class="tt" data-tip="Случайная пауза между сообщениями. Минимум 60с — ниже это уже подозрительно для живого человека. Больше окно = естественнее.">?</span>
                    </label>
                    <div class="d-flex gap-1 align-center">
                        <input type="number" class="form-control w-70px" id="warmup-delay-min" value="120" min="60">
                        <span class="text-muted">—</span>
                        <input type="number" class="form-control w-70px" id="warmup-delay-max" value="300" min="120">
                    </div>
                </div>
                <!-- «Потоки» в основном ряду (warmup-threads). Дубль input type="hidden" удалён — нельзя 2 элемента с одним id. -->

            </div>
            </div>

            <!-- Подсказка о режиме генерации текстов — отдельной строкой под гридом,
                 чтобы не вылазила из ячейки и не перекрывала «Задержка»/«Потоки» внизу.
                 padding+border-top отделяет визуально от грида и от чекбоксов ниже. -->
            <div id="warmup-gen-mode-hint" style="font-size:0.72rem;color:var(--text-muted);line-height:1.55;margin-top:14px;padding:10px 0 14px 0;border-top:1px solid var(--border);min-height:18px;"></div>

            <!-- Свои шаблоны: textarea per-фаза для замены встроенных фраз -->
            <details class="ad-block">
                <summary>
                    <i class="bi bi-chat-square-text"></i> Свои шаблоны прогрева
                    <span class="tt" data-tip="Если стандартные «Привет!», «Здарова», «Ку!» примелькались — впиши свои фразы по одной на строку. Используется только в режиме «Шаблоны». Можно поддерживать варианты через {вариант1|вариант2}.">?</span>
                </summary>
                <div class="ad-body">
                <div style="font-size:0.72rem;color:var(--text-muted);line-height:1.55;margin:0 0 10px 0;">
                    Используются ТОЛЬКО когда выбран режим «Шаблоны». В каждое поле — по одной фразе на строку.
                    Поддерживается варианты в скобках <code style="background:var(--bg-card);padding:1px 4px;border-radius:3px;">{вариант1|вариант2|вариант3}</code> —
                    софт случайно выбирает один из вариантов при отправке.<br>
                    Пример: <code style="background:var(--bg-card);padding:1px 4px;border-radius:3px;">{Привет|Хай|Здарова}, {как дела|чё нового}?</code>
                    превратится в 6 разных фраз.
                </div>
                <div class="d-grid" style="grid-template-columns:1fr;gap:10px;">
                    <div>
                        <label class="form-label" style="font-size:0.74rem;">Приветствия (фаза greeting)</label>
                        <textarea id="warmup-tpl-greetings" class="form-control" rows="4" placeholder="{Привет|Хай|Здарова}!&#10;Йоу, {как сам|чё нового}?&#10;Куку, давно не общались"></textarea>
                    </div>
                    <div>
                        <label class="form-label" style="font-size:0.74rem;">Основные фразы (фаза chatting)</label>
                        <textarea id="warmup-tpl-chatting" class="form-control" rows="5" placeholder="Че там у тебя?&#10;Чем занят {сегодня|вечером}?&#10;{Видел|Смотрел} {новости|погоду}?"></textarea>
                    </div>
                    <div>
                        <label class="form-label" style="font-size:0.74rem;">Прощания (фаза goodbye)</label>
                        <textarea id="warmup-tpl-goodbye" class="form-control" rows="3" placeholder="{Пока|Бай|До связи}!&#10;{Удачи|Береги себя}"></textarea>
                    </div>
                </div>
                <div class="d-flex gap-2 align-center flex-wrap" style="margin-top:10px;">
                    <button class="btn btn-accent btn-sm" onclick="saveWarmupTemplates()">
                        <i class="bi bi-check-lg"></i> Сохранить шаблоны
                    </button>
                    <button class="btn btn-outline btn-sm" onclick="document.getElementById('warmup-tpl-import-file').click()" data-tip="Загрузить шаблоны из .txt файла. Формат: фразы по одной на строку. Можно с тегами [greetings] / [chatting] / [goodbye] чтобы разделить — или загрузить отдельный файл для каждой фазы.">
                        <i class="bi bi-file-arrow-up"></i> Загрузить из .txt
                    </button>
                    <select id="warmup-tpl-import-target" class="form-control" style="width:auto;font-size:0.72rem;padding:4px 8px;">
                        <option value="auto">авто (по [тегам])</option>
                        <option value="greetings">→ Приветствия</option>
                        <option value="chatting">→ Основные фразы</option>
                        <option value="goodbye">→ Прощания</option>
                    </select>
                    <input type="file" id="warmup-tpl-import-file" accept=".txt" style="display:none;" onchange="importWarmupTemplatesFromFile(this)">
                    <button class="btn btn-outline btn-sm" onclick="clearWarmupTemplates()">
                        <i class="bi bi-arrow-counterclockwise"></i> Сбросить
                    </button>
                    <span id="warmup-tpl-status" style="font-size:0.7rem;color:var(--text-muted);margin-left:auto;"></span>
                </div>
                </div>
            </details>

            <!-- Опции чата прогрева (показывается только для chat_flow) -->
            <div id="warmup-chat-opts-wrap" style="display:none;background:var(--bg-card-hover);border:1px solid var(--border);border-radius:4px;padding:8px 12px;margin-bottom:14px;">
                <div class="text-xs text-muted mb-1 fw-600">Опции чата прогрева</div>
                <div class="d-flex gap-4 flex-wrap fs-78">
                    <label class="d-flex align-center gap-2 cursor-pointer">
                        <input type="checkbox" class="form-check-input" id="warmup-id-format">
                        ID-формат (001-01) <span class="tt" data-tip="Каждое сообщение прогрева получает префикс 001-01 (номер акка — номер сообщения в диалоге). Удобно для отладки и поиска проблем в логах, но в чате выглядит ненатурально — для прода лучше отключить.">?</span>
                    </label>
                    <label class="d-flex align-center gap-2 cursor-pointer">
                        <input type="checkbox" class="form-check-input" id="warmup-duplicate-dm" checked>
                        Дубль в ЛС после reply <span class="tt" data-tip="После публичного ответа в общем чате с шансом ~40% акк отправит то же сообщение в ЛС тому же собеседнику. Имитирует реальное поведение: «дублирую, чтобы не потерялось».">?</span>
                    </label>
                </div>
            </div>

            <!-- «Работать до 23:59» и «Ручной запуск следующего дня» удалены.
                 Оставлен только авто-перенос в «В работе» после завершения. -->
            <input type="hidden" id="warmup-until-midnight">
            <input type="hidden" id="warmup-manual-next-day">
            <div class="d-flex align-center gap-4 flex-wrap" style="font-size:0.8rem;margin-top:12px;padding-top:12px;border-top:1px solid var(--border);">
                <label class="d-flex align-center gap-2 cursor-pointer" style="white-space:nowrap;">
                    <input type="checkbox" class="form-check-input" id="warmup-auto-move" checked>
                    Переместить в «В работе» после завершения
                </label>
                <div style="flex:1;"></div>
                <button class="btn btn-accent btn-sm" onclick="saveWarmupConfig()">
                    <i class="bi bi-check"></i> Сохранить
                </button>
            </div>
        </div>
    </div>

    <!-- Сценарии прогрева -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-diagram-3 text-accent"></i> Сценарии прогрева</div>
        <div class="card-body" style="display:flex;flex-direction:column;gap:14px;">
            <div class="info-box">
                Лимиты ниже считаются на каждый аккаунт отдельно, а не на всех вместе.
            </div>

            <!-- DM -->
            <div style="background:var(--bg-card-hover);border:1px solid var(--border);border-radius:5px;padding:10px 14px;">
                <label class="d-flex align-center gap-2 cursor-pointer">
                    <input type="checkbox" class="form-check-input" id="scn-dm" checked>
                    <span style="font-weight:600;font-size:0.78rem;"><i class="bi bi-chat-dots-fill" style="color:var(--text-muted);margin-right:4px;"></i>Переписка между аккаунтами</span>
                </label>
                <p style="margin-top:4px;font-size:0.66rem;color:var(--text-muted);margin-bottom:6px;line-height:1.5;">
                    Аккаунты общаются друг с другом в ЛС как друзья. Это <b>основа прогрева</b> — оставляйте включённым.
                </p>
                <div class="d-flex gap-2 align-center flex-wrap mb-2-x">
                    <label style="font-size:0.66rem;color:var(--text-muted);">Сообщений/день <b>(на акк)</b>:</label>
                    <input type="number" class="form-control" id="scn-dm-msgs-per-day" value="0" min="0" max="200" style="width:65px;font-size:0.72rem;" placeholder="auto">
                    <span class="tt" data-tip="Сколько ЛС-сообщений в день будет отправлять каждый аккаунт другим из пула. 0 = автоматический режим: 4-6 в первые дни, 12-20 к концу прогрева. Поставь число чтобы зафиксировать темп: 5 = очень безопасно, 10 = средне, 20+ = быстро. Учти: если поставить выше — растёт риск спам-блока.">
                        <svg class="icon-inline" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
                    </span>
                </div>
                <label class="d-flex align-center gap-2" style="cursor:pointer;font-size:0.7rem;color:var(--text-secondary);">
                    <input type="checkbox" class="form-check-input" id="scn-reply" checked>
                    Отвечать контекстно на последнее входящее сообщение <span class="tt" data-tip="Акк прочитает последнее входящее от собеседника и AI напишет ответ по смыслу. Без галки — каждое сообщение это новая случайная тема, диалог выглядит как два монолога.">?</span>
                </label>
            </div>

            <!-- Channels -->
            <div style="background:var(--bg-card-hover);border:1px solid var(--border);border-radius:5px;padding:12px 14px;">
                <label class="d-flex align-center gap-2 cursor-pointer">
                    <input type="checkbox" class="form-check-input" id="scn-channels">
                    <span style="font-weight:600;font-size:0.85rem;"><i class="bi bi-megaphone" style="color:var(--accent-light);margin-right:4px;"></i>Подписка на каналы</span>
                </label>
                <p style="margin-top:6px;font-size:0.72rem;color:var(--text-muted);margin-bottom:8px;">
                    Каждый акк подписывается на каналы из списка ниже. Повышает траст — у живого юзера всегда есть подписки. Ниже укажите каналы (по одному юзернейму на строку).
                </p>
                <div class="d-flex gap-2 align-center flex-wrap">
                    <label style="font-size:0.72rem;color:var(--text-muted);">Подписок/день <b>(на акк)</b>: <span class="tt" data-tip="Сколько каналов из списка ниже каждый акк подпишет за день. 1–2 — очень щадяще. 3–5 — норма. 7+ — рискованно для свежих акков (Telegram ловит «вспышки подписок»).">?</span></label>
                    <input type="number" class="form-control" id="scn-channels-per-day" value="3" min="1" max="10" style="width:60px;font-size:0.75rem;">
                    <button class="btn btn-outline btn-sm fs-70" onclick="loadDefaultChannels()">Список по умолчанию</button>
                </div>
                <div class="mt-2" style="background:rgba(99,102,241,0.05);border:1px solid var(--border);border-radius:4px;padding:10px 12px;">
                    <div style="font-size:0.72rem;color:var(--text-muted);margin-bottom:6px;line-height:1.5;">
                        Можно подгрузить свой список каналов по ссылке (обычный текстовый файл со списком, по одной ссылке на строку). У разных клиентов будут разные пулы — так у аккаунтов не будет одинакового набора каналов.
                    </div>
                    <div class="d-flex gap-2 align-center flex-wrap">
                        <input type="text" class="form-control" id="warmup-github-url" placeholder="https://raw.githubusercontent.com/USER/REPO/main/channels.txt" style="flex:1;min-width:280px;font-size:0.72rem;font-family:monospace;">
                        <button class="btn btn-outline btn-sm fs-70" onclick="fetchGithubChannels()">
                            <i class="bi bi-cloud-download"></i> Подгрузить
                        </button>
                        <button class="btn btn-outline btn-sm fs-70" onclick="clearGithubPool()" data-tip="Очистить локальный кеш скачанных каналов">
                            <i class="bi bi-trash"></i>
                        </button>
                    </div>
                    <div id="warmup-github-status" style="margin-top:6px;font-size:0.66rem;color:var(--text-muted);"></div>
                </div>
                <textarea id="scn-channels-list" class="form-control mt-2" rows="4" placeholder="Список каналов (по одному на строку, без @)&#10;Пример:&#10;telegram&#10;tginfo&#10;durov" style="font-size:0.72rem;font-family:monospace;"></textarea>
            </div>

            <!-- Reactions -->
            <div style="background:var(--bg-card-hover);border:1px solid var(--border);border-radius:5px;padding:12px 14px;">
                <label class="d-flex align-center gap-2 cursor-pointer">
                    <input type="checkbox" class="form-check-input" id="scn-reactions">
                    <span style="font-weight:600;font-size:0.85rem;">👍 Реакции в каналах</span>
                </label>
                <p style="margin-top:6px;font-size:0.72rem;color:var(--text-muted);margin-bottom:8px;">
                    Ставит реакции (👍❤️🔥) на последние посты каналов, на которые подписан аккаунт. Работает только вместе со сценарием "Подписка на каналы" — без подписок реагировать не на что.
                </p>
                <div class="d-flex gap-2 align-center">
                    <label style="font-size:0.72rem;color:var(--text-muted);">Реакций/день <b>(на акк)</b>: <span class="tt" data-tip="Сколько реакций (👍❤️🔥) каждый акк поставит за день, размазав по подписанным каналам. За один заход — 1–3 реакции на разные посты.">?</span></label>
                    <input type="number" class="form-control" id="scn-reactions-per-day" value="5" min="1" max="30" style="width:60px;font-size:0.75rem;">
                </div>
            </div>

            <!-- «Свой чат и канал» + Search/Mention/Hub-chat сценарии удалены — опасны для акков.
                 Mass create_group, create_channel, invite-flood и search-join — триггеры заморозок. -->
            <input type="hidden" id="scn-own-chat">
            <input type="hidden" id="scn-diaries">
            <input type="hidden" id="scn-search">
            <input type="hidden" id="scn-mention">
            <input type="hidden" id="scn-hub">
            <input type="hidden" id="scn-hub-phone">
            <input type="hidden" id="scn-hub-channel-id">
            <input type="hidden" id="own-chat-subgroup" value="0">
            <input type="hidden" id="scn-mention-per-day" value="3">
            <textarea id="scn-search-keywords" style="display:none;"></textarea>
            </div><!-- hidden block end -->

            <button class="btn btn-accent btn-sm" onclick="saveScenarios()" style="align-self:flex-start;">
                <i class="bi bi-check"></i> Сохранить сценарии
            </button>
        </div>
    </div>

    <!-- Blacklist -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-shield-exclamation text-danger"></i> Чёрный список слов</div>
        <div class="card-body">
            <textarea class="form-control mb-2" id="warmup-blacklist" rows="5"
                placeholder="Одно слово на строку" style="font-size:0.75rem;"></textarea>
            <button class="btn btn-outline btn-sm" onclick="saveWarmupBlacklist()">
                <i class="bi bi-check"></i> Сохранить
            </button>
        </div>
    </div>

    </details>
    <!-- /расширенные опции -->
            <div class="run-row">
            <div class="d-flex gap-3 align-center flex-wrap">
                <button class="btn btn-accent btn-sm" id="warmup-start-btn" onclick="startWarmup()">
                    <i class="bi bi-play-fill"></i> Запустить
                </button>
                <button class="btn btn-outline btn-sm" id="warmup-pause-btn" onclick="pauseWarmup()" style="display:none;">
                    <i class="bi bi-pause-fill"></i> Пауза
                </button>
                <button class="btn btn-danger btn-sm" id="warmup-stop-btn" onclick="stopWarmup()" style="display:none;">
                    <i class="bi bi-stop-fill"></i> Стоп
                </button>
                <button class="btn btn-accent btn-sm" id="warmup-next-day-btn" onclick="warmupNextDay()" style="display:none;">
                    <i class="bi bi-sunrise"></i> Следующий день
                </button>
            </div>
            </div>
</div>

<!-- TAB «История запусков» удалён. -->

<!-- ═══ TAB: Переавторизация ═══ -->
<div class="section" id="tab-stories">

    <div class="card mb-3" style="border-left:4px solid var(--accent-light); background: rgba(99,102,241,0.07);">
        <div class="card-body" style="padding:12px 16px;">
            <div style="display:flex;align-items:center;gap:8px;margin-bottom:4px;">
                <i class="bi bi-camera-reels" style="color:var(--accent-light);"></i>
                <strong>Истории для прогрева</strong>
            </div>
            <div class="text-hint" style="font-size:0.78rem;line-height:1.5;">
                Аккаунты постят истории (Stories) из папки «Истории» — профиль выглядит живым, это сильный анти-бан сигнал. Видео автоматически приводится к вертикальному формату. Одно медиа уходит максимум на несколько акков (watchdog). Прокси не обязательна, но с ней спокойнее — постинг истории это запись на акк.
            </div>
        </div>
    </div>

    <!-- Аккаунты -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-people text-accent"></i><div class="ch-text"><div class="ch-title">Аккаунты</div><div class="card-sub">постинг историй</div></div></div>
        <div class="card-body">
            <div class="d-flex align-center" style="gap:10px;flex-wrap:wrap;">
                <button class="btn btn-accent btn-sm" onclick="openStoriesMultiPicker()">
                    <i class="bi bi-check2-square"></i> Выбрать аккаунты
                </button>
                <span id="stories-multi-count" class="text-sm" style="color:var(--text-muted);font-weight:700;">0</span>
            </div>
        </div>
    </div>

    <!-- Медиа -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-images text-accent"></i> Медиа для историй</div>
        <div class="card-body">
            <div class="d-flex align-center mb-2" style="gap:10px;flex-wrap:wrap;">
                <label class="btn btn-outline btn-sm" style="margin:0;">
                    <i class="bi bi-upload"></i> Загрузить фото/видео
                    <input type="file" accept="image/*,video/*" multiple style="display:none;"
                           onchange="uploadStoriesMedia(this)">
                </label>
                <button class="btn btn-outline btn-sm" onclick="openStoriesFolder()">
                    <i class="bi bi-folder2-open"></i> Открыть папку
                </button>
                <button class="btn btn-outline btn-sm" onclick="loadStoriesMedia()">
                    <i class="bi bi-arrow-clockwise"></i> Обновить
                </button>
                <span id="stories-media-count" class="text-sm" style="color:var(--text-muted);">медиа: —</span>
            </div>
            <div id="stories-media-list" class="text-sm" style="max-height:160px;overflow:auto;color:var(--text-muted);font-size:0.74rem;"></div>
        </div>
    </div>

    <!-- Параметры -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-sliders text-accent"></i> Параметры</div>
        <div class="card-body">
            <div class="d-flex" style="gap:16px;flex-wrap:wrap;">
                <div>
                    <label class="text-sm" style="display:block;margin-bottom:4px;color:var(--text-muted);">Кто видит</label>
                    <select id="stories-privacy" class="form-control" style="min-width:170px;">
                        <option value="everyone" selected>Все</option>
                        <option value="contacts">Контакты</option>
                        <option value="closeFriends">Близкие друзья</option>
                    </select>
                </div>
                <div>
                    <label class="text-sm" style="display:block;margin-bottom:4px;color:var(--text-muted);">Сколько висит</label>
                    <select id="stories-period" class="form-control" style="min-width:140px;">
                        <option value="21600">6 часов</option>
                        <option value="43200">12 часов</option>
                        <option value="86400" selected>24 часа</option>
                        <option value="172800">48 часов</option>
                    </select>
                </div>
            </div>
            <div class="d-flex" style="gap:16px;flex-wrap:wrap;margin-top:14px;padding-top:12px;border-top:1px solid var(--border);">
                <div>
                    <label class="text-sm" style="display:block;margin-bottom:4px;color:var(--text-muted);">Пауза между аккаунтами, от <span class="tt" data-tip="Сколько программа ждёт между постингом с разных аккаунтов. Пауза каждый раз случайная в этом промежутке — так постинг не выглядит одновременным. По умолчанию 20–60 секунд.">?</span></label>
                    <input type="number" class="form-control w-100px" id="stories-min-delay" value="20" min="1" max="3600">
                </div>
                <div>
                    <label class="text-sm" style="display:block;margin-bottom:4px;color:var(--text-muted);">до (сек)</label>
                    <input type="number" class="form-control w-100px" id="stories-max-delay" value="60" min="1" max="3600">
                </div>
                <div>
                    <label class="text-sm" style="display:block;margin-bottom:4px;color:var(--text-muted);">Одно фото не больше чем на <span class="tt" data-tip="Сколько аккаунтов могут выложить одну и ту же картинку за двое суток. Когда десяток аккаунтов постит одинаковое фото, Telegram видит связку между ними. По умолчанию 3.">?</span></label>
                    <input type="number" class="form-control w-100px" id="stories-watchdog-threshold" value="3" min="1" max="50">
                </div>
            </div>
        </div>
    </div>

    <!-- Управление -->

    <!-- Статус -->
    <div id="stories-status" class="card" style="display:none;">
        <div class="card-header"><i class="bi bi-activity text-accent"></i> Постинг историй</div>
        <div class="card-body">
            <div id="stories-status-summary" class="mb-2 text-sm"></div>
            <div id="stories-status-list" style="max-height:320px;overflow:auto;font-size:0.75rem;"></div>
        </div>
    </div>

            <div class="run-row">
    <div class="d-flex align-center mb-3" style="gap:10px;flex-wrap:wrap;">
        <button id="stories-start-btn" class="btn btn-accent" onclick="startStories()">
            <i class="bi bi-camera-reels"></i> Запостить истории
        </button>
        <button id="stories-stop-btn" class="btn btn-outline" onclick="stopStories()" style="display:none;">
            <i class="bi bi-stop-circle"></i> Стоп
        </button>
    </div>
            </div>
</div>

<div class="section" id="tab-reauth">
    <!-- Карточка 1: Переавторизация -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-arrow-repeat" style="color:#60a5fa;"></i><div class="ch-text"><div class="ch-title">Переавторизация</div><div class="card-sub">повторный вход в аккаунты</div></div></div>
        <div class="card-body">
            <div class="info-box">
                Пересоздаёт сессии аккаунтов с новыми параметрами (устройство, версия, язык). В Telegram они появятся как новые сессии — помогает при ограничениях и подозрениях от Telegram.
            </div>

            <label class="form-label">Выбор аккаунтов</label>
            <div class="d-flex gap-2 align-center mb-2 flex-wrap">
                <button class="btn btn-accent btn-sm" onclick="openReauthAccPicker()" style="font-size:0.78rem;padding:5px 14px;">
                    <i class="bi bi-people"></i> Выбрать аккаунты
                </button>
                <span id="reauth-selected-count" style="color:var(--text-muted);font-weight:700;">0</span>
            </div>
            <div id="reauth-acc-list" class="d-flex flex-wrap gap-1 mb-3 fs-70"></div>

            <label class="form-label">Параметры для аккаунтов</label>
            <div class="d-flex gap-2 align-center mb-2 flex-wrap">
                <select class="form-control" id="reauth-preset" style="max-width:260px;" onchange="reauthPresetChanged()">
                    <option value="custom">Свои параметры</option>
                    <option value="mixed">Встроенные вперемешку</option>
                    <option value="web">Web</option>
                    <option value="tdesktop" selected>Telegram Desktop</option>
                    <option value="android">Android</option>
                </select>
                <!-- Кнопка-дубль «Свои параметры» убрана — дублирует опцию в дропдауне.
                     Поля редактируются через массовый импорт ниже или модалку при выборе «Свои параметры». -->
                <button class="btn btn-outline btn-sm" id="reauth-custom-btn" onclick="openReauthCustomModal()" style="display:none;">
                    <i class="bi bi-list-task"></i> Указать поля
                </button>
            </div>
            <!-- Текстовик — ПУЛ device-вариантов, софт рандомит для каждого акка.
                 Phone не нужен — акки уже выбраны в плитке выше. -->
            <details class="ad-block">
                <summary>
                    <i class="bi bi-file-earmark-text"></i> Пул device-параметров (для разнообразия)
                </summary>
                <div class="ad-body">
                <div style="font-size:0.78rem;color:var(--text-muted);line-height:1.5;">
                    Каждая строка — один вариант. Формат:
                    <code style="background:var(--bg-card);padding:1px 5px;border-radius:3px;">device;system;app_version</code>
                    <br>
                    Софт случайно подберёт строку из этого пула для каждого выбранного акка —
                    так у каждого аккаунта будут свои параметры устройства. Номер указывать не нужно.
                    <br>
                    Если оставить пусто — все акки идут по пресету выше.
                    <br>
                    <span style="opacity:0.7;font-size:0.7rem;">Если строка начинается с phone (10-15 цифр) — это старый mapping-формат, применяется только к указанному акку.</span>
                </div>
                <textarea id="reauth-per-acc-text" class="form-control mt-2" rows="6"
                          placeholder="HP Pavilion 15;Windows 11 x64;6.4.4 x64&#10;Dell XPS 13;Windows 10 x64;6.4.2 x64&#10;Lenovo ThinkPad T14;Windows 11 x64;6.4.3 x64&#10;ASUS ROG Strix;Windows 11 x64;6.4.4 x64"
                          style="font-family:monospace;font-size:0.72rem;"></textarea>
                <div id="reauth-per-acc-info" style="margin-top:6px;font-size:0.7rem;color:var(--text-muted);"></div>
                </div>
            </details>

            <label class="form-label">Новая 2FA <span class="text-xs text-muted">(опционально)</span></label>
            <input type="text" class="form-control mb-3" id="reauth-new-2fa" placeholder="Оставьте пусто чтобы не менять">

            <details class="ad-block" open>
                <summary><i class="bi bi-gear"></i> Дополнительные опции</summary>
                <div class="ad-body" style="display:flex;flex-direction:column;gap:8px;font-size:0.8rem;">
                    <label class="d-flex align-center gap-2 cursor-pointer">
                        <input type="checkbox" class="form-check-input" id="reauth-close-others">
                        Закрывать старые сессии <span class="tt" data-tip="Выключено по умолчанию. Свежий вход, который тут же закрывает все остальные сессии аккаунта, Telegram читает как перехват — и закрывает сессии сам, вместе с только что созданной. Включайте, только если аккаунт заведомо ваш и старые входы нужно убрать осознанно.">?</span>
                    </label>
                    <label class="d-flex align-center gap-2 cursor-pointer">
                        <input type="checkbox" class="form-check-input" id="reauth-delete-dialog" checked>
                        Удалять диалог с Telegram после переавторизации
                    </label>
                    <label class="d-flex align-center gap-2 cursor-pointer">
                        <input type="checkbox" class="form-check-input" id="reauth-continue-limit">
                        Продолжать даже если сессия моложе 24ч (пропустить закрытие)
                    </label>
                    <label class="d-flex align-center gap-2 cursor-pointer">
                        <input type="checkbox" class="form-check-input" id="reauth-keep-original" checked>
                        Сохранить оригинал (новый файл в папке Переавторизованные/)
                    </label>
                </div>
            </details>

            <div id="reauth-progress" style="display:none;" class="mb-2">
                <div class="d-flex align-center justify-between mb-1">
                    <span class="text-sm" id="reauth-progress-text">0/0</span>
                    <span class="text-xs text-muted" id="reauth-stats"></span>
                </div>
                <div class="progress" style="height:6px;"><div class="progress-bar" id="reauth-progress-bar" style="width:0%;background:linear-gradient(90deg,#60a5fa,#a78bfa);"></div></div>
            </div>
            <textarea id="reauth-log" class="form-control task-log" rows="10" readonly style="display:none;"></textarea>

        </div>
    </div>
    <div class="run-row">
    <div class="d-flex gap-2 mb-2">
        <button class="btn btn-accent btn-sm" onclick="startReauth()" id="btn-reauth-start">
            <i class="bi bi-play-fill"></i> Запустить
        </button>
        <button class="btn btn-danger btn-sm" onclick="stopReauth()" id="btn-reauth-stop" style="display:none;">
            <i class="bi bi-stop-fill"></i> Стоп
        </button>
    </div>
    </div>
</div>

<!-- ═══ TAB: Конвертер tdata → session ═══ -->
<div class="section" id="tab-conv-t2s">
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-file-earmark-arrow-down text-success"></i><div class="ch-text"><div class="ch-title">Конвертер tdata → session</div><div class="card-sub">конвертация tdata в session</div></div></div>
        <div class="card-body">
            <div style="background:var(--surface-success-bg);border:1px solid var(--surface-success-border);border-radius:5px;padding:10px 14px;margin-bottom:12px;font-size:0.72rem;color:var(--text-muted);line-height:1.6;">
                Положите папки tdata в указанную директорию. Каждая папка должна содержать каталог <code>D877F783D5D3EF8C</code>. Результат — .session + .json в папке "В работе".
            </div>
            <!-- Предупреждение про закрытие входа: без галки оба входа делят один ключ. -->
            <div style="background:linear-gradient(135deg,#3b1c0a,#2a1410);border:1px solid #f97316;border-radius:5px;padding:10px 14px;margin-bottom:12px;font-size:0.78rem;line-height:1.5;color:#fed7aa;">
                <div style="font-weight:700;color:#fdba74;margin-bottom:4px;">
                    <i class="bi bi-exclamation-triangle-fill"></i> Не оставляй tdata открытой в Telegram Desktop пока будешь работать в TelePush
                </div>
                По умолчанию (с галкой <b>«Создать новую сессию»</b>) .session получит свой ключ — можно работать параллельно с tdata в Desktop.
                Без галки .session и tdata будут использовать <b>один</b> ключ: если запустишь .session в TelePush с другого IP пока tdata активна в Desktop — Telegram отзовёт обе.
            </div>

            <div class="rd-group"><div class="rd-group-title">ИСТОЧНИК</div>
            <label class="form-label">Путь к папке с tdata <span class="text-xs text-muted">(если пусто — берётся <code>Аккаунты/Конвертер tdata → session/</code>)</span></label>
            <input type="text" class="form-control mb-3" id="reauth-t2s-folder" placeholder="оставьте пусто чтобы использовать папку по умолчанию">
            </div>

            <div class="rd-group"><div class="rd-group-title">ОПЦИИ</div>
            <div class="d-flex gap-3 flex-wrap mb-3">
                <div>
                    <label class="form-label fs-72">Количество потоков</label>
                    <input type="number" class="form-control" id="reauth-t2s-threads" value="5" min="1" max="30" style="width:80px;font-size:0.8rem;">
                </div>
                <label class="d-flex align-center gap-2" style="cursor:pointer;font-size:0.8rem;align-self:flex-end;margin-bottom:6px;">
                    <input type="checkbox" class="form-check-input" id="reauth-t2s-keep">
                    Не убирать сконвертированные аккаунты
                </label>
                <label class="d-flex align-center gap-2" style="cursor:pointer;font-size:0.8rem;align-self:flex-end;margin-bottom:6px;">
                    <input type="checkbox" class="form-check-input" id="reauth-t2s-new-session" checked>
                    Создать новую сессию в .session <span class="tt" data-tip="Включено по умолчанию: файл аккаунта получит собственный вход. Папка Telegram Desktop останется рабочей — можно параллельно открыть её в Telegram Desktop, входы не конфликтуют. Минусы: в 5–10 раз медленнее, и в списке устройств аккаунта появится ещё один Telegram Desktop. ВЫКЛЮЧИ только если хочешь чтобы .session использовала ТОТ ЖЕ ключ что в tdata — но тогда не открывай tdata в Desktop пока работаешь с .session в TelePush.">?</span>
                </label>
            </div>

            <details class="ad-block">
                <summary><i class="bi bi-gear"></i> Дополнительные опции</summary>
                <div class="ad-body" style="display:flex;flex-direction:column;gap:8px;font-size:0.8rem;">
                    <div>
                        <label class="form-label fs-72">Название файла с 2FA</label>
                        <input type="text" class="form-control" id="reauth-t2s-pwd" value="Password2FA.txt" style="font-size:0.8rem;">
                    </div>
                    <div>
                        <label class="form-label fs-72">Глубина поиска папок</label>
                        <input type="number" class="form-control" id="reauth-t2s-depth" value="4" min="1" max="10" style="font-size:0.8rem;width:80px;">
                    </div>
                </div>
            </details>
            </div>

        </div>
    </div>
            <div class="run-row">
            <button class="btn btn-accent btn-sm" onclick="runTdataToSession()">
                <i class="bi bi-rocket-takeoff"></i> Запустить
            </button>
            <div id="t2s-progress" class="mt-2" style="display:none;">
                <div class="d-flex align-center justify-between mb-1">
                    <span class="text-sm" id="t2s-progress-text">0/0</span>
                    <span class="text-xs text-muted" id="t2s-stats"></span>
                </div>
                <div class="progress" style="height:6px;"><div id="t2s-progress-bar" style="width:0%;background:linear-gradient(90deg,#22c55e,#4ade80);height:100%;border-radius:3px;transition:width .3s;"></div></div>
            </div>
            <textarea id="t2s-log" class="form-control task-log" rows="12" readonly style="display:none;"></textarea>
            </div>
</div>

<!-- ═══ TAB: Конвертер session → tdata ═══ -->
<div class="section" id="tab-conv-s2t">
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-file-earmark-arrow-up text-warning"></i><div class="ch-text"><div class="ch-title">Конвертер session → tdata</div><div class="card-sub">конвертация session в tdata</div></div></div>
        <div class="card-body">
            <div class="info-box info-box--warning">
                Выберите аккаунты и сконвертируйте их в tdata-папки для использования в Telegram Desktop. Результат — в <code>data/tdata_out/</code>.
            </div>
            <!-- Видимое предупреждение про закрытие входа: открыть tdata в Desktop пока акк работает в TelePush
                 → обе сессии получают AuthKeyDuplicated → акк слетает. -->
            <div style="background:linear-gradient(135deg,#3b1c0a,#2a1410);border:1px solid #f97316;border-radius:5px;padding:10px 14px;margin-bottom:12px;font-size:0.78rem;line-height:1.5;color:#fed7aa;">
                <div style="font-weight:700;color:#fdba74;margin-bottom:4px;">
                    <i class="bi bi-exclamation-triangle-fill"></i> Не открывай tdata в Telegram Desktop пока этот же акк работает в TelePush
                </div>
                Без галки <b>«Создать новый вход»</b> оба входа — и в программе, и в Telegram Desktop — общие.
                Если открыть tdata в Desktop с другого IP — Telegram увидит «session_stolen» и отзовёт <b>обе</b> сессии: акк слетит и здесь, и там.
                Хочешь использовать акк в Desktop параллельно — включи галку ниже («Создать новый вход для Telegram Desktop»).
                <div style="margin-top:6px;color:#fcd34d;">
                    ⚠️ <b>Даже с новой сессией</b>: открытие в Desktop = новый вход с твоего IP. Для <b>свежих</b> акков (только что зарегистрированы / меняли профиль) вход из Desktop с <b>другого IP/страны</b> = триггер антифрода Telegram → может слететь. Открывай <b>с того же прокси/IP</b>, на котором акк грелся, и не сразу после правок профиля.
                </div>
            </div>

            <div class="rd-group"><div class="rd-group-title">АККАУНТЫ</div>
            <div class="d-flex gap-2 align-center mb-2 flex-wrap">
                <button class="btn btn-accent btn-sm" onclick="openReauthAccPicker('s2t')" style="font-size:0.78rem;padding:5px 14px;">
                    <i class="bi bi-people"></i> Выбрать аккаунты
                </button>
                <span id="s2t-selected-count" style="color:var(--text-muted);font-weight:700;">0</span>
            </div>
            <div id="s2t-acc-list" class="d-flex flex-wrap gap-1 mb-3 fs-70"></div>
            </div>

            <div class="rd-group"><div class="rd-group-title">ПАРАМЕТРЫ</div>
            <div class="d-flex gap-3 flex-wrap mb-3" style="align-items:flex-end;">
                <div>
                    <label class="form-label fs-72">Аккаунтов в одну tdata</label>
                    <input type="number" class="form-control" id="s2t-pack" value="1" min="1" max="10" style="width:80px;font-size:0.8rem;">
                </div>
                <div>
                    <label class="form-label fs-72">Количество потоков</label>
                    <input type="number" class="form-control" id="s2t-threads" value="5" min="1" max="30" style="width:80px;font-size:0.8rem;">
                </div>
                <label class="d-flex align-center gap-2" style="cursor:pointer;font-size:0.8rem;margin-bottom:6px;">
                    <input type="checkbox" class="form-check-input" id="s2t-offline">
                    Оффлайн-конвертация
                </label>
            </div>
            </div>

            <details class="ad-block">
                <summary><i class="bi bi-gear"></i> Дополнительные опции</summary>
                <div class="ad-body" style="display:flex;flex-direction:column;gap:8px;font-size:0.8rem;">
                    <label class="d-flex align-center gap-2 cursor-pointer">
                        <input type="checkbox" class="form-check-input" id="s2t-save-2fa" checked>
                        Сохранять 2FA в файл
                    </label>
                    <label class="d-flex align-center gap-2 cursor-pointer">
                        <input type="checkbox" class="form-check-input" id="s2t-copy-orig" checked>
                        Копировать оригинал аккаунта в папку tdata
                    </label>
                    <label class="d-flex align-center gap-2 cursor-pointer">
                        <input type="checkbox" class="form-check-input" id="s2t-new-session">
                        Сделать для Desktop отдельный вход <span class="tt" data-tip="Выключено по умолчанию: в tdata уходит ТА ЖЕ сессия, что и была — это перенос аккаунта в Telegram Desktop, а не второй вход рядом. Пара файлов после конверта уезжает в папку «Конвертер session → tdata» и в задачах больше не участвует, поэтому входы не пересекаются. Включайте, только если аккаунт должен остаться работать в TelePush: тогда для Desktop создаётся ОТДЕЛЬНЫЙ вход. Он в 5–10 раз медленнее, появляется в списке устройств аккаунта как новое устройство, первые сутки ограничен Telegram и требует онлайн-режима.">?</span>
                    </label>
                    <label class="d-flex align-center gap-2 cursor-pointer">
                        <input type="checkbox" class="form-check-input" id="s2t-move-to-archive" checked>
                        После конверта убрать акк из работы (в папку «Конвертер session → tdata») <span class="tt" data-tip="Включено по умолчанию. После удачной конвертации файлы аккаунта переезжают в папку «Конвертер session → tdata/. TelePush больше не задействует акк ни в одной задаче (рассылка/подписка/прогрев) — входы не пересекутся с вашим Telegram Desktop. Хочешь вернуть в работу — перемести файлы обратно в «В работе» вручную.">?</span>
                    </label>
                </div>
            </details>

        </div>
    </div>
            <div class="run-row">
            <button class="btn btn-accent btn-sm" onclick="runSessionToTdata()">
                <i class="bi bi-rocket-takeoff"></i> Запустить
            </button>
            <div id="s2t-progress" class="mt-2" style="display:none;">
                <div class="d-flex align-center justify-between mb-1">
                    <span class="text-sm" id="s2t-progress-text">0/0</span>
                    <span class="text-xs text-muted" id="s2t-stats"></span>
                </div>
                <div class="progress" style="height:6px;"><div id="s2t-progress-bar" style="width:0%;background:linear-gradient(90deg,#f59e0b,#fbbf24);height:100%;border-radius:3px;transition:width .3s;"></div></div>
            </div>
            <textarea id="s2t-log" class="form-control task-log" rows="12" readonly style="display:none;"></textarea>
            </div>
</div>

<!-- Модалка: Свои параметры -->
<div id="reauth-custom-modal" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,0.7);z-index:500;align-items:center;justify-content:center;">
    <div style="background:var(--bg-card-hover);border:1px solid var(--border);border-radius:7px;padding:22px;max-width:440px;width:90%;max-height:85vh;overflow-y:auto;">
        <h3 style="color:#fff;font-size:1.1rem;margin-bottom:14px;">Свои параметры</h3>
        <div style="display:flex;flex-direction:column;gap:10px;font-size:0.8rem;">
            <div><label class="form-label">API ID</label><input type="number" class="form-control" id="cp-api-id"></div>
            <div><label class="form-label">API Hash</label><input type="text" class="form-control" id="cp-api-hash"></div>
            <div><label class="form-label">Device Model</label><input type="text" class="form-control" id="cp-device" placeholder="напр. Aspire 5 / MS-7C75"></div>
            <div><label class="form-label">System Version</label><input type="text" class="form-control" id="cp-sysver" placeholder="Windows 10"></div>
            <div><label class="form-label">App Version</label><input type="text" class="form-control" id="cp-appver" placeholder="6.2.2 x64"></div>
            <div class="d-flex gap-2">
                <div class="flex-1" ><label class="form-label">Lang Code</label><input type="text" class="form-control" id="cp-lang" value="en"></div>
                <div class="flex-1" ><label class="form-label">System Lang</label><input type="text" class="form-control" id="cp-syslang" value="en-US"></div>
            </div>
        </div>
        <div class="d-flex gap-2 mt-3">
            <button class="btn btn-accent btn-sm" onclick="saveReauthCustomPreset()">Сохранить</button>
            <button class="btn btn-outline btn-sm" onclick="document.getElementById('reauth-custom-modal').style.display='none';">Отмена</button>
        </div>
    </div>
</div>

<!-- ═══ TAB: Настройки ═══ -->
<div class="section" id="tab-settings">
    <!-- Поиск по настройкам. Sticky убран (перекрывал контент) — скроллится вместе с табом. -->
    <div class="card mb-3">
        <div class="card-body" style="padding:10px;">
            <div style="position:relative;">
                <i class="bi bi-search" style="position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--text-muted);font-size:0.85rem;"></i>
                <input type="text" id="settings-search" class="form-control" placeholder="Поиск по настройкам (прокси, прогрев, AI, лицензия...)" style="padding-left:34px;" oninput="filterSettings(this.value)">
                <span id="settings-search-clear" onclick="document.getElementById('settings-search').value='';filterSettings('');" style="display:none;position:absolute;right:10px;top:50%;transform:translateY(-50%);color:var(--text-muted);cursor:pointer;font-size:0.9rem;"><i class="bi bi-x-circle"></i></span>
            </div>
            <div id="settings-search-empty" style="display:none;margin-top:8px;font-size:0.78rem;color:var(--text-muted);text-align:center;">Ничего не найдено</div>
        </div>
    </div>

    <!-- Звуковые уведомления (opt-in) -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-volume-up-fill" style="color:#fbbf24;"></i><div class="ch-text"><div class="ch-title">Звуковые уведомления</div><div class="card-sub">параметры приложения</div></div></div>
        <div class="card-body">
            <div class="info-box note-row" style="margin-bottom:10px;">
                Короткий beep на важные события. По умолчанию выключены. Можно отойти от компа и слышать когда что-то случилось.
            </div>
            <label class="ad-check" style="display:block;margin-bottom:6px;"><input type="checkbox" id="sound-freeze" onchange="tpSetSound('freeze', this.checked)"> <span>Заморозка аккаунта<span class="ad-hint">Глухой низкий beep при появлении нового frozen-акка</span></span></label>
            <label class="ad-check" style="display:block;margin-bottom:6px;"><input type="checkbox" id="sound-done" onchange="tpSetSound('done', this.checked)"> <span>Завершение задачи (рассылка/прогрев/инвайт)<span class="ad-hint">Два восходящих тона когда задача закончилась</span></span></label>
            <label class="ad-check" style="display:block;margin-bottom:10px;"><input type="checkbox" id="sound-error" onchange="tpSetSound('error', this.checked)"> <span>Критическая ошибка<span class="ad-hint">Сигнал-падение когда показывается error-тост</span></span></label>
            <div style="display:flex;gap:12px;align-items:center;margin-top:8px;">
                <label class="form-label" style="margin:0;">Громкость:</label>
                <input type="range" id="sound-volume" min="0" max="100" value="50" style="width:160px;" oninput="tpSetSoundVolume(this.value/100);document.getElementById('sound-volume-val').textContent=this.value+'%'">
                <span id="sound-volume-val" style="font-size:0.75rem;color:var(--text-muted);">50%</span>
                <button class="btn btn-outline btn-sm" onclick="tpTestSound('done')" style="margin-left:auto;"><i class="bi bi-play-fill"></i> Проверить</button>
            </div>
            <script>
                // Восстанавливаем чекбоксы из localStorage при загрузке настроек
                (function() {
                    var bindRestore = function() {
                        ['freeze','done','error'].forEach(function(k) {
                            var cb = document.getElementById('sound-' + k);
                            if (cb) cb.checked = (localStorage.getItem('tp_sound_' + k) === '1');
                        });
                        var vol = parseFloat(localStorage.getItem('tp_sound_volume') || '0.5');
                        var v = document.getElementById('sound-volume');
                        var vv = document.getElementById('sound-volume-val');
                        if (v) v.value = Math.round(vol * 100);
                        if (vv) vv.textContent = Math.round(vol * 100) + '%';
                    };
                    if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', bindRestore);
                    else bindRestore();
                })();
            </script>
        </div>
    </div>

    <!-- Информация о путях софта -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-folder2-open text-info"></i> Где софт хранит данные</div>
        <div class="card-body">
            <div class="info-box note-row" style="margin-bottom:10px;">
                TelePush держит файлы вне папки с exe — чтобы автообновление не сносило сессии и настройки. Если нужно стереть всё дочиста — кнопка ниже.
            </div>
            <div id="paths-info-rows" style="font-size:0.78rem;color:var(--text-muted);">Загрузка…</div>
            <div style="margin-top:12px;display:flex;gap:8px;flex-wrap:wrap;">
                <button class="btn btn-outline btn-sm" onclick="openPathFolder('accounts')"><i class="bi bi-folder2-open"></i> Аккаунты</button>
                <button class="btn btn-outline btn-sm" onclick="openPathFolder('data')"><i class="bi bi-database"></i> data</button>
                <button class="btn btn-outline btn-sm" onclick="openPathFolder('backup')"><i class="bi bi-shield"></i> ~/.telepush</button>
                <button class="btn btn-danger btn-sm" onclick="factoryReset()" style="margin-left:auto;">
                    <i class="bi bi-trash"></i> Стереть всё (полный сброс)
                </button>
            </div>
        </div>
    </div>

    <!-- AI помощник — выбор провайдера + ключ -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-stars" style="color:#a855f7;"></i> AI помощник (чат в углу экрана)</div>
        <div class="card-body">
            <div class="info-box note-row" style="margin-bottom:10px;">
                Выбери AI-провайдера и вставь свой ключ. Помощник будет знать твои аккаунты и активные задачи, советовать настройки, объяснять пауза от Telegram. Запросы идут напрямую от твоего ПК к AI-провайдеру, через наш сервер не проходят.
            </div>
            <div class="row-flex gap-3" style="flex-wrap:wrap;">
                <div style="flex:1;min-width:200px;">
                    <label class="form-label">Провайдер</label>
                    <select id="tphelper-ai-provider" class="form-control" onchange="onTphelperAiProviderChange()">
                        <option value="deepseek">DeepSeek (дёшево)</option>
                        <option value="openai">OpenAI (GPT)</option>
                        <option value="anthropic">Anthropic Claude</option>
                        <option value="gemini">Google Gemini (есть бесплатный лимит)</option>
                    </select>
                </div>
                <div style="flex:2;min-width:240px;">
                    <label class="form-label">API ключ</label>
                    <input type="password" id="tphelper-ai-key" class="form-control" placeholder="sk-... / AIza... / sk-ant-...">
                </div>
                <div style="flex:1;min-width:200px;">
                    <label class="form-label">Модель <span style="font-size:0.7rem;color:var(--text-muted);">(опц.)</span></label>
                    <input type="text" id="tphelper-ai-model" class="form-control" placeholder="по умолчанию">
                </div>
            </div>
            <div style="margin-top:8px;font-size:0.72rem;color:var(--text-muted);" id="tphelper-ai-key-hint"></div>
            <div style="margin-top:10px;display:flex;gap:8px;align-items:center;">
                <button class="btn btn-accent btn-sm" onclick="saveTphelperAiSettings()"><i class="bi bi-check"></i> Сохранить</button>
                <button class="btn btn-outline btn-sm" onclick="testTphelperAiSettings()"><i class="bi bi-play"></i> Проверить</button>
                <span id="tphelper-ai-key-status" style="font-size:0.75rem;color:var(--text-muted);"></span>
            </div>
        </div>
    </div>

    <!-- Глобальная защита аккаунтов -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-shield-check text-success"></i> Глобальная защита аккаунтов</div>
        <div class="card-body">
            <div class="info-box note-row">
                Эти настройки действуют во всех модулях по умолчанию. В каждом модуле можно переопределить отдельно (раскрывашка «Защита аккаунта»).
            </div>
            <label class="ad-check"><input type="checkbox" id="global-pre-spam-check" onchange="saveGlobalAdSettings()"> <span>Перед стартом любой задачи проверять аккаунты на спам-блок<span class="ad-hint">Один проход через @SpamBot — заблокированные пропустятся, чисто-живые пойдут в работу</span></span></label>
        </div>
    </div>

    <!-- «Расписание работы» удалено. Задачи стартуют по запуску, без часовых ограничений. -->

    <!-- TG-бот уведомления -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-telegram" style="color:#5db7ff;"></i> Уведомления через Telegram-бот</div>
        <div class="card-body">
            <div class="info-box note-row">
                Создай бота через @BotFather, получи токен. Затем напиши боту /start и укажите свой ID (узнать через @userinfobot).
                Софт будет слать тебе алерты в Telegram — даже если программа не открыта.
            </div>
            <div class="grid-2 mb-2">
                <div>
                    <label class="form-label">ключ бота</label>
                    <input type="text" class="form-control" id="tg-bot-token" placeholder="123456:AAH...xyz">
                </div>
                <div>
                    <label class="form-label">Твой Chat ID</label>
                    <input type="text" class="form-control" id="tg-bot-chat-id" placeholder="123456789">
                </div>
            </div>
            <label class="ad-check"><input type="checkbox" id="tg-notify-spamblock"> <span>Уведомлять когда аккаунт ушёл в спам-блок</span></label>
            <label class="ad-check"><input type="checkbox" id="tg-notify-task-done"> <span>Уведомлять когда задача завершена</span></label>
            <label class="ad-check"><input type="checkbox" id="tg-notify-error"> <span>Уведомлять при критических ошибках</span></label>
            <div class="d-flex gap-2 mt-2 mt-8">
                <button class="btn btn-accent btn-sm" onclick="saveTgBot()"><i class="bi bi-save"></i> Сохранить</button>
                <button class="btn btn-outline btn-sm" onclick="testTgBot()"><i class="bi bi-send"></i> Тест-сообщение</button>
                <span id="tg-bot-status" class="text-xs text-muted" style="margin-left:auto;align-self:center;"></span>
            </div>
        </div>
    </div>

    <!-- Управление софтом из бота -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-sliders" style="color:#5db7ff;"></i> Управление через бота</div>
        <div class="card-body">
            <div class="info-box note-row">
                Тот же бот, что шлёт уведомления, сможет запускать и останавливать работу прямо из переписки.
                Отметь, что ему разрешено — остальное он делать не будет. Кто имеет доступ к этому чату,
                тот управляет твоими аккаунтами, поэтому по умолчанию всё выключено.
            </div>
            <label class="ad-check"><input type="checkbox" id="bot-control-enabled" onchange="renderBotControl()"> <span>Разрешить управление софтом из бота</span></label>
            <div id="bot-control-modules" class="mt-2" style="padding-left:18px;"></div>
            <div class="d-flex gap-2 mt-2 mt-8">
                <button class="btn btn-accent btn-sm" onclick="saveBotControl()"><i class="bi bi-save"></i> Сохранить</button>
                <span id="bot-control-status" class="text-xs text-muted" style="margin-left:auto;align-self:center;"></span>
            </div>
        </div>
    </div>

    <!-- Внешний вид: переключатель тем -->
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-palette" style="color:#5db7ff;"></i> Внешний вид</div>
        <div class="card-body">
            <div class="info-box" style="margin-bottom:12px;font-size:0.72rem;">
                Тема меняется мгновенно, без перезапуска. Выбор сохраняется между запусками.
            </div>
            <div class="theme-picker" id="theme-picker">
                <button type="button" class="theme-card" data-theme="calm" onclick="selectTheme('calm')">
                    <div class="theme-card__preview theme-preview-calm">
                        <span class="tp-line tp-line-bg"></span>
                        <span class="tp-line tp-line-card"></span>
                        <span class="tp-line tp-line-card2"></span>
                        <span class="tp-line tp-line-accent"></span>
                    </div>
                    <div class="theme-card__name">Спокойная</div>
                    <div class="theme-card__desc">Тёмно-синяя, текущая</div>
                </button>
                <button type="button" class="theme-card" data-theme="amoled" onclick="selectTheme('amoled')">
                    <div class="theme-card__preview theme-preview-amoled">
                        <span class="tp-line tp-line-bg"></span>
                        <span class="tp-line tp-line-card"></span>
                        <span class="tp-line tp-line-card2"></span>
                        <span class="tp-line tp-line-accent"></span>
                    </div>
                    <div class="theme-card__name">AMOLED</div>
                    <div class="theme-card__desc">Чёрный для OLED</div>
                </button>
                <button type="button" class="theme-card" data-theme="light" onclick="selectTheme('light')">
                    <div class="theme-card__preview theme-preview-light">
                        <span class="tp-line tp-line-bg"></span>
                        <span class="tp-line tp-line-card"></span>
                        <span class="tp-line tp-line-card2"></span>
                        <span class="tp-line tp-line-accent"></span>
                    </div>
                    <div class="theme-card__name">Светлая</div>
                    <div class="theme-card__desc">Белая, для дневного</div>
                </button>
            </div>
        </div>
    </div>

    <!-- AI / нейродиалоги -->
    <div class="card mb-3">
        <div class="card-header cursor-pointer" onclick="toggleSettingsSection('settings-ai')">
            <i class="bi bi-cpu text-purple"></i> <b>AI / нейродиалоги</b>
            <span id="ai-status-badge" class="badge-soft badge-soft--muted" style="margin-left:8px;font-size:0.62rem;">не настроено</span>
            <i class="bi bi-chevron-down text-muted" style="margin-left:auto;font-size:0.7rem;" id="chev-settings-ai"></i>
        </div>
        <div class="card-body" id="settings-ai" style="display:none;">

            <div class="info-box info-box--accent" style="margin-bottom:12px;font-size:0.7rem;line-height:1.55;">
                <b>Зачем:</b> с AI прогрев и комменты звучат как живые люди — не повторяющиеся шаблоны, а контекстные ответы по теме.<br>
                <b>Кто платит:</b> ты сам, своему провайдеру AI (OpenAI / OpenRouter / DeepSeek и т.п.). TelePush только выступает клиентом твоего ключа — мы не видим запросов.<br>
                <b>Стоимость:</b> зависит от модели. DeepSeek через OpenRouter ~$0.0002 за диалог (5 диалогов на акк × 30 акков × 30 дней ≈ <b>$0.9 за весь месяц прогрева</b>). GPT-4o-mini ~$0.001 за диалог (~$5/мес).
            </div>

            <div class="grid-2 mb-2">
                <div>
                    <label class="form-label">Провайдер</label>
                    <select class="form-control" id="ai-provider" onchange="onAiProviderChange()"></select>
                </div>
                <div>
                    <label class="form-label">Модель</label>
                    <select class="form-control" id="ai-model"></select>
                </div>
            </div>

            <div class="mb-2" id="ai-url-row" style="display:none;">
                <label class="form-label">Адрес, куда слать</label>
                <input type="text" class="form-control" id="ai-url" placeholder="https://api.example.com/v1">
            </div>

            <div class="mb-2">
                <label class="form-label">API ключ <span id="ai-has-key-badge" style="display:none;font-size:0.65rem;color:var(--success);margin-left:6px;">✓ сохранён</span></label>
                <div class="d-flex gap-2 align-center">
                    <input type="password" class="form-control" id="ai-key" placeholder="sk-... (вставь сюда)" style="font-family:monospace;font-size:0.75rem;flex:1;">
                    <button class="btn btn-outline btn-sm" onclick="aiTest()" id="btn-ai-test"><i class="bi bi-lightning-charge"></i> Тест</button>
                </div>
                <div id="ai-test-result" style="margin-top:6px;font-size:0.7rem;"></div>
                <div id="ai-signup-hint" style="margin-top:6px;font-size:0.68rem;color:var(--text-muted);line-height:1.5;"></div>
            </div>

            <div class="grid-2 mb-2">
                <div>
                    <label class="form-label">Дневной бюджет, $ <span class="tt" data-tip="Максимум потратишь в день. Когда лимит достигнут — AI отключается до следующего дня (fallback на шаблоны). 0 = без лимита (опасно если введёшь дорогой ключ).">
                        <svg class="icon-inline" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
                    </span></label>
                    <input type="number" class="form-control" id="ai-budget-usd" value="5" min="0" max="1000" step="0.5" style="width:120px;">
                </div>
                <div>
                    <label class="form-label">Запросов в день <span class="tt" data-tip="Максимум HTTP-запросов к AI в сутки. 0 = без лимита.">
                        <svg class="icon-inline" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
                    </span></label>
                    <input type="number" class="form-control" id="ai-budget-req" value="0" min="0" step="100" placeholder="без лимита" style="width:140px;">
                </div>
            </div>

            <details class="ad-block" open>
                <summary>
                    <i class="bi bi-chat-quote"></i> Промпты для AI — пиши свой текст здесь
                </summary>
                <div class="ad-body">
                    <div style="font-size:0.7rem;color:var(--text-muted);margin-bottom:8px;line-height:1.5;">
                        Это поля для своих AI-промтов. Работают ТОЛЬКО когда выше включена галка «Включить AI» и указан AI-ключ. В промпте можно использовать <code>{persona}</code> и <code>{topic}</code> — подставляются автоматически. Если поле пустое — берётся стандартный промпт.
                    </div>
                    <label class="form-label">Темы для нейродиалогов <span style="color:var(--text-muted);font-weight:normal;font-size:0.65rem;">(каждая с новой строки — софт случайно выбирает на пару)</span></label>
                    <textarea class="form-control mb-2 fs-72" id="ai-dialog-topics" rows="4" placeholder="работа&#10;выходные&#10;фильмы&#10;еда&#10;спорт"></textarea>

                    <label class="form-label">Свой системный промпт для диалогов <span style="color:var(--text-muted);font-weight:normal;font-size:0.65rem;">(если пусто — стандартный)</span></label>
                    <textarea class="form-control mb-2" id="ai-custom-dialog-prompt" rows="5" placeholder="Используется {persona} и {topic} — подставляются автоматически." style="font-size:0.72rem;font-family:monospace;"></textarea>

                    <label class="form-label">Свой системный промпт для комментов</label>
                    <textarea class="form-control mb-2" id="ai-custom-comment-prompt" rows="5" placeholder="Используется {persona} и {cta_block}. Если пусто — стандартный." style="font-size:0.72rem;font-family:monospace;"></textarea>

                    <label class="form-label">Своя приписка в комментарии <span style="color:var(--text-muted);font-weight:normal;font-size:0.65rem;">(куда вести, если комментарий органично подходит)</span></label>
                    <input type="text" class="form-control mb-2" id="ai-comment-cta" placeholder="Например: 'упоминай канал @mychannel' или пусто — без рекламы">
                </div>
            </details>

            <div class="d-flex gap-2 align-center mt-2 flex-wrap">
                <label class="d-flex align-center gap-2" style="cursor:pointer;font-size:0.78rem;">
                    <input type="checkbox" class="form-check-input" id="ai-enabled">
                    <b>Включить AI</b> (без галки — софт работает только на шаблонах)
                </label>
                <label class="d-flex align-center gap-2" style="cursor:pointer;font-size:0.72rem;color:var(--text-muted);" data-tip="При ошибке провайдера (5xx/таймаут) попробовать запрос ещё раз через 2 сек. По умолчанию OFF — на ошибке софт сразу падает на шаблоны.">
                    <input type="checkbox" class="form-check-input" id="ai-retry-on-error">
                    Повторить запрос при ошибке провайдера
                </label>
                <button class="btn btn-accent btn-sm ml-auto" onclick="aiSave()">
                    <i class="bi bi-check-lg"></i> Сохранить
                </button>
            </div>

            <div id="ai-spent-info" style="margin-top:10px;font-size:0.68rem;color:var(--text-muted);"></div>
            <div id="ai-quota-warning" style="display:none;margin-top:8px;padding:10px 12px;border-radius:4px;background:rgba(239,68,68,0.1);border-left:3px solid #ef4444;font-size:0.72rem;line-height:1.5;">
                <b style="color:#ef4444;">⚠ Бюджет AI на сегодня исчерпан</b><br>
                Прогрев сейчас работает на встроенных шаблонах (без AI). Если хочешь продолжить с AI — пополни баланс провайдера или увеличь дневной лимит выше.<br>
                Нужна помощь — напиши в раздел «Поддержка» (меню слева), ответим в тикете.
            </div>

            <!-- AI-пулы для прогрева -->
            <div class="mt-3" style="border-top:1px solid var(--border);padding-top:14px;">
                <div style="font-weight:600;font-size:0.82rem;margin-bottom:4px;">
                    <i class="bi bi-database-fill-add" style="color:var(--accent-light);"></i> AI-пулы для прогрева
                </div>
                <p style="font-size:0.7rem;color:var(--text-muted);line-height:1.55;margin-bottom:10px;">
                    Одной кнопкой сгенерируй уникальные имена чатов, юзернеймы, приветствия и тексты дневников — индивидуально для твоей инсталляции TelePush. Это снимает риск массового бана: Telegram не сможет «забанить пул» потому что у каждого клиента он свой.
                    <br><b>Стоимость:</b> ~$0.05-0.15 за полный пересчёт (одноразово). Промпты встроены в софт — настраивать ничего не нужно.
                </p>
                <div id="ai-pool-status" style="font-size:0.7rem;color:var(--text-muted);margin-bottom:8px;">Пулы не сгенерированы — используются встроенные шаблоны.</div>
                <div id="ai-pool-progress" style="display:none;margin-bottom:8px;">
                    <div class="progress mb-1" style="height:8px;"><div class="progress-bar" id="ai-pool-progress-bar" style="width:0%;background:var(--accent);"></div></div>
                    <div style="font-size:0.68rem;color:var(--text-muted);" id="ai-pool-progress-text">—</div>
                </div>
                <div class="d-flex gap-2 align-center flex-wrap">
                    <button class="btn btn-accent btn-sm" onclick="aiRegeneratePools()" id="btn-ai-regen">
                        <i class="bi bi-magic"></i> Сгенерировать AI-пулы
                    </button>
                    <button class="btn btn-outline btn-sm" onclick="aiClearPool()" id="btn-ai-clear">
                        <i class="bi bi-trash"></i> Сбросить пулы
                    </button>
                </div>
            </div>
        </div>
    </div>

    <!-- Разное -->
    <div class="card mb-3">
        <div class="card-header cursor-pointer" onclick="toggleSettingsSection('settings-misc')">
            <i class="bi bi-gear text-muted"></i> <b>Разное</b>
            <i class="bi bi-chevron-down text-muted" style="margin-left:auto;font-size:0.7rem;transition:transform .2s;" id="chev-settings-misc"></i>
        </div>
        <div class="card-body" id="settings-misc" style="display:none;">
            <!-- «Профиль безопасности» убран: он одной кнопкой перетирал паузы во
                 всех модулях сразу, а клиент их там же и настраивает руками —
                 и потом не понимает, кто сбросил его значения. -->
<div class="mb-3">
                <button class="btn btn-outline btn-sm" onclick="packLogs()">
                    <i class="bi bi-file-zip"></i> Упаковать логи <span class="tt" data-tip="Собирает все логи приложения (data/logs/) в один зашифрованный .tplog архив. Отправь его в поддержку — мы сможем диагностировать проблемы у тебя.">?</span>
                </button>
            </div>

            <!-- Присылка расширенных логов включена всегда и без переключателя:
                 клиенту решать тут нечего, а без логов разбор его же проблемы
                 превращается в переписку «пришлите скриншот». Телефоны и
                 юзернеймы маскируются, тексты сообщений не уходят. -->
            <div class="rd-group"><div class="rd-group-title">ОБНОВЛЕНИЯ</div>
            <div class="mb-3">
                <label class="ad-check"><input type="checkbox" id="s-auto-update-install" onchange="saveAutoUpdateInstall()"> <span>Устанавливать обновления автоматически при запуске<span class="ad-hint">Если включено — при старте софта новая версия скачается и накатится сама (без баннера «Обновить»). Без галочки — баннер появляется и ты сам решаешь когда обновиться.</span></span></label>
            </div>

            <div class="mb-3 d-flex align-center gap-3">
                <label class="ad-check mb-0"><input type="checkbox" id="s-update-sound" checked onchange="saveUpdateSound(this)"> <span>Звуковой сигнал когда приходит обновление<span class="ad-hint">Когда выходит новая версия — софт один раз проиграет весёлую мелодию «та-да», чтобы ты сразу услышал что обновление вышло. Сними галку если не нужно.</span></span></label>
                <button type="button" class="btn btn-outline btn-sm" onclick="playUpdateChime(true)" title="Проиграть звук обновления"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg> Прослушать</button>
            </div>
            </div>

            <div class="mb-3">
                <label class="form-label">Отдых аккаунта между задачами: <span class="tp-sec-hint" data-for="s-account-cooldown-sec"></span> <span class="tt" data-tip="Закончил задачу — столько ждёт перед следующей. 0 = без паузы. Это лёгкий спейсинг; основная защита акка — паузы между сообщениями и реакция на пауза от Telegram.">?</span></label>
                <div style="display:flex;gap:6px;align-items:center;">
                    <input type="number" class="form-control w-100px tp-sec" id="s-account-cooldown-sec" value="300" min="0" max="7200" step="60" onchange="saveAccountCooldown()">
                    <span style="font-size:0.72rem;color:var(--text-muted);">сек</span>
                </div>
            </div>

            <!-- Тумблер фонового сбора убран: он был выключен по умолчанию, поэтому
                 общий поиск по чатам наполняли единицы, а пользовались им все.
                 Сбор идёт всегда, аккаунты при этом не расходуются заметно. -->
<div class="rd-group"><div class="rd-group-title">ПАРАМЕТРЫ АККАУНТОВ</div>
            <div class="grid-2 mb-3" style="max-width:500px;">
                <div>
                    <label class="form-label">Параметры генерации JSON</label>
                    <select class="form-control" id="s-json-device" onchange="onDeviceChange()">
                        <option value="desktop_2040">Desktop (пара 2040)</option>
                        <option value="android">Android</option>
                        <option value="ios">iOS</option>
                    </select>
                </div>
                <div>
                    <label class="form-label">Автоудаление мёртвых акков</label>
                    <select class="form-control" id="s-auto-clean-dead">
                        <option value="off">Выключено</option>
                        <option value="move">Переместить в папку</option>
                        <option value="delete">Удалить</option>
                    </select>
                </div>
            </div>
            <div class="grid-2 mb-3" style="max-width:500px;">
                <div>
                    <label class="form-label">Авто-снятие спам-блока <span class="tt" data-tip="Когда срок временного блока истёк: «через @SpamBot» подключает акк и возвращает в работу только если бот подтвердил «свободен»; «по таймеру» снимает сразу.">?</span></label>
                    <select class="form-control" id="s-spam-auto-recheck">
                        <option value="spambot">Перепроверять через @SpamBot</option>
                        <option value="flag">Снимать по таймеру</option>
                        <option value="off">Не снимать автоматически</option>
                    </select>
                    
                </div>
            </div>
            <label class="opt-row mb-3">
                <input type="checkbox" id="s-tg-lang-ru" checked>
                Telegram общается с аккаунтом по-русски <span class="tt" data-tip="Аккаунт подключается с русским языком приложения. Тогда @SpamBot при проверке отвечает по-русски (а не по-португальски или узбекски — их софт распознаёт хуже), и встроенный веб-Telegram открывается на русском. Меняется только язык приложения; модель устройства, версия и язык системы у пары остаются прежними. Сними галку, чтобы вернуть язык по номеру телефона.">?</span>
            </label>

            <div class="grid-2 mb-3" style="max-width:500px;">
                <div>
                    <label class="form-label">API ID</label>
                    <input type="number" class="form-control" id="s-api-id" value="2040" min="1" style="max-width:200px;">
                </div>
                <div>
                    <label class="form-label">API Hash</label>
                    <input type="text" class="form-control" id="s-api-hash" value="b18441a1ff607e10a989891a5462e627" style="max-width:320px;">
                </div>
            </div>
            </div>
        </div>
    </div>

    <div class="d-flex gap-2 flex-wrap">
        <button class="btn btn-accent" onclick="saveSettings()"><i class="bi bi-check2"></i> Сохранить настройки</button>
        <button class="btn btn-outline btn-sm" onclick="openSettingsFolder()" data-tip="Открыть папку с файлом настроек в Проводнике — можно скопировать себе бэкап">
            <i class="bi bi-folder2-open"></i> Открыть папку
        </button>
        <button class="btn btn-outline btn-sm" onclick="showSettingsDebug()" data-tip="Показать путь к файлу настроек и что в нём реально записано">
            <i class="bi bi-info-circle"></i> Диагностика
        </button>
        <button class="btn btn-outline btn-sm" onclick="restoreSettingsFromBackup()" data-tip="Восстановить настройки из резервной копии (если основной файл был сброшен)">
            <i class="bi bi-arrow-counterclockwise"></i> Восстановить из бэкапа
        </button>
        <button class="btn btn-outline btn-sm" onclick="showHistoryStats()" data-tip="История операций (что софт помнит про отправки/подписки/парсинг) — посмотреть статистику и при желании сбросить">
            <i class="bi bi-clock-history"></i> История операций
        </button>
    </div>

    <!-- «Расширенные: Webhook» удалён. -->

    <!-- Глобальные чёрные списки -->
    <div class="card mb-3 mt-3">
        <div class="card-header"><i class="bi bi-shield-x text-danger"></i> Глобальные чёрные списки <span class="text-xs text-muted ml-2">— применяются ко ВСЕМ модулям</span></div>
        <div class="card-body">
            <div class="grid-2" style="gap:14px;">
                <div>
                    <label class="form-label">Чёрный список юзеров <span class="text-xs text-muted">(для DM и инвайтера)</span></label>
                    <textarea class="form-control" id="bl-users" rows="5" placeholder="@username&#10;123456789&#10;@another" style="font-size:0.72rem;font-family:monospace;"></textarea>
                    <div class="text-xs text-muted mt-1">Один юзер на строку: @username или id. Эти юзеры будут пропущены в DM и при инвайте.</div>
                </div>
                <div>
                    <label class="form-label">Чёрный список чатов <span class="text-xs text-muted">(для рассылки, парсера, мониторинга)</span></label>
                    <textarea class="form-control" id="bl-chats" rows="5" placeholder="@chatname&#10;https://t.me/somechat&#10;-1001234567890" style="font-size:0.72rem;font-family:monospace;"></textarea>
                    <div class="text-xs text-muted mt-1">Один чат на строку: @username, t.me/X или id. Эти чаты пропустятся в spam/parser/monitor.</div>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- ═══ TAB: Инструкция ═══ -->
<div class="section" id="tab-guide">
    <div class="card mb-3" style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;justify-content:space-between;">
        <div style="font-size:0.84rem;color:var(--text-secondary);">Не нашёл ответ здесь? Спроси AI-помощника или открой онлайн-версию путеводителя.</div>
        <div class="d-flex gap-2 flex-wrap">
            <button class="btn btn-accent btn-sm" onclick="toggleAiChat()"><i class="bi bi-robot"></i> Спросить AI</button>
            <a class="btn btn-outline btn-sm" href="https://telepush.org/guide" target="_blank" rel="noopener" style="text-decoration:none;"><i class="bi bi-box-arrow-up-right"></i> Онлайн-путеводитель</a>
        </div>
    </div>
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-book text-warning"></i><div class="ch-text"><div class="ch-title">Быстрый старт</div><div class="card-sub">как пользоваться</div></div></div>
        <div class="card-body" style="font-size:0.82rem;color:var(--text-secondary);line-height:1.6;">
            <ol style="margin:0 0 0 18px;padding:0;">
                <li><b>Закройте Telegram Desktop и другие программы с этими аккаунтами</b>, потом добавьте файлы аккаунтов во вкладке «Аккаунты» (два файла на аккаунт, лежат рядом). Если аккаунт в это же время открыт где-то ещё, Telegram закроет вход сразу в обоих местах.</li>
                <li>Добавьте прокси во вкладке «Прокси» — с ними работа стабильнее. Без прокси тоже всё работает.</li>
                <li>По желанию проверьте аккаунт кнопкой <i class="bi bi-heart-pulse"></i> в строке — покажет оценку надёжности от 0 до 100.</li>
                <li>Выберите раздел, настройте текст, чаты и паузы — и нажмите «Запустить».</li>
            </ol>
            <p style="margin-top:8px;color:var(--text-muted);font-size:0.74rem;">Один аккаунт — одна задача за раз. Несколько аккаунтов работают одновременно. Метка «Глух» рядом со статусом означает, что аккаунту лучше дать отдохнуть.</p>
            <div class="info-box" style="margin-top:10px;color:#f59e0b;background:rgba(245,158,11,.08);border-color:rgba(245,158,11,.3);">
                <i class="bi bi-exclamation-triangle" style="margin-right:6px;"></i>
                <b>Если аккаунт стал «Мёртвый» сразу после загрузки</b> — значит он в этот момент был открыт где-то ещё: в Telegram Desktop, на телефоне, в боте или в другой программе. Telegram закрыл вход сам. Если аккаунт покупной — просите у продавца новые файлы. Если ваш — войдите заново по номеру и коду во вкладке «Переавторизация».
            </div>
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-chat-dots text-accent"></i> Рассылка по чатам</div>
        <div class="card-body text-hint">
            Отправляет текст или фото в группы и каналы, где аккаунт уже состоит. Чтобы сообщения не были одинаковыми, пишите варианты в фигурных скобках: <code>{привет|здравствуй}</code> — программа выберет один случайно. Есть фильтр по словам и настройка пауз.
            <b>Подстановка</b>: <code>%name%</code> — имя получателя, <code>%username%</code> — его юзернейм, <code>%group%</code> — название чата.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-envelope text-success"></i> Личные сообщения</div>
        <div class="card-body text-hint">
            Рассылка в личные сообщения по списку получателей — вставьте вручную или загрузите .txt. Принимает @юзернейм, ссылку t.me/… и номер телефона. Есть варианты текста в фигурных скобках, фото, фильтр стоп-слов и подстановка имени через <code>%name%</code>.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-link-45deg text-info"></i> Подписка на чаты</div>
        <div class="card-body text-hint">
            Вступление в чаты и каналы по списку ссылок — обычных t.me/… и пригласительных. Паузы между вступлениями программа делает случайными сама. Повторы в списке по умолчанию не трогаются: если нужно их убрать, включите галочку «Чистить дубликаты в списке».
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-people text-warning"></i> Мульти-аккаунт</div>
        <div class="card-body text-hint">
            Запуск задачи сразу на нескольких аккаунтах. В окне выбора можно взять всех, только нужную папку или отметить поштучно. Занятые аккаунты выбрать нельзя — они уже в работе.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-search text-accent-base"></i> Сбор аудитории и поиск чатов</div>
        <div class="card-body text-hint">
            Откройте «Парсинг» и выберите режим в списке сверху:
            <ul style="margin:6px 0 0 18px;font-size:0.78rem;">
                <li><b>Аудитория из чата</b> — кто состоит, кто писал, кто ставил реакции, кто голосовал в опросах. Галочки можно отметить сразу несколько и собрать всё за один проход.</li>
                <li><b>Сборщик ссылок</b> — все ссылки t.me из сообщений и описаний выбранного чата.</li>
                <li><b>Слово везде</b> — находит каналы и чаты по слову. Работает <b>мгновенно и без аккаунтов</b>: ответ берётся из нашей базы. Можно отфильтровать по языку текста и региону.</li>
                <li><b>По словам</b> — ищет тех, кто писал указанные слова, в ваших собственных чатах.</li>
                <li><b>Глобальный поиск</b> — ищет чаты и каналы по словам через сам Telegram. С ключом TGStat охват шире.</li>
                <li><b>Чаты юзера</b> — где состоит указанный @юзернейм.</li>
                <li><b>Чекер юзов</b> — проверяет список людей: существует ли, когда был в сети.</li>
                <li><b>Чекер ссылок</b> — проверяет список ссылок t.me: живые или нет.</li>
            </ul>
            <p style="margin:8px 0 0 0;font-size:0.74rem;color:var(--text-muted);">
                Выгрузить результат — кнопка над таблицей, Excel или .txt.
                Режимы «Чаты юзера» и «Слово везде» работают даже без подключённых аккаунтов.
            </p>
</div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-fire text-orange"></i> Прогрев аккаунтов</div>
        <div class="card-body text-hint">
            Аккаунты переписываются между собой, чтобы выглядеть живыми. По умолчанию берутся <b>готовые фразы</b> — это бесплатно. Если включить <b>ИИ</b>, диалоги пишет нейросеть (нужен ключ в настройках). Нужно минимум два аккаунта, работа расписана по дням.
            <ul style="margin:6px 0 0 18px;font-size:0.78rem;">
                <li><b>Свои фразы</b> — раздел «Свои шаблоны прогрева». Три поля: приветствия, основные фразы, прощания. Можно загрузить из .txt</li>
                <li><b>Кого прогревать</b> — кнопка «Выбрать аккаунты». Выбор запоминается до следующего раза.</li>
                <li><b>Защита от повторов</b> — если три и больше аккаунтов отправили одну и ту же фразу за сутки, следующему отправку запретим: одинаковые сообщения с разных аккаунтов Telegram замечает быстро.</li>
                <li><b>Юзернейм</b> — программа сама поставит его аккаунту, если его нет. Если Telegram попросит подождать, попробует ещё раз через час.</li>
            </ul>
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-person-vcard text-accent"></i> Заполнение профиля</div>
        <div class="card-body text-hint">
            Массово ставит имя, фамилию, фото и описание сразу многим аккаунтам. Варианты текста пишутся в фигурных скобках, можно поручить сочинение нейросети.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-reply text-success"></i> Автоответчик</div>
        <div class="card-body text-hint">
            Отвечает на входящие в личных сообщениях и заодно собирает тех, кто написал — их список можно выгрузить в Excel или .txt. Текст ответа и задержка настраиваются. Работает, пока аккаунт подключён, и его можно включить прямо со старта рассылки.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-broadcast" style="color:#f472b6;"></i> Мониторинг чатов</div>
        <div class="card-body text-hint">
            Следит за сообщениями по ключевым словам в чатах, где состоит аккаунт. Как только слово попалось — уведомление уходит в «Избранное» этого же аккаунта или на указанный @юзернейм. Можно слать через своего бота.
            <ul style="margin:6px 0 0 18px;font-size:0.78rem;">
                <li>Чаты по 1 на строку, ключи через запятую</li>
                <li>Все совпадения складываются в файл — кнопка «Лог совпадений»</li>
                <li>После перезапуска программы нажмите <b>«Восстановить»</b> — слежение поднимется с прежними настройками</li>
            </ul>
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-chat-quote text-purple"></i> Нейрокомменты</div>
        <div class="card-body text-hint">
            Аккаунты пишут осмысленные комменты под свежими постами в указанных каналах. Текст генерит AI по теме поста.
            <ul style="margin:6px 0 0 18px;font-size:0.78rem;">
                <li>У канала должны быть включены комментарии</li>
                <li>Аккаунты должны быть подписаны на канал</li>
                <li>Ограничения: сколько комментариев на один пост, пауза 2–15 минут, лимит на аккаунт в час и в сутки</li>
                <li>Можно добавить свою приписку с рекламой — нейросеть вставит её только если комментарий получается естественным</li>
            </ul>
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-person-walking text-purple"></i> Имитация активности</div>
        <div class="card-body text-hint">
            Держит аккаунты живыми: показывает их в сети и открывает истории других людей. Так Telegram реже принимает аккаунт за брошенный или за бота. Запускается на выбранные аккаунты и работает в фоне.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-graph-up-arrow text-success"></i> Накрутка</div>
        <div class="card-body text-hint">
            Массовые действия вашими аккаунтами по одной ссылке: подписаться на канал, поставить реакцию, проголосовать в опросе, нажать кнопку под постом, запустить бота, добавить просмотры. Всё идёт параллельно, с паузами между действиями.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-cpu text-purple"></i> AI помощник</div>
        <div class="card-body text-hint">
            Кнопка <b>ИИ</b> сверху панели. Помощник видит состояние ваших аккаунтов (кто на паузе, кто в заморозке, что с прокси) и знает все разделы программы. Спросите коротко — ответит в два-три предложения и подскажет, куда нажать.
            <ul style="margin:6px 0 0 18px;font-size:0.78rem;">
                <li><b>Примеры вопросов:</b> «Telegram просит подождать, что делать?», «как добавить прокси?», «как найти чаты, где состоит человек?», «почему аккаунты часто слетают?»</li>
                <li><b>Разбирается:</b> во всех разделах программы, в частых ограничениях Telegram — спам-блок, заморозка, вход с двух мест одновременно — и в безопасных паузах для рассылки.</li>
                <li><b>Ключ:</b> подключается в <a class="text-accent" href="javascript:showTab('settings')">Настройках → ИИ</a>. На выбор DeepSeek (самый дешёвый), OpenAI, Anthropic и Gemini — у последнего есть бесплатный лимит.</li>
                <li><b>Тот же ключ работает</b> в прогреве, нейрокомментах и нейро-чаттере.</li>
                <li>Ваши аккаунты и их файлы никуда не отправляются — только числа: сколько живых, сколько на паузе.</li>
            </ul>
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-shield-lock text-info"></i> Прокси</div>
        <div class="card-body text-hint">
            Вставьте список прокси — программа сама поймёт тип и раздаст их аккаунтам. Один прокси на 1–3 аккаунта — нормально. Кнопка «Проверить прокси» покажет, какие живые. Внизу вкладки — паузы и таймауты подключения.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-people-fill text-accent-base"></i> Аккаунты — массовые операции</div>
        <div class="card-body text-hint">
            Отметьте галочками несколько аккаунтов — их можно <b>проверить на спам-блок</b>, перенести в другую папку, поставить или снять облачный пароль, отвязать прокси. Удаление — по одному, кнопкой в строке. Папки «Мониторинг», «Прогрев», «После инвайта» нужны, чтобы разделять аккаунты по назначению.
            <ul style="margin:6px 0 0 18px;font-size:0.78rem;">
                <li><b>Кнопки статусов</b> над таблицей — один клик фильтрует список: живые, заморозка, спам-блок. Мёртвые в списке не показываются, их файлы лежат в папке «Мёртвые».</li>
                <li><b><i class="bi bi-heart-pulse"></i> Проверка аккаунта</b> — кнопка в строке. Покажет оценку надёжности от 0 до 100 и что на неё влияет: возраст, юзернейм, фото, контакты, переписки.</li>
                <li><b>Метка «Глух»</b> — оценка ниже 45 или Telegram перестал через этот аккаунт находить публичные чаты. Снимается сама через сутки или после первой удачной работы.</li>
            </ul>
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-shield-check text-info"></i> Чекер аккаунтов</div>
        <div class="card-body text-hint">
            Проверяет, в каком состоянии аккаунты: есть ли <b>спам-блок</b> (спрашивает у @SpamBot) и нет ли <b>заморозки</b> — её @SpamBot не показывает, поэтому проверяем отдельно. После проверки аккаунты сами раскладываются по папкам: рабочие — в «Живые», с временным спам-блоком и с вечным — в свои подпапки «Спамблок», замороженные — в «Замороженные». Можно запустить по выбранным или сразу по всем.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-arrow-repeat text-info"></i> Переавторизация</div>
        <div class="card-body text-hint">
            Если аккаунт слетел — войдите заново по номеру и коду прямо здесь, без Telegram Desktop. Работает с аккаунтом из любой папки, после успешного входа метка «Мёртвый» снимается.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-person-plus text-accent"></i> Приглашения (инвайтинг)</div>
        <div class="card-body text-hint">
            Массово приглашает людей из собранного списка в вашу группу или канал. Внутри: список чатов, история приглашений (кого уже звали — повторно не позовём) и отчёты. После работы аккаунты сами раскладываются по папкам «После инвайта» — отдельно те, кто поймал спам-блок.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-chat-heart text-purple"></i> Оживление (AI-переписка в ЛС)</div>
        <div class="card-body text-hint">
            Аккаунт ведёт живую переписку в личных сообщениях с помощью нейросети (нужен ключ ИИ). Может <b>писать первым</b> по списку людей и <b>отвечать на входящие</b>. Помнит, о чём говорили раньше, показывает «печатает» и делает паузы, как человек.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-graph-up text-success"></i> Аналитика</div>
        <div class="card-body text-hint">
            Сводка по аккаунтам и задачам: сколько отправлено, сколько живых и замороженных, чем занимались разделы.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-trash3 text-info"></i> Очистка</div>
        <div class="card-body text-hint">
            Массово чистит переписки аккаунтов — обычные диалоги, ответы и «Избранное», — чтобы аккаунт не копил лишнее и выглядел естественно. Перед удалением можно посмотреть список без изменений.
        </div>
    </div>


    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-telephone text-info"></i> Чекер номеров</div>
        <div class="card-body text-hint">
            Проверяет список телефонов: есть ли у номера Telegram и что о нём видно — юзернейм, имя, когда был в сети. Номера по одному на строку, результат выгружается в Excel или .txt. Проверка идёт вашими аккаунтами, поэтому большой список лучше разбить.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-chat-heart text-purple"></i> Нейро-чаттер</div>
        <div class="card-body text-hint">
            Переписка в личных сообщениях с помощью нейросети. Отличие от «Оживления» — здесь аккаунт сам заводит новые диалоги по списку целей и держит темп живого человека: несколько новых собеседников в день, пауза 20–90 минут между ними, ограничение на число сообщений одному человеку за сутки. Нужен ключ ИИ.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-activity text-warning"></i> Монитор аккаунтов</div>
        <div class="card-body text-hint">
            Показывает, что прямо сейчас происходит с аккаунтами: кто чем занят, кто на паузе, у кого спам-блок или заморозка. Удобно держать открытым во время большой рассылки — видно, где встало, не заглядывая в логи.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-arrow-left-right text-accent"></i> Конвертеры аккаунтов</div>
        <div class="card-body text-hint">
            Два раздела для перевода аккаунтов между форматами:
            <ul style="margin:6px 0 0 18px;font-size:0.78rem;">
                <li><b>Из Telegram Desktop</b> — берёт папку с данными Telegram Desktop и делает из неё файлы аккаунта для программы.</li>
                <li><b>В Telegram Desktop</b> — обратно: из файлов аккаунта собирает папку, которую откроет Telegram Desktop.</li>
            </ul>
            <p style="margin:8px 0 0 0;font-size:0.74rem;color:var(--text-muted);">
                Пароль второго уровня, если он был, сохраняется в отдельный файл рядом. Оригиналы не удаляются — при желании поставьте галку «Сохранить оригинал».
            </p>
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-person-badge text-accent"></i> Профиль лицензии</div>
        <div class="card-body text-hint">
            Ваш ключ, до какого числа он действует и какие разделы открыты. Там же кнопка отвязки от компьютера — она нужна, если вы переносите программу на другой ПК.
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-life-preserver text-success"></i> Сообщить об ошибке</div>
        <div class="card-body text-hint">
            Опишите, что пошло не так, — сообщение уйдёт прямо нам вместе с версией программы. Если приложить логи кнопкой «Упаковать логи» в настройках, разбираться будем быстрее: там видно, на каком шаге всё встало.
        </div>
    </div>

    <div class="card">
        <div class="card-header"><i class="bi bi-lightbulb text-success"></i> Советы (по желанию)</div>
        <div class="card-body text-hint">
            <ul style="margin:0 0 0 18px;font-size:0.78rem;">
                <li>С прокси работа стабильнее — берите один прокси на 1–3 аккаунта</li>
                <li>Новым аккаунтам полезно дать пару дней прогрева перед работой</li>
                <li>Статусы во вкладке «Аккаунты» обновляются сами, вручную обновлять не нужно</li>
            </ul>
        </div>
    </div>
</div>

<!-- ═══ TAB: Профиль ═══ -->
<div class="section" id="tab-profile">
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-person-badge text-accent"></i><div class="ch-text"><div class="ch-title">Профиль лицензии</div><div class="card-sub">ваш профиль и лицензия</div></div></div>
        <div class="card-body" id="profile-data" style="font-size:0.85rem;">
            <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px 24px;">
                <div>
                    <span class="section-label" >Лицензия</span>
                    <div id="prf-key" style="font-family:'JetBrains Mono',monospace;font-weight:600;color:var(--text-primary);margin-top:2px;">---</div>
                </div>
                <div>
                    <span class="section-label" >Срок действия</span>
                    <div id="prf-expires" style="font-weight:600;color:var(--success);margin-top:2px;">---</div>
                </div>
                <div>
                    <span class="section-label" >Версия</span>
                    <div id="prf-version" style="font-weight:600;color:var(--accent-light);margin-top:2px;">---</div>
                </div>
                <div>
                    <span class="section-label" >Тариф</span>
                    <div id="prf-key-type" style="font-weight:600;color:var(--success);margin-top:2px;">---</div>
                </div>
                <div>
                    <span class="section-label" >привязку к компьютеру</span>
                    <div id="prf-hwid" style="font-family:'JetBrains Mono',monospace;font-size:0.75rem;color:var(--text-muted);margin-top:2px;">---</div>
                </div>
                <div>
                    <span class="section-label" >Компьютер</span>
                    <div id="prf-pc" style="color:var(--text-primary);margin-top:2px;">---</div>
                </div>
                <div>
                    <span class="section-label" >Аккаунты</span>
                    <div id="prf-accs" style="color:var(--text-primary);margin-top:2px;">---</div>
                </div>
            </div>
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-grid-3x3-gap text-accent"></i> Доступные модули</div>
        <div class="card-body">
            <div id="prf-modules" style="display:flex;flex-wrap:wrap;gap:6px;"></div>
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-key text-accent"></i> Сменить ключ</div>
        <div class="card-body">
            <p style="font-size:0.82rem;color:var(--text-muted);margin-bottom:12px;">Введите новый лицензионный ключ — активируется на месте, без выхода из софта. Старый ключ заменится.</p>
            <div class="d-flex gap-3 align-center" style="flex-wrap:wrap;">
                <input type="text" class="form-control" id="new-license-key" placeholder="Новый ключ"
                       autocomplete="off" spellcheck="false"
                       style="max-width:340px;font-family:'JetBrains Mono',monospace;">
                <button class="btn btn-accent btn-sm" onclick="changeLicenseKey()" id="btn-change-key">
                    <i class="bi bi-key"></i> Сменить ключ
                </button>
            </div>
            <div id="change-key-result" style="margin-top:8px;font-size:0.82rem;display:none;"></div>
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-arrow-repeat text-warning"></i> Сброс привязки</div>
        <div class="card-body">
            <p style="font-size:0.82rem;color:var(--text-muted);margin-bottom:12px;">Сменили компьютер? Сбросьте привязку и войдите заново на новом ПК.</p>
            <button class="btn btn-outline btn-sm" onclick="resetHwid()" id="btn-reset-hwid">
                <i class="bi bi-pc-display"></i> Сбросить привязку
            </button>
            <div id="reset-result" style="margin-top:8px;font-size:0.82rem;display:none;"></div>
        </div>
    </div>

    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-globe2 text-accent-base"></i> Профиль на сайте</div>
        <div class="card-body">
            <p style="font-size:0.82rem;color:var(--text-muted);margin-bottom:12px;">Версия, скачивание, сброс привязки, поддержка.</p>
            <a id="prf-site-link" href="#" target="_blank" class="btn btn-accent btn-sm" style="text-decoration:none;">
                <i class="bi bi-box-arrow-up-right"></i> Открыть профиль
            </a>
        </div>
    </div>

    <div class="card">
        <div class="card-header"><i class="bi bi-door-open text-danger"></i> Выход</div>
        <div class="card-body">
            <a href="/logout" class="btn btn-outline btn-sm" style="color:var(--danger);border-color:var(--danger);">
                <i class="bi bi-box-arrow-left"></i> Выйти из аккаунта
            </a>
        </div>
    </div>
</div>

<!-- ═══ TAB: Имитация активности ═══ -->
<div class="section" id="tab-imitation">
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-person-walking text-purple"></i><div class="ch-text"><div class="ch-title">Имитация активности</div><div class="card-sub">имитация живой активности</div></div></div>
        <div class="card-body">
            <div class="info-box" style="margin-bottom:12px;font-size:0.74rem;">
                Аккаунты в фоне делают «человеческие» действия БЕЗ реальных задач рассылки —
                читают сообщения в случайных диалогах, открывают профили, скроллят. Telegram-алгоритмы видят
                естественный паттерн → меньше шанс ловли спам-фильтра у свежих/прогретых акков.
                <br><br>
                <b>Когда полезно:</b> молодые акки между основными задачами, акки-мониторщики,
                «отлёжка» акков после спам-блока.
                <br><br>
                <b>⚠️ Совет от сообщества:</b> на просмотрах историй / постов без реакций Telegram быстро шлёт пауза от Telegram. Чтобы избежать — раз в 4-5 действий имитация должна ставить лайк/реакцию (либо открыть профиль). На свежих акках (&lt;2 мес) масс-просмотры почти не работают — Telegram бьёт банами независимо от настроек.
            </div>

            <div class="rd-group"><div class="rd-group-title">АККАУНТЫ</div>
            <label class="form-label">Аккаунты</label>
            <div class="acc-selector mb-3" id="acc-selector-imitation"></div>
            </div>

            <div class="rd-group"><div class="rd-group-title">ЛИМИТЫ</div>
            <div class="grid-3 mb-3">
                <div>
                    <label class="form-label">Интервал между действиями, от (сек) <span class="tp-sec-hint" data-for="imit-interval-sec"></span></label>
                    <input type="number" class="form-control tp-sec" id="imit-interval-sec" value="900" min="300" max="10800" step="60">
                </div>
                <div>
                    <label class="form-label">Интервал между действиями, до (сек)</label>
                    <input type="number" class="form-control tp-sec" id="imit-interval-sec-max" value="2700" min="600" max="21600" step="60">
                </div>
                <div>
                    <label class="form-label">Действий за раунд</label>
                    <input type="number" class="form-control" id="imit-actions-per-round" value="3" min="1" max="10">
                </div>
            </div>
            </div>

            <details class="ad-block" open>
                <summary><i class="bi bi-list-check"></i> Что делает аккаунт</summary>
                <div class="ad-body">
                    <label class="ad-check"><input type="checkbox" id="imit-do-read" checked> <span>Читать непрочитанные сообщения<span class="ad-hint">Открыть случайный диалог где есть unread → отметить прочитанным</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="imit-do-view-profile" checked> <span>Открывать профили из контактов<span class="ad-hint">Открывать профиль случайного пользователя из диалогов</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="imit-do-view-photo"> <span>Смотреть аватарки<span class="ad-hint">Реже — раз в 5-10 диалогов</span></span></label>
                </div>
            </details>


            <div id="imit-counters" style="margin-top:12px;display:none;font-size:0.78rem;color:var(--text-muted-strong);"></div>
        </div>
    </div>
            <div class="run-row">
            <div class="d-flex gap-2 mb-2">
                <button class="btn btn-accent btn-sm" onclick="startImitation()" id="btn-imit-start">
                    <i class="bi bi-play-fill"></i> Запустить
                </button>
                <button class="btn btn-danger btn-sm" onclick="stopImitation()" id="btn-imit-stop" style="display:none;">
                    <i class="bi bi-stop-fill"></i> Остановить
                </button>
                <span id="imit-status-label" class="text-xs text-muted tag-right"></span>
            </div>
            </div>
</div>

<!-- ═══ TAB: Чекер аккаунтов ═══ -->
<div class="section" id="tab-checker">
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-shield-check text-accent"></i><div class="ch-text"><div class="ch-title">Чекер аккаунтов</div><div class="card-sub">проверка аккаунтов на живость</div></div></div>
        <div class="card-body">
            <div class="info-box" style="margin-bottom:14px;">
                Проверяет аккаунты через @SpamBot и определяет статус: <b>живой</b> / временный спамблок / вечный спамблок / заморожен.
                Опционально — авто-подача заявок на снятие спамблока, авто-снятие заморозки через DeepSeek-AI, сортировка по папкам.
            </div>

            <div class="rd-group"><div class="rd-group-title">АККАУНТЫ И КЛЮЧ</div>
            <label class="form-label">Аккаунты для проверки</label>
            <div class="acc-selector mb-3" id="acc-selector-checker"></div>

            <label class="form-label">Ключ от RuCaptcha <span style="color:var(--text-muted);font-weight:400;">(опционально, для прохождения капчи если @SpamBot её попросит)</span></label>
            <input type="text" class="form-control mb-3" id="ck-rucaptcha" placeholder="Получить ключ: rucaptcha.com">
            </div>

            <details class="ad-block" open>
                <summary><i class="bi bi-shield-exclamation"></i> Опции для спамблока</summary>
                <div class="ad-body">
                    <button class="btn btn-outline btn-sm mb-2" onclick="ckOpenSpamTexts()" style="font-size:0.7rem;padding:4px 12px;">
                        <i class="bi bi-list-ul"></i> Тексты для снятия спамблока
                    </button>
                    <label class="ad-check"><input type="checkbox" id="ck-check-spam" checked> <span>Проверять аккаунты на спамблок<span class="ad-hint">Если выкл — пропускает шаг проверки, сразу подаёт заявку (если включено)</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="ck-submit-spam-appeal"> <span>Подавать заявку на снятие спамблока<span class="ad-hint">При временном спамблоке отправляет случайный текст из списка в @SpamBot</span></span></label>
                </div>
            </details>

            <details class="ad-block">
                <summary><i class="bi bi-snow"></i> Опции для заморозки</summary>
                <div class="ad-body">
                    <label class="form-label" style="margin-top:6px;">Промт для снятия заморозки <small class="text-muted" >(контекст для DeepSeek)</small></label>
                    <textarea class="form-control mb-2" id="ck-freeze-prompt" rows="2" placeholder="Например: Я обычный пользователь, использую аккаунт для общения с друзьями." style="font-size:0.74rem;"></textarea>
                    <label class="ad-check"><input type="checkbox" id="ck-submit-freeze-appeal"> <span>Подавать заявку на снятие заморозки<span class="ad-hint">При заморозке ведёт диалог с @SpamBot через DeepSeek</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="ck-use-hacked" checked> <span>Использовать причину "Аккаунт был взломан"</span></label>
                    <label class="ad-check"><input type="checkbox" id="ck-use-mistake" checked> <span>Использовать причину "Это ошибка"</span></label>
                    <label class="form-label mt-8">Ключ от DeepSeek <small class="text-muted" >(нужен для снятия заморозки — генерит «человеческие» ответы)</small></label>
                    <input type="text" class="form-control" id="ck-deepseek" placeholder="Получить ключ: platform.deepseek.com">
                </div>
            </details>

            <details class="ad-block">
                <summary><i class="bi bi-gear"></i> Дополнительные опции</summary>
                <div class="ad-body">
                    <label class="form-label" style="margin-top:6px;">Параллельных потоков
                        <span class="ad-hint">Сколько акков проверять одновременно — это и есть число «Потоков» в логе. <b>0 или пусто = все сразу</b> (годится, когда у аккаунтов разные прокси). Если все сидят на одном прокси, темп задаёт сам прокси — программа своих пауз перед подключением не делает.</span>
                    </label>
                    <input type="number" class="form-control mb-3" id="ck-max-parallel" min="0" max="200" value="0" placeholder="0 = все сразу" style="max-width:160px;">
                    <label class="ad-check"><input type="checkbox" id="ck-sort-folders" checked> <span>Сортировать аккаунты по папкам<span class="ad-hint">После проверки аккаунты раскладываются по статусу: Живые / Спамблок / Замороженные</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="ck-rename-files"> <span>Обновлять название файлов<span class="ad-hint">Если в имени session/json указан неверный номер — файлы переименуются</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="ck-delete-dialog"> <span>Удалять диалог со спамботом<span class="ad-hint">После проверки удаляет переписку с @SpamBot</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="ck-prepare"> <span>Подготовить аккаунты к рассылке<span class="ad-hint">Для живых аккаунтов собирает чаты, в которые можно сразу писать. Собранные чаты потом подставляются как цели (кнопка в «Рассылке») или уходят в монитор-бота.</span></span></label>
                    <div style="margin-left:24px;border-left:2px solid var(--border);padding-left:12px;">
                        <label class="ad-check"><input type="checkbox" id="ck-prepare-leave" checked> <span>Выйти из непишущих групп<span class="ad-hint">Аккаунт выходит из групп, где писать нельзя (только чтение / забанен / форум). Выход идёт ДО рассылки. Сними галку, если хочешь только собрать список, ничего не покидая.</span></span></label>
                        <label class="ad-check"><input type="checkbox" id="ck-prepare-bot"> <span>Отправить список чатов в монитор-бота<span class="ad-hint">Писабельные чаты по каждому аккаунту прилетят тебе в бота управления фермой.</span></span></label>
                        <label class="ad-check"><input type="checkbox" id="ck-prepare-load"> <span>…а также автоматически при забивке (загрузке) аккаунтов<span class="ad-hint">Новые загруженные аккаунты готовятся сами, в фоне, по одному (без нагрузки). Собранные чаты так же попадают в кнопку «Подставить собранные чаты» и (если включено) в монитор-бота.</span></span></label>
                    </div>
                </div>
            </details>

            <details class="ad-block">
                <summary><i class="bi bi-folder"></i> Настройки папок</summary>
                <div class="ad-body" style="padding:8px 14px 12px;">
                    <label class="form-label" style="margin-top:4px;">Куда перемещать живые аккаунты</label>
                    <input type="text" class="form-control mb-2" id="ck-folder-alive" value="Аккаунты/Живые" placeholder="Аккаунты/Живые">
                    <label class="form-label">Куда перемещать с временным спамблоком</label>
                    <input type="text" class="form-control mb-2" id="ck-folder-temp" value="Аккаунты/Спамблок/Временный" placeholder="Аккаунты/Спамблок/Временный">
                    <label class="form-label">Куда перемещать с вечным спамблоком</label>
                    <input type="text" class="form-control mb-2" id="ck-folder-eternal" value="Аккаунты/Спамблок/Вечный" placeholder="Аккаунты/Спамблок/Вечный">
                    <label class="form-label">Куда перемещать замороженные</label>
                    <input type="text" class="form-control" id="ck-folder-frozen" value="Аккаунты/Замороженные" placeholder="Аккаунты/Замороженные">
                </div>
            </details>


            <div id="ck-progress" style="display:none;margin-top:8px;">
                <div class="progress mb-2-x">
                    <div class="progress-bar" id="ck-progress-bar" style="width:0%;"></div>
                </div>
                <div style="font-size:0.74rem;color:var(--text-muted);" id="ck-progress-text">—</div>
                <div id="ck-counters" style="margin-top:6px;font-size:0.72rem;display:flex;gap:14px;flex-wrap:wrap;"></div>
            </div>
        </div>
    </div>
            <div class="run-row">
            <div class="d-flex gap-2 mt-3 mb-2">
                <button class="btn btn-accent" onclick="startChecker()" id="btn-ck-start">
                    <i class="bi bi-play-fill"></i> Запустить проверку
                </button>
                <button class="btn btn-outline btn-sm self-center" onclick="saveCheckerConfig()">
                    <i class="bi bi-save"></i> Сохранить настройки
                </button>
                <button class="btn btn-danger" onclick="stopChecker()" id="btn-ck-stop" style="display:none;">
                    <i class="bi bi-stop-fill"></i> Остановить
                </button>
                <span id="ck-status-label" class="text-xs text-muted tag-right"></span>
            </div>
            </div>
</div>

<!-- ═══ TAB: Чекер номеров ═══ -->
<div class="section" id="tab-number-checker">
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-telephone-fill text-accent"></i><div class="ch-text"><div class="ch-title">Чекер номеров</div><div class="card-sub">проверка номеров в Telegram</div></div></div>
        <div class="card-body">
            <div class="info-box" style="margin-bottom:14px;">
                Проверяет, кто из списка телефонов <b>зарегистрирован в Telegram</b>. Номера раскидываются по выбранным аккаунтам (резолв через контакты), результат можно выгрузить в файл или отправить в ЛС-рассылку. ⚠️ Импорт номеров — чувствительная операция: держи паузу и не гони большие списки одним аккаунтом.
            </div>

            <div class="rd-group"><div class="rd-group-title">ИСХОДНЫЕ ДАННЫЕ</div>
            <label class="form-label">Номера телефонов <span style="color:var(--text-muted);font-weight:400;">(по одному на строку или через запятую; любой формат: +7…, 380…, 1 202…)</span></label>
            <textarea class="form-control mb-3" id="nc-phones" rows="7" placeholder="+79991234567&#10;380671234567&#10;+1 202 555 0143"></textarea>

            <label class="form-label">Каким аккаунтами проверять</label>
            <div class="acc-selector mb-3" id="acc-selector-number-checker"></div>
            </div>

            <details class="ad-block">
                <summary><i class="bi bi-gear"></i> Тайминги (анти-бан)</summary>
                <div class="ad-body">
                    <div class="mb-2"><label class="form-label">Пауза между номерами — мин (сек) <span class="ad-hint">Импорт контактов — сильный спам-сигнал Telegram. Держи паузу 4+ сек. Софт ждёт случайное число между «мин» и «макс».</span></label><input type="number" inputmode="numeric" class="form-control ts-num" id="nc-delay-min" min="0" step="1" value="6" style="max-width:130px;"></div>
                    <div class="mb-2"><label class="form-label">макс (сек)</label><input type="number" inputmode="numeric" class="form-control ts-num" id="nc-delay-max" min="0" step="1" value="12" style="max-width:130px;"></div>
                </div>
            </details>


            <div id="nc-progress" style="display:none;margin-top:8px;">
                <div class="progress mb-2-x"><div class="progress-bar" id="nc-progress-bar" style="width:0%;"></div></div>
                <div style="font-size:0.74rem;color:var(--text-muted);" id="nc-progress-text">—</div>
                <div id="nc-counters" style="margin-top:6px;font-size:0.72rem;display:flex;gap:14px;flex-wrap:wrap;"></div>
            </div>

            <div id="nc-results-wrap" style="display:none;margin-top:12px;">
                <div class="d-flex gap-2 mb-2 flex-wrap align-center">
                    <button class="btn btn-outline btn-sm" onclick="exportNumberCheck('registered','txt')"><i class="bi bi-download"></i> Экспорт (кто в ТГ) .txt</button>
                    <button class="btn btn-outline btn-sm" onclick="exportNumberCheck('all','csv')"><i class="bi bi-filetype-csv"></i> Экспорт всё .csv</button>
                    <button class="btn btn-outline btn-sm" onclick="numberCheckToDm()"><i class="bi bi-person-lines-fill"></i> Отправить в ЛС-рассылку</button>
                </div>
                <div id="nc-results" style="max-height:320px;overflow:auto;"></div>
            </div>

        </div>
    </div>
            <div class="run-row">
            <div class="d-flex gap-2 mt-3 mb-2">
                <button class="btn btn-accent" onclick="startNumberCheck()" id="btn-nc-start"><i class="bi bi-play-fill"></i> Проверить</button>
                <button class="btn btn-danger" onclick="stopNumberCheck()" id="btn-nc-stop" style="display:none;"><i class="bi bi-stop-fill"></i> Остановить</button>
                <span id="nc-status-label" class="text-xs text-muted tag-right"></span>
            </div>
            </div>
</div>

<!-- ═══ TAB: Очистка ТГ ═══ -->
<div class="section" id="tab-cleanup">
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-eraser text-accent"></i><div class="ch-text"><div class="ch-title">Очистка ТГ</div><div class="card-sub">очистка диалогов и подписок</div></div></div>
        <div class="card-body">
            <div class="info-box" style="margin-bottom:14px;">
                Покидает каналы/группы/боты + убирает диалоги из списка. Личные переписки только скрывает у себя (история у собеседника остаётся).
                Закреплённые диалоги, <b>Telegram</b>, <b>Replies</b>, <b>Saved Messages</b> — никогда не трогаем.
                Между удалениями пауза <b>1,5–4 сек</b>, плюс отдых <b>15–45 сек</b> примерно каждые 15 удалений — так это
                выглядит как ручная чистка. Ориентир: <b>1000 диалогов ≈ 1 час</b>. Если Telegram просит подождать — ждём сами.
            </div>

            <div class="rd-group"><div class="rd-group-title">АККАУНТЫ</div>
            <label class="form-label">Аккаунты</label>
            <div class="acc-selector mb-3" id="acc-selector-cleanup"></div>
            </div>

            <div class="rd-group"><div class="rd-group-title">ОПЦИИ</div>
            <div class="grid-2" style="gap:14px;margin-bottom:14px;">
                <div>
                    <label class="form-label">Что чистить</label>
                    <label class="ad-check"><input type="checkbox" id="cln-t-channels"> <span>Каналы (broadcast)</span></label>
                    <label class="ad-check"><input type="checkbox" id="cln-t-groups"> <span>Группы (megagroup + chat)</span></label>
                    <label class="ad-check"><input type="checkbox" id="cln-t-bots"> <span>Боты</span></label>
                    <label class="ad-check"><input type="checkbox" id="cln-t-pm"> <span>Личные диалоги</span></label>
                </div>
                <div>
                    <label class="form-label">Действие</label>
                    <label class="ad-check"><input type="radio" name="cln-action" value="delete" checked> <span>Покинуть + убрать из списка <span class="ad-hint">(рекомендуется)</span></span></label>
                    <label class="ad-check"><input type="radio" name="cln-action" value="leave_only"> <span>Только выйти, оставить в списке</span></label>
                    <label class="ad-check"><input type="radio" name="cln-action" value="hide_only"> <span>Только убрать из списка</span></label>
                </div>
            </div>
            </div>

            <details class="ad-block">
                <summary><i class="bi bi-funnel"></i> Дополнительные фильтры</summary>
                <div class="ad-body">
                    <label class="ad-check"><input type="checkbox" id="cln-only-no-write"> <span>Только где нельзя писать <span class="ad-hint">broadcast без админа / группы где запрещено писать</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="cln-delete-folders"> <span>Удалить папки аккаунта <span class="ad-hint">снести все папки (chat folders) — из чатов НЕ выкидывает, только убирает группировку и «следы»</span></span></label>
                    <div class="grid-2" style="gap:14px;margin-top:8px;">
                        <div>
                            <label class="form-label fs-72">Только без активности больше N дней <span class="ad-hint">(0 = без фильтра)</span></label>
                            <input type="number" class="form-control" id="cln-inactive-days" min="0" max="3650" value="0">
                        </div>
                        <div>
                            <label class="form-label fs-72">Ключевые слова в названии <span class="ad-hint">(по строке/запятой; пусто = не использовать)</span></label>
                            <textarea class="form-control" id="cln-keywords" rows="2" placeholder="спам&#10;казино&#10;crypto"></textarea>
                        </div>
                    </div>
                </div>
            </details>

            <details class="ad-block">
                <summary><i class="bi bi-shield-lock"></i> Whitelist (не трогать)</summary>
                <div class="ad-body">
                    <label class="ad-check"><input type="checkbox" id="cln-skip-no-username" checked> <span>Не трогать личные диалоги без @username <span class="ad-hint">защита от случайного сноса VIP-контактов</span></span></label>
                    <label class="form-label fs-72" style="margin-top:8px;">@юзернеймы которые НЕ трогать (по строке)</label>
                    <textarea class="form-control" id="cln-whitelist" rows="3" placeholder="@telegram&#10;@friend1&#10;@my_main_chat"></textarea>
                </div>
            </details>


            <div id="cleanup-progress" style="display:none;margin-top:14px;">
                <div style="display:flex;justify-content:space-between;font-size:0.72rem;margin-bottom:4px;">
                    <span id="cleanup-current-step" style="color:var(--text-muted);">—</span>
                    <span><b id="cleanup-processed">0</b> удалено</span>
                </div>
                <div style="display:flex;gap:8px;flex-wrap:wrap;font-size:0.7rem;color:var(--text-muted);margin-bottom:8px;">
                    <span>Каналы: <b id="cleanup-ch">0</b></span>
                    <span>Группы: <b id="cleanup-gr">0</b></span>
                    <span>Боты: <b id="cleanup-bt">0</b></span>
                    <span>Личка: <b id="cleanup-pm">0</b></span>
                    <span>WL: <b id="cleanup-wl">0</b></span>
                    <span style="color:var(--danger);">Ошибок: <b id="cleanup-err">0</b></span>
                </div>
            </div>

            <div id="cleanup-dryrun-result" style="display:none;margin-top:14px;">
                <div style="font-size:0.78rem;margin-bottom:6px;">Сухой прогон — будет удалено <b id="cleanup-dryrun-count">0</b> диалогов:</div>
                <div id="cleanup-dryrun-list" style="max-height:340px;overflow:auto;font-size:0.7rem;background:var(--bg-input);padding:8px;border-radius:4px;"></div>
            </div>
        </div>
    </div>
            <div class="run-row">
            <div class="d-flex gap-2 align-center" style="margin-top:16px;flex-wrap:wrap;">
                <label class="form-label m-0" data-tip="Сколько акков чистится одновременно. 1 = по очереди, 5-10 = быстрее.">Потоки <span class="text-muted" style="font-size:0.7rem;">?</span></label>
                <input type="number" class="form-control" id="cln-threads" value="1" min="1" max="100" style="width:70px;">
                <button class="btn btn-outline btn-sm" onclick="cleanupPreview()">
                    <i class="bi bi-eye"></i> Сухой прогон (показать что удалится)
                </button>
                <button class="btn btn-accent btn-sm" onclick="cleanupStart()">
                    <i class="bi bi-trash3"></i> Запустить очистку
                </button>
                <button class="btn btn-danger btn-sm" onclick="cleanupStop()" id="btn-cleanup-stop" style="display:none;">
                    <i class="bi bi-stop-fill"></i> Стоп
                </button>
                <span style="flex:1;"></span>
                <button class="btn btn-outline btn-sm" onclick="cleanupLeaveAll()">
                    <i class="bi bi-box-arrow-right"></i> Покинуть всё кроме whitelist <span class="tt tt-left" data-tip="Аккаунт выйдет из всех каналов и групп. Whitelist выше не трогается. Личные диалоги и боты остаются. Полезно перед перепродажей акка или сменой ниши.">?</span>
                </button>
            </div>
            </div>
</div>

<!-- ═══ TAB: Накрутка ═══ -->
<div class="section" id="tab-boost">
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-graph-up-arrow text-accent"></i><div class="ch-text"><div class="ch-title">Накрутка</div><div class="card-sub">накрутка подписчиков и реакций</div></div></div>
        <div class="card-body">
            <div class="info-box" style="margin-bottom:14px;">
                Массовое действие пачкой аккаунтов на одну цель. Подписчики, реакции, голосования, нажатия кнопок, запуск ботов, просмотры.
                <br><b>Защита:</b> Telegram отслеживает массовые действия за короткое время. Рекомендуем не более <b>30-50 аккаунтов в час</b> на одну цель — иначе цель может попасть под анти-накрутку. Жёстких лимитов на нашей стороне нет.
            </div>

            <div class="rd-group"><div class="rd-group-title">ЦЕЛЬ</div>
            <!-- Тип накрутки -->
            <label class="form-label">Тип накрутки</label>
            <select class="form-control mb-3" id="boost-type" onchange="onBoostTypeChange()">
                <option value="subscribers">Подписчики в канал/чат</option>
                <option value="reactions">Реакции на пост</option>
                <option value="polls">Голос в опросе</option>
                <option value="buttons">Нажатие кнопок</option>
                <option value="bots">Запуск ботов</option>
                <option value="views">Просмотры на пост</option>
            </select>

            <!-- Цель -->
            <label class="form-label" id="boost-target-label">Ссылка на канал / @username</label>
            <input type="text" class="form-control mb-3" id="boost-target" placeholder="@channel или t.me/+invite">

            <!-- Тип-специфичные поля -->
            <div id="boost-field-emojis" style="display:none;">
                <label class="form-label">Эможди реакций (через пробел; повторите чтобы выбирались чаще)</label>
                <input type="text" class="form-control mb-3" id="boost-emojis" value="👍 ❤ 🔥" placeholder="👍 ❤ 🔥">
            </div>
            <div id="boost-field-poll" style="display:none;">
                <label class="form-label">Номер варианта (0 = первый, пусто = случайный)</label>
                <input type="number" class="form-control mb-3" id="boost-poll-option" placeholder="случайный" min="0" max="9">
            </div>
            <div id="boost-field-button" style="display:none;">
                <label class="form-label">Кнопка (текст или индекс 0/1/2...)</label>
                <input type="text" class="form-control mb-3" id="boost-button" placeholder="Принять или 0">
            </div>
            </div>

            <div class="rd-group"><div class="rd-group-title">ЛИМИТЫ</div>
            <!-- Общие настройки -->
            <div class="grid-3 mb-3">
                <div>
                    <label class="form-label">Сколько аккаунтов</label>
                    <input type="number" class="form-control" id="boost-count" value="50" min="1" max="9999">
                </div>
                <div>
                    <label class="form-label">Задержка (сек)</label>
                    <input type="text" class="form-control" id="boost-delay" value="5-15" placeholder="5-15">
                </div>
                <div>
                    <label class="form-label">Потоков (параллельно)</label>
                    <input type="number" class="form-control" id="boost-threads" value="1" min="1" max="20">
                </div>
            </div>
            </div>

            <details class="ad-block">
                <summary><i class="bi bi-gear"></i> Дополнительные опции</summary>
                <div class="ad-body">
                    <label class="form-label">Папка аккаунтов (пусто = все живые)</label>
                    <input type="text" class="form-control mb-2" id="boost-folder" placeholder="например: Прогрев / В работе (пусто = все живые)">
                    <label class="ad-check"><input type="checkbox" id="boost-allow-restart"> <span>Разрешить перезапуск ботов<span class="ad-hint">Если у акка уже есть диалог с ботом — запустить /start повторно</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="boost-allow-revote"> <span>Разрешить переголосование в опросах<span class="ad-hint">Если акк уже голосовал — изменить голос</span></span></label>
                </div>
            </details>


            <!-- Прогресс -->
            <div id="boost-progress" style="display:none;margin-top:8px;">
                <div class="progress mb-2-x">
                    <div class="progress-bar" id="boost-progress-bar" style="width:0%;"></div>
                </div>
                <div style="font-size:0.74rem;color:var(--text-muted);" id="boost-progress-text">—</div>
            </div>
        </div>
    </div>
            <div class="run-row">
            <div class="d-flex gap-2 mb-3">
                <button class="btn btn-accent" onclick="startBoost()" id="btn-boost-start">
                    <i class="bi bi-play-fill"></i> Запустить накрутку
                </button>
                <button class="btn btn-danger" onclick="stopBoost()" id="btn-boost-stop" style="display:none;">
                    <i class="bi bi-stop-fill"></i> Остановить
                </button>
                <span id="boost-status-label" class="text-xs text-muted tag-right"></span>
            </div>
            </div>
</div>

<!-- ═══ TAB: Нейрокомменты (beta) ═══ -->
<div class="section" id="tab-neuro-comments">
    <div class="card mb-3">
        <div class="card-header">
            <i class="bi bi-chat-quote text-purple"></i><div class="ch-text"><div class="ch-title">Нейрокомменты</div><div class="card-sub">комментарии под постами в каналах</div></div>
        </div>
        <div class="card-body">
            <div class="info-box info-box--accent" style="margin-bottom:12px;font-size:0.7rem;line-height:1.55;">
                Аккаунты автоматически пишут осмысленные комменты под свежими постами в указанных каналах. Текст генерится AI по теме поста (нужен настроенный <a class="text-accent" href="javascript:showTab('settings')">AI ключ в Настройках</a>).
                <br><b>Защита:</b> один пост — макс N комментов от наших акков, рандомные паузы 2-15 мин между ними, лимит на акк/час и /день.
                <br><b>Условия:</b> у канала должны быть включены комментарии (есть чат для комментариев). Аккаунты должны быть подписаны на канал (можно через инвайтер или модуль Подписка).
            </div>

            <div class="rd-group"><div class="rd-group-title">КАНАЛЫ И АККАУНТЫ</div>
            <label class="form-label">Каналы для комментирования (по одному на строку, @username или t.me/...)</label>
            <textarea class="form-control mb-3" id="nc-channels" rows="5" placeholder="@channel1&#10;@channel2&#10;t.me/channel3" style="font-size:0.78rem;font-family:monospace;"></textarea>

            <label class="form-label">Аккаунты-комментаторы</label>
            <div class="acc-selector mb-3" id="acc-selector-neuro-comments"></div>
            </div>

            <div class="rd-group"><div class="rd-group-title">ОПЦИИ И ЛИМИТЫ</div>
            <details class="ad-block">
                <summary>
                    <i class="bi bi-sliders"></i> Тайминги и лимиты
                </summary>
                <div class="ad-body grid-2">
                    <div>
                        <label class="form-label">Раз в сколько минут проверять каналы <span class="tt" data-tip="Как часто софт заходит в указанные каналы и смотрит новые посты. 5 = каждые 5 минут. Чаще = быстрее реагирует на свежие посты, но больше API-запросов и риск поймать пауза от Telegram.">?</span></label>
                        <input type="number" class="form-control w-100px" id="nc-poll-interval" value="5" min="1" max="60">
                    </div>
                    <div>
                        <label class="form-label">Не комментировать посты старше (сек) <span class="tp-sec-hint" data-for="nc-recency-sec"></span> <span class="tt" data-tip="Посты старше этого возраста не комментируются — даже если их нашли при первом сканировании. 60 = только посты не старше часа. Комментарии под старыми постами выглядят неестественно.">?</span></label>
                        <input type="number" class="form-control w-100px tp-sec" id="nc-recency-sec" value="3600" min="300" max="86400" step="300">
                        <div style="font-size:0.65rem;color:var(--text-muted);margin-top:2px;">Не комментировать посты старше</div>
                    </div>
                    <div>
                        <label class="form-label">Пауза между комментами, от и до (сек) <span class="tp-sec-hint" data-for="ncomm-delay-sec"></span> <span class="tt" data-tip="Пауза между двумя комментариями с одного акка. Софт ждёт случайное время из диапазона. 120-900 сек (2-15 минут) — естественно для живого человека.">?</span></label>
                        <div class="row-gap-6" >
                            <input type="number" class="form-control w-70px tp-sec" id="ncomm-delay-sec" value="120" min="60" max="3600" step="30">
                            <input type="number" class="form-control w-70px tp-sec" id="ncomm-delay-sec-max" value="900" min="120" max="7200" step="30">
                        </div>
                    </div>
                    <div>
                        <label class="form-label">Макс комментов под одним постом <span class="tt" data-tip="Сколько разных аккаунтов оставят коммент под одним и тем же постом. 1 = на каждый пост — один коммент с одного акка. Больше 2-3 выглядит как накрутка.">?</span></label>
                        <input type="number" class="form-control w-100px" id="nc-per-post" value="1" min="1" max="5">
                    </div>
                    <div>
                        <label class="form-label">Лимит на акк / час <span class="tt" data-tip="Сколько комментариев максимум один акк может оставить за последний час. Скользящее окно: софт считает за каждые 60 минут отдельно. 5 — безопасно для живых акков.">?</span></label>
                        <input type="number" class="form-control w-100px" id="nc-per-hour" value="5" min="1" max="60">
                    </div>
                    <div>
                        <label class="form-label">Лимит на акк / день <span class="tt" data-tip="Дневной лимит комментариев с одного акка. 30 = акк перестанет комментировать после 30 за последние 24 часа. Сильная защита от спам-блока.">?</span></label>
                        <input type="number" class="form-control w-100px" id="nc-per-day" value="30" min="1" max="500">
                    </div>
                </div>
            </details>

            <details class="ad-block">
                <summary>
                    <i class="bi bi-megaphone"></i> Своя приписка с рекламой (по желанию)
                </summary>
                <div class="ad-body">
                    <label class="form-label">Своя приписка для нейросети <span class="tt" data-tip="Нейросеть получит этот текст как дополнительное указание. Если комментарий сильно по теме — нейросеть вставит приписку естественно, иначе проигнорирует. Без приписки комментарии будут просто по теме, без рекламы.">?</span></label>
                    <input type="text" class="form-control" id="nc-cta" placeholder="Например: 'если коммент органичен — упомяни канал @mychannel'">
                    
                </div>
            </details>

            <details class="ad-block">
                <summary>
                    <i class="bi bi-code"></i> Свой системный промпт (продвинутое)
                </summary>
                <div class="ad-body">
                    <textarea class="form-control" id="nc-custom-prompt" rows="6" placeholder="Если пусто — используется стандартный промпт для русскоязычных комментов. Доступные плейсхолдеры: {persona}, {cta_block}." style="font-size:0.72rem;font-family:monospace;"></textarea>
                </div>
            </details>
            </div>

            <details class="ad-block">
                <summary><i class="bi bi-shield-check"></i> Защита аккаунта</summary>
                <div class="ad-body">
                    <label class="ad-check"><input type="checkbox" id="nc-pre-spam-check"> <span>Перед стартом проверить аккаунты на спам-блок</span></label>
                    <label class="ad-check"><input type="checkbox" id="nc-solve-captcha"> <span>Решать капчу-боты в чатах для комментариев</span></label>
                    <label class="ad-check"><input type="checkbox" id="nc-keep-online"> <span>Держать аккаунт онлайн во время работы</span></label>
                    <label class="ad-check"><input type="checkbox" id="nc-read-msgs"> <span>Читать пост перед комментированием<span class="ad-hint">Имитация — открыть пост, прокрутить</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="nc-mark-read"> <span>Отмечать сообщения прочитанными</span></label>
                    <label class="ad-check"><input type="checkbox" id="nc-view-profile"> <span>Смотреть профиль автора поста</span></label>
                </div>
            </details>


            <div id="ncomm-counters" style="margin-top:12px;display:none;font-size:0.75rem;line-height:1.7;color:var(--text-muted);"></div>
        </div>
    </div>
            <div class="run-row">
            <div class="d-flex gap-2 align-center">
                <button class="btn btn-accent btn-sm" onclick="ncStart()" id="btn-ncomm-start">
                    <i class="bi bi-play-fill"></i> Запустить
                </button>
                <button class="btn btn-outline btn-sm" onclick="ncStop()" id="btn-ncomm-stop" style="display:none;">
                    <i class="bi bi-stop-fill"></i> Остановить
                </button>
                <span id="ncomm-status-label" class="text-xs text-muted" style="margin-left:8px;"></span>
            </div>
            </div>
</div>

<!-- ═══ TAB: Нейро-чаттер ═══ -->
<div class="section" id="tab-chatter">
    <div class="card mb-3">
        <div class="card-header">
            <i class="bi bi-chat-dots text-accent"></i><div class="ch-text"><div class="ch-title">Нейро-чаттер</div><div class="card-sub">диалоги с аудиторией через AI</div></div>
        </div>
        <div class="card-body">
            <div class="info-box info-box--accent" style="margin-bottom:12px;font-size:0.7rem;line-height:1.55;">
                Аккаунт ведёт живую переписку в ЛС: <b>проактив</b> — сам пишет первым по списку целей; <b>реактив</b> — отвечает на сообщения. Текст генерит AI (нужен настроенный <a class="text-accent" href="javascript:showTab('settings')">AI-ключ в Настройках</a>), с памятью диалога и имитацией человека (печатает, паузы, цитаты).
                <br><b>Только свои диалоги:</b> акк отвечает <u>только</u> тем, кому написал сам (или с кем уже есть переписка). Холодные входящие от чужих игнорируются — защита от ловушек, админов и спамеров.
                <br><b>Защита:</b> дневные/часовые лимиты на акк, спам-блок → акк на 6ч в покой, без ссылок в сообщениях, только живые/прогретые акки.
            </div>

            <div class="rd-group"><div class="rd-group-title">АККАУНТЫ И ЦЕЛИ</div>
            <label class="form-label">Аккаунты-чаттеры (живые/прогретые)</label>
            <div class="acc-selector mb-3" id="acc-selector-chatter"></div>

            <label class="form-label">Цели для проактива (@username по одному на строку — из парсера/списка). Пусто = только реактив по уже существующим своим диалогам.</label>
            <textarea class="form-control mb-3" id="chatter-targets" rows="5" placeholder="@user1&#10;@user2&#10;@user3" style="font-size:0.78rem;font-family:monospace;"></textarea>

            <label class="form-label">Темы диалога (по одной на строку — AI выбирает случайную). Пусто = свободная беседа.</label>
            <textarea class="form-control mb-3" id="chatter-topics" rows="3" placeholder="работа&#10;выходные&#10;хобби" style="font-size:0.78rem;"></textarea>
            </div>

            <details class="ad-block">
                <summary>
                    <i class="bi bi-sliders"></i> Тайминги и лимиты
                </summary>
                <div class="ad-body grid-2">
                    <div>
                        <label class="form-label">Новых диалогов на акк / день <span class="tt" data-tip="Сколько НОВЫХ целей акк напишет первым за сутки (проактив). 8 — безопасно для прогретых. Холодные первые сообщения — самый рискованный момент, не задирай.">?</span></label>
                        <input type="number" class="form-control w-100px" id="chatter-seed-day" value="8" min="0" max="100">
                    </div>
                    <div>
                        <label class="form-label">Пауза между новыми диалогами: <span class="tp-sec-hint" data-for="chatter-seed-sec"></span> <span class="tt" data-tip="Сколько ждать между первыми сообщениями новым собеседникам с одного акка. 1200-5400 сек (20-90 минут) — живой темп, не похожий на рассылку.">?</span></label>
                        <div class="row-gap-6" style="align-items:center;">
                            <span style="font-size:0.72rem;color:var(--text-muted);">от</span>
                            <input type="number" class="form-control w-70px tp-sec" id="chatter-seed-sec" value="1200" min="60" max="36000">
                            <span style="font-size:0.72rem;color:var(--text-muted);">до</span>
                            <input type="number" class="form-control w-70px tp-sec" id="chatter-seed-sec-max" value="5400" min="120" max="86400">
                            <span style="font-size:0.72rem;color:var(--text-muted);">сек</span>
                        </div>
                    </div>
                    <div>
                        <label class="form-label">Ответов на акк / день <span class="tt" data-tip="Дневной лимит ответов с одного акка (реактив). 30 — безопасно. Защита от спам-блока при активной переписке.">?</span></label>
                        <input type="number" class="form-control w-100px" id="chatter-reply-day" value="30" min="1" max="500">
                    </div>
                    <div>
                        <label class="form-label">Ответов на акк / час <span class="tt" data-tip="Скользящий часовой лимит ответов с одного акка. 6 в час — живой человек не строчит без остановки.">?</span></label>
                        <input type="number" class="form-control w-100px" id="chatter-reply-hour" value="6" min="1" max="100">
                    </div>
                    <div>
                        <label class="form-label">Сообщений в один диалог / день <span class="tt" data-tip="Чтобы не задавить одного собеседника — максимум столько НАШИХ сообщений ему за сутки. 4 — нормальный темп переписки.">?</span></label>
                        <input type="number" class="form-control w-100px" id="chatter-dialog-day" value="4" min="1" max="50">
                    </div>
                </div>
            </details>

            <details class="ad-block">
                <summary>
                    <i class="bi bi-person-badge"></i> Персона и стиль (опционально)
                </summary>
                <div class="ad-body">
                    <label class="form-label">Персона (пусто = разная по акку автоматически)</label>
                    <input type="text" class="form-control mb-2" id="chatter-persona" placeholder="Например: парень 27, любит спорт и игры, разговорный стиль">
                    <label class="form-label">Свой системный промпт (продвинутое)</label>
                    <textarea class="form-control" id="chatter-prompt" rows="5" placeholder="Если пусто — стандартный промпт живого собеседника из СНГ. Плейсхолдеры: {persona}, {topic}." style="font-size:0.72rem;font-family:monospace;"></textarea>
                </div>
            </details>

            <details class="ad-block">
                <summary><i class="bi bi-shield-check"></i> Поведение и имитация</summary>
                <div class="ad-body">
                    <label class="ad-check"><input type="checkbox" id="chatter-typing" checked> <span>Показывать «печатает…» перед ответом<span class="ad-hint">+ задержка под длину текста</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="chatter-quote" checked> <span>Иногда отвечать цитатой (reply)</span></label>
                    <label class="ad-check"><input type="checkbox" id="chatter-nolinks" checked> <span>Никогда не отправлять ссылки<span class="ad-hint">Анти-спам-блок</span></span></label>
                    <label class="ad-check"><input type="checkbox" id="chatter-seed-enabled" checked> <span>Проактив (писать первым по целям)<span class="ad-hint">Выкл = только отвечать в своих диалогах</span></span></label>
                </div>
            </details>


            <div id="chatter-counters" style="margin-top:12px;display:none;font-size:0.75rem;line-height:1.7;color:var(--text-muted);"></div>
        </div>
    </div>
            <div class="run-row">
            <div class="d-flex gap-2 align-center" style="margin-top:8px;">
                <button class="btn btn-accent btn-sm" onclick="startChatter()" id="btn-chatter-start">
                    <i class="bi bi-play-fill"></i> Запустить
                </button>
                <button class="btn btn-outline btn-sm" onclick="stopChatter()" id="btn-chatter-stop" style="display:none;">
                    <i class="bi bi-stop-fill"></i> Остановить
                </button>
                <span id="chatter-status-label" class="text-xs text-muted" style="margin-left:8px;"></span>
            </div>
            </div>
</div>

<!-- ═══ TAB: Поддержка ═══ -->
<div class="section" id="tab-support">
    <div class="card mb-3">
        <div class="card-header"><i class="bi bi-life-preserver text-accent"></i><div class="ch-text"><div class="ch-title">Сообщить об ошибке или предложить улучшение</div><div class="card-sub">помощь и контакты</div></div></div>
        <div class="card-body">
            <div style="background:var(--surface-info-bg, #14223a);border:1px solid var(--surface-info-border, #1e3a5f);border-radius:5px;padding:12px;margin-bottom:16px;font-size:0.8rem;color:var(--accent-light);">
                <i class="bi bi-info-circle" style="margin-right:4px;"></i>
                Нашли баг или есть идея как сделать лучше — напишите здесь. Логи и версия прикрепятся автоматически.
                Для бага укажите модуль и что именно не так; для предложения — просто опишите идею.
            </div>

            <label class="form-label">Тип обращения</label>
            <select class="form-control mb-2" id="ticket-type" style="font-size:0.85rem;">
                <option value="bug">Баг / ошибка</option>
                <option value="idea">Предложение / идея</option>
                <option value="question">Вопрос</option>
            </select>

            <label class="form-label">Модуль</label>
            <select class="form-control mb-2" id="ticket-module" style="font-size:0.85rem;">
                <option value="">Выберите модуль</option>
                <option value="spam">Рассылка по чатам</option>
                <option value="dm">Личные сообщения</option>
                <option value="join">Подписка на чаты</option>
                <option value="multi">Мульти-аккаунт</option>
                <option value="parser">Парсинг юзеров</option>
                <option value="warmup">Прогрев аккаунтов</option>
                <option value="profiles">Заполнение профиля</option>
                <option value="autoreply">Автоответчик</option>
                <option value="inviter">Инвайтер</option>
                <option value="monitoring">Мониторинг чатов</option>
                <option value="analytics">Аналитика</option>
                <option value="cleanup">Очистка ТГ</option>
                <option value="boost">Накрутка</option>
                <option value="neurocomments">Нейрокомменты</option>
                <option value="activity">Имитация активности</option>
                <option value="accounts">Аккаунты</option>
                <option value="telegram">Telegram-просмотр</option>
                <option value="proxy">Прокси</option>
                <option value="settings">Настройки</option>
                <option value="update">Обновление</option>
                <option value="login">Авторизация/Лицензия</option>
                <option value="other">Другое</option>
            </select>

            <label class="form-label">Тема</label>
            <input type="text" class="form-control mb-2" id="ticket-subject" placeholder="Кратко: что не работает">

            <label class="form-label">Описание <span style="color:var(--text-muted);font-weight:normal;">— для бага необязательно, главное скриншот</span></label>
            <textarea class="form-control mb-2" id="ticket-body" rows="2" placeholder="Если на скрине не всё видно — пара слов (необязательно)"></textarea>

            <label class="form-label" style="font-weight:600;">Скриншот <span style="color:var(--danger);">(обязателен для бага — по нему и разбираем)</span></label>
            <div class="mb-3" >
                <label style="display:flex;align-items:center;gap:8px;padding:12px;border:2px dashed #252540;border-radius:5px;cursor:pointer;transition:border-color 0.2s;" onmouseover="this.style.borderColor='var(--accent)'" onmouseout="this.style.borderColor='#252540'">
                    <i class="bi bi-image" style="font-size:1.2rem;color:var(--accent-light);"></i>
                    <span style="font-size:0.82rem;color:var(--text-muted);">Нажмите чтобы прикрепить скриншот (PNG/JPG; для бага обязателен)</span>
                    <input type="file" id="ticket-screenshot" accept="image/*" style="display:none;" onchange="previewTicketImg(this)">
                </label>
                <div id="ticket-img-preview" style="display:none;margin-top:8px;position:relative;">
                    <img id="ticket-img-thumb" style="max-width:200px;max-height:150px;border-radius:5px;border:1px solid #252540;">
                    <button onclick="clearTicketImg()" data-tip="Удалить скриншот" style="position:absolute;top:-6px;right:-6px;background:var(--danger);border:none;border-radius:50%;width:20px;height:20px;color:#fff;font-size:0.7rem;cursor:pointer;display:flex;align-items:center;justify-content:center;"><i class="bi bi-x"></i></button>
                </div>
            </div>

            <div class="d-flex gap-2 flex-wrap">
                <button class="btn btn-accent btn-sm" onclick="sendTicket()" id="btn-send-ticket">
                    <i class="bi bi-send"></i> Отправить
                </button>
                <button class="btn btn-outline btn-sm" onclick="copyDiagInfo(this)" data-tip="Скопировать в буфер обмена техническую информацию для поддержки">
                    <i class="bi bi-clipboard-data"></i> Скопировать диагностику
                </button>
                <span class="text-xs text-muted self-center">Логи и версия прикрепляются автоматически</span>
            </div>
            <div id="ticket-result" style="display:none;margin-top:10px;font-size:0.82rem;"></div>
        </div>
    </div>
</div>

<!-- ═══ TAB: Монитор аккаунтов ═══ -->
<!-- Пассивное наблюдение. Ни одного обращения к Telegram: карточки собираются
     из событий, которые модули уже испустили (core/infra/monitor_bus.py). -->
<div class="section" id="tab-accmon">
    <div class="card mb-3">
        <div class="card-header">
            <i class="bi bi-grid-1x2 text-accent"></i>
            <div class="ch-text">
                <div class="ch-title">Монитор аккаунтов</div>
                <div class="card-sub">видно, что происходит на каждом аккаунте прямо сейчас</div>
            </div>
        </div>
        <div class="card-body">
            <div id="accmon-toolbar" style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:14px;">
                <button type="button" class="am-chip" data-f="all" aria-pressed="true">Все <span class="am-cnt">0</span></button>
                <button type="button" class="am-chip" data-f="work" aria-pressed="false">В работе <span class="am-cnt">0</span></button>
                <button type="button" class="am-chip" data-f="bad" aria-pressed="false">С проблемой <span class="am-cnt">0</span></button>
                <span style="flex:1;"></span>
                <span id="accmon-live" style="display:inline-flex;align-items:center;gap:8px;font-size:0.7rem;color:var(--text-muted);">
                    <span class="am-pulse"></span><span id="accmon-live-text">подключаюсь…</span>
                </span>
            </div>

            <div id="accmon-empty" style="padding:34px 16px;text-align:center;color:var(--text-muted);font-size:0.82rem;line-height:1.6;">
                Аккаунтов пока нет. Добавьте их на вкладке «Аккаунты» — и здесь появятся карточки
                с тем, что на каждом происходит.
            </div>

            <div id="accmon-grid" class="am-grid"></div>

            <div id="accmon-stage" class="am-stage" style="display:none;">
                <div class="am-pane">
                    <div class="am-ph">
                        <span class="am-ava" id="accmon-ava">—</span>
                        <div>
                            <b id="accmon-title">—</b>
                            <span class="am-s" id="accmon-sub">—</span>
                        </div>
                        <span class="am-rt" id="accmon-rt"></span>
                    </div>
                    <div class="am-chat" id="accmon-chat"></div>
                    <div class="am-steps-cap">
                        <span>шаги — высота столбика это время ответа</span>
                        <span id="accmon-cap"></span>
                    </div>
                    <div class="am-steps" id="accmon-steps"></div>
                </div>
                <div class="am-pane">
                    <div class="am-ph"><b>Что происходит</b></div>
                    <div class="am-tele">
                        <div id="accmon-verd"></div>
                        <dl class="am-kv" id="accmon-kv"></dl>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

{% endblock %}

{% block extra_js %}
<script src="https://cdn.jsdelivr.net/npm/chart.js@4"></script>
<script>
// ── Range sliders live update ──
document.querySelectorAll('.range-slider').forEach(function(s) {
    var valEl = document.getElementById('v-' + s.id.replace('s-', ''));
    if (valEl) {
        s.addEventListener('input', function() { valEl.textContent = s.value; });
    }
});

// ── Drop zone click (если есть) ──
(function(){
    var dz = document.getElementById('session-drop');
    var si = document.getElementById('session-input');
    if (dz && si) dz.addEventListener('click', function() { si.click(); });
})();

// ── Join links counter ──
(function(){
    var ta = document.getElementById('join-links');
    if (!ta) return;
    function updateCount() {
        var lines = ta.value.split('\n').filter(function(l) { return l.trim(); });
        var el = document.getElementById('join-count');
        var btn = document.getElementById('btn-join');
        if (el) el.textContent = lines.length;
        if (btn) btn.disabled = lines.length === 0;
    }
    ta.addEventListener('input', updateCount);
    ta.addEventListener('paste', function() { setTimeout(updateCount, 10); });
    ta.addEventListener('change', updateCount);
    ta.addEventListener('keyup', updateCount);
    updateCount();
})();

// ── Parser chat change ──
document.getElementById('parser-chat').addEventListener('change', function() {
    updateChatPreview();
});

// ── Init ──
refreshStatus();
</script>
{% endblock %}