diff --git a/docs/docs/CHANGELOG.md b/docs/docs/CHANGELOG.md
index 145efa1..b159a1b 100644
--- a/docs/docs/CHANGELOG.md
+++ b/docs/docs/CHANGELOG.md
@@ -22,6 +22,7 @@ Anubis now supports these new languages:
- [Czech](https://github.com/TecharoHQ/anubis/pull/849)
- [Finnish](https://github.com/TecharoHQ/anubis/pull/863)
+- [Russian](https://github.com/TecharoHQ/anubis/pull/882)
Anubis now supports the [`missingHeader`](./admin/configuration/expressions.mdx#missingHeader) to assert the absence of headers in requests.
diff --git a/lib/localization/locales/manifest.json b/lib/localization/locales/manifest.json
index 014592e..cf80a2e 100644
--- a/lib/localization/locales/manifest.json
+++ b/lib/localization/locales/manifest.json
@@ -12,6 +12,7 @@
"it",
"ja",
"pt-BR",
+ "ru",
"tr",
"zh-CN",
"zh-TW"
diff --git a/lib/localization/locales/ru.json b/lib/localization/locales/ru.json
new file mode 100644
index 0000000..629fe97
--- /dev/null
+++ b/lib/localization/locales/ru.json
@@ -0,0 +1,64 @@
+{
+ "loading": "Загрузка...",
+ "why_am_i_seeing": "Почему я вижу это?",
+ "protected_by": "Защищено",
+ "protected_from": "От",
+ "made_with": "Сделано с ❤️ из 🇨🇦",
+ "mascot_design": "Дизайн маскота от",
+ "ai_companies_explanation": "Вы это видите, потому что администратор этого сайта настроил Anubis для защиты сервера от атак, использующих ИИ, которые агрессивно копируют данные с сайтов. Это может привести к зависанию сайтов и делает их ресурсы недоступными для всех.",
+ "anubis_compromise": "Anubis - это компромисс. Anubis использует Proof-of-Work, похожую на Hashcash, для борьбы со спамом в электронной почте. Идея в том, что на отдельных уровнях дополнительная нагрузка не влиятельна, но на уровне массового парсинга она накапливается и значительно удорожает сбор данных.",
+ "hack_purpose": "В реальности, это хак, у которого настоящая цель - предоставить «достаточно хорошее» решение, чтобы можно было потратить больше времени на идентификацию headless-браузеров (например, по тому, как они выполняют отрисовку шрифтов), чтобы не отображать страницу с подтверждением пользователям, которые с гораздо большей вероятностью являются настоящими.",
+ "jshelter_note": "Anubis требует использования современных функций JavaScript, которые плагины, по типу JShelter, отключают. Пожалуйста, отключите JShelter и другие подобные плагины для этого домена.",
+ "version_info": "На сайте запущен Anubis версии",
+ "try_again": "Попробуйте снова",
+ "go_home": "Перейти на домашнюю",
+ "contact_webmaster": "если вы уверены, что это ошибка, свяжитесь с владельцем сайта через",
+ "connection_security": "Пожалуйста, подождите, пока мы проверим безопасность вашего соединения.",
+ "javascript_required": "К сожалению, для решения этой проверки необходимо включить JavaScript. Это необходимо, поскольку компании, занимающиеся разработкой ИИ, изменили моральные правила, касающийся хостинга веб-сайтов. Решение без использования JavaScript находится в стадии разработки.",
+ "benchmark_requires_js": "Для работы тестирования необходимо включить JavaScript.",
+ "difficulty": "Сложность:",
+ "algorithm": "Алгоритм:",
+ "compare": "Сравнить:",
+ "time": "Время",
+ "iters": "Итерации",
+ "time_a": "Время A",
+ "iters_a": "Итерации A",
+ "time_b": "Время B",
+ "iters_b": "Итерации B",
+ "static_check_endpoint": "Это всего лишь точка проверки, которую может использовать ваш обратный прокси-сервер.",
+ "authorization_required": "Требуется авторизация.",
+ "cookies_disabled": "В вашем браузере отключены cookie файлы. Anubis требует их для подтверждения того, что вы являетесь настоящим человеком. Пожалуйста, включите файлы cookie для этого домена",
+ "access_denied": "Доступ запрещён: код ошибки",
+ "dronebl_entry": "DroneBL сообщил о записи",
+ "see_dronebl_lookup": "см.",
+ "internal_server_error": "Внутренняя ошибка сервера: администратор неправильно настроил Anubis. Обратитесь к администратору и попросите его просмотреть логи",
+ "invalid_redirect": "Неверное перенаправление",
+ "redirect_not_parseable": "URL-адрес перенаправления не может быть анализирован",
+ "redirect_domain_not_allowed": "Перенаправление домена запрещено",
+ "failed_to_sign_jwt": "не смог подписать JWT",
+ "invalid_invocation": "Неверный вызов MakeChallenge",
+ "client_error_browser": "Ошибка клиента: убедитесь, что у вас браузер новейшей версии, и повторите попытку позже.",
+ "oh_noes": "О нет!",
+ "benchmarking_anubis": "Анализ Анубиса!",
+ "you_are_not_a_bot": "Вы не бот!",
+ "making_sure_not_bot": "Проверяем, что вы не бот!",
+ "celphase": "CELPHASE",
+ "js_web_crypto_error": "В вашем браузере отсутствует функция web.crypto. Вы просматриваете страницу через защищённый контекст?",
+ "js_web_workers_error": "Ваш браузер не поддерживает web worker (Anubis использует его, чтобы избежать зависания браузера). У вас установлен плагин типа JShelter?",
+ "js_cookies_error": "Ваш браузер не сохраняет cookie файлы. Anubis использует их для определения клиентов, прошедших проверку, сохраняя подписанный токен в файле cookie. Включите сохранение файлов cookie для этого домена. Имена файлов cookie, хранимых Anubis, могут изменяться без предварительного уведомления. Имена и значения cookie файлов не являются частью общедоступного API.",
+ "js_context_not_secure": "Ваш контекст небезопасен!",
+ "js_context_not_secure_msg": "Попробуйте подключиться по HTTPS или попросите администратора, чтобы он настроил HTTPS. Подробнее см. MDN.",
+ "js_calculating": "Расчёт...",
+ "js_missing_feature": "Отсутствует функция",
+ "js_challenge_error": "Ошибка проверки!",
+ "js_challenge_error_msg": "Не удалось определить алгоритм проверки. Возможно, нужно перезагрузить страницу..",
+ "js_calculating_difficulty": "Расчёт...
Сложность:",
+ "js_speed": "Скорость:",
+ "js_verification_longer": "Проверка занимает больше времени, чем ожидалось. Пожалуйста, не обновляйте страницу.",
+ "js_success": "Успех!",
+ "js_done_took": "Получилось! Заняло",
+ "js_iterations": "итераций",
+ "js_finished_reading": "Я дочитал, продолжить →",
+ "js_calculation_error": "Ошибка расчёта!",
+ "js_calculation_error_msg": "Не удалось рассчитать задачу:"
+}
\ No newline at end of file
diff --git a/lib/localization/localization_test.go b/lib/localization/localization_test.go
index 5e7abf0..b8e1b83 100644
--- a/lib/localization/localization_test.go
+++ b/lib/localization/localization_test.go
@@ -23,6 +23,7 @@ func TestLocalizationService(t *testing.T) {
"is": "Hleður...",
"pt-BR": "Carregando...",
"tr": "Yükleniyor...",
+ "ru": "Загрузка...",
"zh-CN": "加载中...",
"zh-TW": "載入中...",
}
@@ -57,7 +58,7 @@ func TestLocalizationService(t *testing.T) {
}
type manifest struct {
- SupportedLanguages []string `json:"supported_languages"`
+ SupportedLanguages []string `json:"supportedLanguages"`
}
func loadManifest(t *testing.T) manifest {
@@ -98,6 +99,11 @@ func TestComprehensiveTranslations(t *testing.T) {
sort.Strings(keys)
+ manifest := loadManifest(t)
+ if len(manifest.SupportedLanguages) == 0 {
+ t.Fatal("no languages loaded")
+ }
+
for _, lang := range loadManifest(t).SupportedLanguages {
t.Run(lang, func(t *testing.T) {
loc := service.GetLocalizer(lang)