TreeMap
A free, open-source disk-space visualizer. Squarified treemap, duplicate hunting, disk-full forecasting, and cleanup that only ever moves files to the Trash.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Доступ только для платных клиентов после входа. Клиентская запись в текущей модели означает платный пакет. Требуются настроенный пароль и действующий токен. Гостям, неизвестным клиентам и клиентам без пароля доступ закрыт до вызова Gemini. Шаблоны выдаются через защищённый /api/translation-templates; исходные JSON перенесены в lib/translation-templates/. Бесплатные лимиты перевода больше не используются. Изменение вступает в силу после развёртывания кода.檢視完整 README ↗
Доступ только для платных клиентов после входа. Клиентская запись в текущей
модели означает платный пакет. Требуются настроенный пароль и действующий токен.
Гостям, неизвестным клиентам и клиентам без пароля доступ закрыт до вызова Gemini.
Шаблоны выдаются через защищённый /api/translation-templates; исходные JSON
перенесены в lib/translation-templates/. Бесплатные лимиты перевода больше
не используются. Изменение вступает в силу после развёртывания кода.
Начальные образцы доступны в списке «Выбрать черновой образец…»: паспорт /
удостоверение личности, свидетельство о рождении, свидетельство о браке,
диплом / аттестат и справка с места работы. Все пять — на английском языке,
версия v1, без привязки к конкретному государственному бланку. Подписи требуют
проверки переводчиком. JSON-файлы находятся в lib/translation-templates/.
После выбора можно скачать текущий шаблон либо настроить и сохранить свою
копию; встроенный образец при этом не меняется. Дополнительный текст и поля
сохраняются. Шаблон справки с работы использует примерный признак «работ»;
для другой формулировки/языка оригинала настройте признак в редакторе.
После распознавания в панели результатов доступен перевод на русский, кыргызский, английский, казахский, узбекский, турецкий, китайский и немецкий. Выберите документ и язык, затем нажмите «Перевести». Исходные результаты не меняются. Перевод можно исправить, продолжить после ошибки и скачать в TXT/DOCX/PDF. PDF сразу скачивается без открытия отдельного окна. Это машинный перевод для последующей проверки. Предупреждение о машинном переводе показывается только в интерфейсе, а не в скачанном DOCX/PDF/TXT-документе.
В интерфейсе результата также показывается применимое регуляторное правило. Для апостиля используется Гаагская конвенция от 5 октября 1961 года. Для паспорта, свидетельств, дипломов и остальных документов показываются требования принимающего органа или страны назначения: это информационная подсказка, а не юридическое заверение. Перед подачей пользователь должен проверить необходимость апостиля, консульской легализации, нотариального заверения или заверения переводчика.
«Настроить шаблон» позволяет задать переведённые подписи, порядок и обязательность полей, а также значения, которые не нужно переводить. Необязательная фраза из оригинала служит признаком версии формы. Шаблон сохраняется в JSON-файл без значений документа и затем загружается кнопкой «Загрузить шаблон». Если тип, язык, обязательные поля или признак формы не совпадают, используется исходная структура. Поля вне шаблона и полный текст не удаляются.
Перед переводом показывается число новых символов. Успешные фрагменты повторно используются только в текущей вкладке. При изменении оригинала экспорт старого перевода блокируется; повторный запуск использует неизменённые фрагменты. Перевод отправляет распознанный текст на сервер и Gemini даже после локального OCR. Автоматического долговременного хранения нет.
Серверный /api/translate принимает { language, segments: [{ id, text }], clientSlug? },
до 50 фрагментов и 2000 символов суммарно. Для защищённого клиента требуется
x-client-token; непубличные ключи остаются на сервере. Отдельные лимиты
TAMGA_TRANSLATION_* описаны в .env.example; это старый поток перевода
сегментов и он не списывает OCR-страницы. Новый /api/translation-docs списывает
одну единицу за изображение и по одной единице за каждую страницу PDF до вызова
Gemini: PDF из трёх страниц расходует три единицы тарифа.
Используется существующий атомарный consume_feedback_attempt с отдельными
ключами translation: и окнами 24 часа / 30 дней. Миграция БД не требуется.
Сбой учёта блокирует перевод; попытки, завершившиеся ошибкой модели, также
учитываются. В лог translation.usage попадают только модель и числа токенов.
Ограничения первого выпуска: экспорт сохраняет доступные абзацы и извлечённые
таблицы, а не точную вёрстку скана. «Оригинал» в экспорте — распознанные данные.
Заверенных форм нет; начальные образцы являются черновиками. DOCX и браузерную печать необходимо визуально
проверить перед выпуском. Проверка кода: npm run test:translation (также в npm test).
Веб-интерфейс обрабатывает страницы конвейером: распознавание начинается
с первой готовой страницы, пока следующие PDF-страницы или фотографии ещё
подготавливаются. В памяти остаются активные страницы и максимум одна
подготовленная в ожидании. Порядок результатов соответствует исходному
порядку страниц. Отмена останавливает подготовку и текущий PDF-рендер;
ошибка отдельной страницы не удаляет результаты остальных.
Проверка конвейера: npm run test:pages.
Автоматическое распознавание выполняется в два этапа: первый запрос Gemini
возвращает только тип документа, второй извлекает поля, строки таблицы и,
если включён includeText, полный текст по схеме определённого типа.
При заданном docType выполняется один запрос. Лимит страниц списывается
один раз на вызов распознавания; токены и задержка учитывают оба этапа.
Ошибка классификации или второго этапа возвращается как ошибка распознавания.
Для нетабличных документов автоматический режим теперь тоже требует два
запроса и может работать медленнее. Проверка точности на реальных документах:
npm run eval (см. eval/README.md).
Распознавание и извлечение структурированных данных из кыргызских и русских документов (паспорта, справки, договоры, банковские документы и т.д.).
Прод: https://tamga-souverigh.vercel.app
public/index.html — весь фронтенд (один файл): загрузка файлов, офлайн-
режим (Tesseract.js, полностью в браузере) и вызов
Gemini-режима через собственный бекенд
api/recognize.js — эндпоинт для веб-интерфейса Тамги (без ключа,
вызывается тем же сайтом)
api/v1/recognize.js — публичный API для внешних интеграций (1С и т.п.),
требует заголовок x-api-key
lib/recognize.js — общая логика вызова Gemini (ключ читается только
из process.env.GEMINI_API_KEY на сервере)
lib/docSchema.js — типы документов и поля извлечения (используется
бекендом; в public/index.html есть своя копия для
офлайн-эвристики Tesseract-режима)
lib/apiKeyAuth.js — проверка x-api-key для публичного API
Это обычный статический сайт + Vercel Functions — фреймворк (Next.js и т.п.)
не используется, api/*.js подхватывается Vercel автоматически по
соглашению об именах файлов.
Раньше пользователь сам вставлял свой Gemini API-ключ в браузере — ключ уходил напрямую в Google с клиента. Теперь:
GEMINI_API_KEY на
Vercel и никогда не передаётся в браузер./api/recognize на этом же домене./api/v1/recognize для внешних систем
(1С и подобные), защищённый ключом x-api-key.Главная без ?client= всегда использует бесплатный тариф: 3 страницы
распознавания через сервер в день на IP-адрес. Сохранённый в браузере slug
больше не подставляется. Неизвестный slug также использует бесплатный лимит.
При недоступности учёта бесплатное распознавание временно возвращает 503.
Локальный режим «Только текст» работает в браузере и сервером не учитывается.
Кнопка настроек показывается для явного ?client=admin и клиентов,
зарегистрированных в базе. В текущей модели тарифа зарегистрированная запись
означает клиентский пакет: page_limit задаёт объём, null — безлимит.
Клиент видит остаток пакета при открытии страницы и после завершения обработки.
Вход на страницы всех клиентов, в их настройки и в /admin сбрасывается
после 60 минут бездействия в текущей вкладке. Движение указателя, нажатия
и прокрутка на видимой странице продлевают сессию; фоновые запросы и
перезагрузка страницы — нет. При возврате после сна срок проверяется снова.
Ключ/токен удаляется из sessionStorage, страница перезагружается и запрашивает
пароль, если он задан. Старые сохранённые входы без отметки активности требуют
повторного входа. Клиенты без пароля по-прежнему доступны без входа.
Это выход в браузере; серверный срок действия токена остаётся отдельным ограничением.
Настройки используют тот же вход, что и клиентская страница, без отдельной
формы пароля. Если сервер отклоняет сессию, настройки возвращают на
/?client=slug для входа. Для клиента без заданного пароля настройки
показывают пояснение о необходимости настроить пароль доступа.
Проверка таймера с управляемыми часами: node --test scripts/test-idle-session.cjs.
npm i -g vercel # если ещё не установлен
cp .env.example .env
# впишите GEMINI_API_KEY и TAMGA_API_KEYS в .env
vercel dev
Проект уже привязан к Vercel-аккаунту souverigh, проект tamga.
vercel --prod
Либо подключите этот репозиторий к Vercel через Git-интеграцию (Project → Settings → Git) — тогда деплой будет идти автоматически на каждый push в основную ветку.
Обязательно задайте переменные окружения в Vercel (Project → Settings → Environment Variables), иначе бекенд ответит ошибкой 500:
| Переменная | Обязательна | Назначение |
|---|---|---|
GEMINI_API_KEY | да | Ключ Google AI Studio для режима Gemini |
TAMGA_API_KEYS | для API | Ключи клиентов через запятую, для /api/v1/* |
POST /api/v1/recognizeHeaders:
Content-Type: multipart/form-data (рекомендуется) или application/json
x-api-key: <ваш ключ из TAMGA_API_KEYS>
Multipart fields:
image: файл
mimeType: image/png (необязательно, берётся из файла)
docType: ... (необязательно)
Для обратной совместимости JSON-вариант остаётся доступен:
{ "image": "<base64>", "mimeType": "image/png" }
Response 200:
{ "documentType": "Справка", "text": "...", "fields": [{"label": "...", "value": "..."}] }
Поддерживаемые mimeType: image/png, image/jpeg, image/webp,
application/pdf (PDF передаётся Gemini целиком, без постраничной разбивки
на сервере — для многостраничных PDF это может работать хуже, чем
пословный по страницам режим в веб-интерфейсе).
Пример через curl:
base64 -w0 document.png > doc.b64
curl -X POST https://tamga-souverigh.vercel.app/api/v1/recognize \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_KEY" \
-d "{\"image\": \"$(cat doc.b64)\", \"mimeType\": \"image/png\"}"
Ключи выдаются вручную — добавьте новый ключ в TAMGA_API_KEYS в Vercel и
поделитесь им с клиентом. Учёта запросов пока нет (см. ниже).
TAMGA_API_KEYS — просто список
валидных строк, без привязки к клиенту и без счётчика запросов. Это
осознанно отложено. Когда понадобится — единственное место для замены на
Supabase-таблицу api_keys (клиент, лимит, счётчик) — lib/apiKeyAuth.js,
остальной код трогать не придётся. Аналогичный паттерн (Supabase +
SECURITY DEFINER функция) уже используется в проекте «Хаво».GEMINI_API_KEY без разделения
затрат по клиентам./api/v1/recognize передаётся Gemini целиком, без постраничной
разбивки (в отличие от веб-интерфейса, где PDF.js рендерит каждую
страницу отдельно на клиенте перед отправкой).tamga_handover.pdf).Полная история решений (почему Tesseract v2.1.5, почему gemini-3.6-flash,
формат дат День.Месяц, баг с пустым PDF-экспортом и его фикс) — см.
tamga_handover.pdf в исходном чате. Этот README описывает только то, что
изменилось при добавлении бекенда.
В модуле «Перевод» экспортируемый документ содержит только перевод. Оригинальные
значения доступны в интерфейсе сверки и не добавляются в скачиваемый .docx,
.txt или .pdf.
Для апостиля используется отдельный шаблон с заголовком APOSTILLE, ссылкой на
Гаагскую конвенцию 5 октября 1961 года и десятью пронумерованными пунктами.
В шаблон подставляются только распознанные и переведённые значения апостиля.
PDF формируется в браузере и сразу скачивается, без открытия отдельного окна.
Имена в апостиле транслитерируются по общей таблице для английского, китайского
и других поддерживаемых языков латинского письма. Уже латинское написание
сохраняется. Числовые даты приводятся к ДД-ММ-ГГГГ, номера и идентификаторы
не передаются модели для перевода. Исходные распознанные значения остаются
доступны в сравнении с оригиналом. Статусы: перевод — зелёный, транслитерация —
фиолетовый, без изменений — серый; изменение формата даты отмечается зелёным.
Экспорт проверяет структуру из десяти пунктов, отдельно от двух заголовков,
и сравнивает имена, даты и номера с результатом тех же правил, которые использует
сервер. Word и PDF используют шапку в рамке и одну таблицу с десятью пунктами,
включая подпись. «This public document» и «Certified» выводятся отдельными
непронумерованными строками после пунктов 1 и 4 соответственно.
Текст печати размещается
под таблицей. Регрессионные тесты покрывают путь
client-recognize → buildExportDocs → DOCX/TXT и вызов сохранения PDF.
Структурная основа — образец апостиля HCCH. Формат даты и латинское представление имён в китайском переводе — настройки этого модуля по предоставленному образцу, а не универсальные требования HCCH. Автоматическая транслитерация не подтверждает написание имени по паспорту.
Для апостиля выполняется дополнительное независимое чтение имён, даты и номера с исходного изображения. Первый вариант модели не передаётся. Расхождения, уверенность ниже 90 или неудачная проверка требуют ручной сверки перед экспортом: в окне сравнения показываются оба чтения и отметка «Сверено с оригиналом». После изменения значения подтверждение сбрасывается. Повторный вызов модели учитывается в расходе токенов, но не списывает ещё одну страницу пакета. Совпадение двух чтений не гарантирует правильность распознавания почерка.