diff --git a/web/i18n/ru/a11y/dialog.json b/web/i18n/ru/a11y/dialog.json
new file mode 100644
index 00000000..ea7c32ce
--- /dev/null
+++ b/web/i18n/ru/a11y/dialog.json
@@ -0,0 +1,5 @@
+{
+ "picker.item.photo": "превью фотографии",
+ "picker.item.video": "превью видео",
+ "picker.item.gif": "превью gif"
+}
diff --git a/web/i18n/ru/a11y/donate.json b/web/i18n/ru/a11y/donate.json
new file mode 100644
index 00000000..93561b71
--- /dev/null
+++ b/web/i18n/ru/a11y/donate.json
@@ -0,0 +1,4 @@
+{
+ "share.qr.expand": "qr-код. нажми, чтобы развернуть.",
+ "share.qr.collapse": "развёрнутый qr-код. нажми, чтобы свернуть."
+}
diff --git a/web/i18n/ru/a11y/queue.json b/web/i18n/ru/a11y/queue.json
new file mode 100644
index 00000000..3921c99b
--- /dev/null
+++ b/web/i18n/ru/a11y/queue.json
@@ -0,0 +1,5 @@
+{
+ "status.completed": "очередь обработки. все задачи завершены.",
+ "status.ongoing": "очередь обработки. есть текущие задачи.",
+ "status.default": "очередь обработки"
+}
diff --git a/web/i18n/ru/a11y/save.json b/web/i18n/ru/a11y/save.json
index d6def5e5..5cf07427 100644
--- a/web/i18n/ru/a11y/save.json
+++ b/web/i18n/ru/a11y/save.json
@@ -1,9 +1,12 @@
{
- "link_area": "зона вставки ссылки",
- "clear_input": "clear input",
+ "link_area": "область ввода ссылки",
+ "clear_input": "очистить поле ввода",
"download": "скачать",
"download.think": "обрабатываю ссылку...",
"download.check": "проверяю загрузку...",
- "download.done": "загрузка завершена!",
- "download.error": "ошибка загрузки"
+ "download.done": "загрузка завершена",
+ "download.error": "ошибка загрузки",
+ "link_area.turnstile": "область ввода ссылки. проверяю, что ты не робот.",
+ "tutorial.shortcut.photos": "добавить команду \"в фото\"",
+ "tutorial.shortcut.files": "добавить команду \"в файлы\""
}
diff --git a/web/i18n/ru/about.json b/web/i18n/ru/about.json
new file mode 100644
index 00000000..8a5f758a
--- /dev/null
+++ b/web/i18n/ru/about.json
@@ -0,0 +1,37 @@
+{
+ "page.general": "что такое кобальт?",
+ "heading.general": "общие условия",
+ "heading.saving": "скачивание",
+ "heading.encryption": "шифрование",
+ "heading.abuse": "сообщение о злоупотреблении",
+ "heading.motivation": "мотивация",
+ "heading.licenses": "лицензии",
+ "heading.summary": "лучший способ сохранять то, что ты любишь",
+ "heading.privacy": "",
+ "page.faq": "",
+ "page.community": "сообщество и поддержка",
+ "page.privacy": "конфиденциальность",
+ "page.terms": "условия и этика",
+ "page.credits": "благодарности и лицензии",
+ "community.discord": "",
+ "community.twitter": "",
+ "community.github": "",
+ "community.email": "",
+ "community.telegram": "",
+ "heading.testers": "бета-тестеры",
+ "heading.community": "открытое сообщество",
+ "heading.local": "обработка на устройстве",
+ "heading.plausible": "анонимная аналитика трафика",
+ "heading.cloudflare": "веб-приватность и безопасность",
+ "heading.responsibility": "ответственности пользователя",
+ "support.github": "смотри исходный код кобальта, вноси свой вклад или сообщай о проблемах",
+ "support.discord": "общайся с сообществом и разработчиками кобальта или попроси о помощи",
+ "support.description.issue": "если ты хочешь сообщить о баге или какой-то другой повторяющейся проблеме, то делай это на github.",
+ "support.description.help": "используй discord для любых других вопросов. чётко опиши проблему в #cobalt-support, иначе никто не сможет тебе помочь.",
+ "support.twitter": "следи за обновлениями и разработкой кобальта в своей ленте твиттера",
+ "support.telegram": "следи за обновлениями кобальта в телеграм-канале",
+ "support.description.best-effort": "вся поддержка осуществляется по мере возможности и не гарантируется, а ответ может занять какое-то время.",
+ "heading.privacy_efficiency": "лучшая приватность и эффективность",
+ "heading.partners": "партнёры",
+ "support.bluesky": "следи за обновлениями и разработкой кобальта в своей ленте bluesky"
+}
diff --git a/web/i18n/ru/about/credits.md b/web/i18n/ru/about/credits.md
new file mode 100644
index 00000000..a58bd223
--- /dev/null
+++ b/web/i18n/ru/about/credits.md
@@ -0,0 +1,94 @@
+
+
+
+
+
+кобальт сделан с любовью и заботой руками [imput](https://imput.net/) ❤️
+
+мы маленькая команда из двух человек, но мы очень усердно работаем, чтобы делать
+классный софт, который приносит пользу всем. если тебе нравится то, что мы
+делаем, поддержи нас на [странице донатов](/donate)!
+
+
+
+
+
+огромное спасибо нашим тестерам за то, что они тестировали обновления заранее и
+следили за их стабильностью. они ещё помогли нам выпустить cobalt 10!
+
+
+все ссылки внешние и ведут на их личные сайты или соцсети.
+
+
+
+
+
+часть инфраструктуры кобальта предоставлена нашим давним партнёром,
+[royalehosting.net]({partners.royalehosting})!
+
+
+
+
+
+мяубальт — это шустрый маскот кобальта, очень выразительный кот, который любит
+быстрый интернет.
+
+весь потрясающий арт мяубальта, который ты видишь в кобальте, был сделан
+[GlitchyPSI](https://glitchypsi.xyz/). он ещё и оригинальный создатель этого
+персонажа.
+
+imput владеет юридическими правами на дизайн персонажа мяубальта, но не на
+конкретные арты, которые были созданы GlitchyPSI.
+
+мы любим мяубальта, поэтому мы вынуждены установить пару правил, чтобы его
+защитить:
+- ты не можешь использовать дизайн персонажа мяубальта ни в какой форме, кроме
+ фанарта.
+- ты не можешь использовать дизайн или арты мяубальта в коммерческих целях.
+- ты не можешь использовать дизайн или арты мяубальта в своих проектах.
+- ты не можешь использовать или изменять работы GlitchyPSI с мяубальтом ни в
+ каком виде.
+
+если ты нарисуешь фанарт мяубальта, не стесняйся делиться им в [нашем
+дискорд-сервере](/about/community), мы с нетерпением ждём!
+
+
+
+
+
+код api (сервера обработки) кобальта — open source и распространяется по
+лицензии [AGPL-3.0]({docs.apiLicense}).
+
+код фронтенда кобальта — [source first](https://sourcefirst.com/) и
+распространяется по лицензии [CC-BY-NC-SA 4.0]({docs.webLicense}).
+
+нам пришлось сделать фронтенд source first, чтобы грифтеры не наживались на
+нашем труде и не создавали вредоносные клоны для обмана людей и порче нашей
+репутации. кроме коммерческого использования, у этого типа лицензии те же
+принципы, что и у многих open source лицензий.
+
+мы используем много опенсорсных библиотек, но также создаём и распространяем
+свои собственные. полный список зависимостей можно посмотреть на
+[github]({contacts.github})!
+
diff --git a/web/i18n/ru/about/general.md b/web/i18n/ru/about/general.md
new file mode 100644
index 00000000..1657ca7b
--- /dev/null
+++ b/web/i18n/ru/about/general.md
@@ -0,0 +1,79 @@
+
+
+
+
+
+кобальт помогает сохранять что угодно с твоих любимых сайтов: видео, аудио, фото
+или гифки. просто вставь ссылку и вперёд!
+
+никакой рекламы, трекеров, платных подписок и прочей ерунды. просто удобное
+веб-приложение, которое работает где угодно и когда угодно.
+
+
+
+
+
+кобальт был создан для всеобщего блага, чтобы защитить людей от рекламы и
+вредоносных программ, которые навязывают альтернативные загрузчики. мы верим,
+что лучший софт — безопасный, открытый и доступный. все проекты imput следуют
+этим принципам.
+
+
+
+
+
+все запросы к бэкенду анонимны, и вся инфа о потенциальных файловых туннелях
+зашифрована. у нас строгая политика нулевых логов, мы *никогда* не храним
+идентифицирующую инфу о людях и никого не отслеживаем.
+
+если запрос требует дополнительной обработки, например ремукса или
+транскодирования, то кобальт обрабатывает медиафайлы прямо на твоём устройстве.
+это обеспечивает максимальную эффективность и приватность.
+
+если твоё устройство не поддерживает локальную обработку, то вместо неё
+используется серверная обработка в реальном времени. в этом сценарии
+обработанные медиаданные передаются напрямую клиенту, никогда не сохраняясь на
+диске сервера.
+
+ты можешь [включить принудительное туннелирование](/settings/privacy#tunnel),
+чтобы ещё сильнее повысить приватность. когда оно включено, кобальт будет
+туннелировать все скачиваемые файлы, а не только те, которым это необходимо.
+никто не узнает, откуда и что ты скачиваешь, даже твой провайдер. всё, что они
+увидят, это то, что ты используешь инстанс кобальта.
+
+
+
diff --git a/web/i18n/ru/about/privacy.md b/web/i18n/ru/about/privacy.md
new file mode 100644
index 00000000..d8522f99
--- /dev/null
+++ b/web/i18n/ru/about/privacy.md
@@ -0,0 +1,129 @@
+
+
+
+
+
+политика конфиденциальности кобальта проста: мы ничего не собираем и не храним о
+тебе. то, что ты делаешь, — это исключительно твоё дело, а не наше или чьё-либо
+ещё.
+
+эти условия применяются только при использовании официального инстанса кобальта.
+в других случаях, возможно, придётся обратиться к хостеру инстанса за точной
+информацией.
+
+
+
+
+
+инструменты, которые используют обработку на устройстве, работают офлайн,
+локально и никогда никуда не отправляют обработанные данные. они явно помечены
+как таковые, когда это применимо.
+
+
+
+
+
+при использовании функции сохранения, кобальту может понадобиться проксировать
+или ремуксировать/транскодировать файлы. если это так, то для этой цели
+создаётся временный туннель, и минимально необходимая информация о медиа
+хранится в течение 90 секунд.
+
+на неизменённом и официальном инстансе кобальта **все данные туннеля шифруются
+ключом, к которому имеет доступ только конечный пользователь**.
+
+зашифрованные данные туннеля могут включать:
+- название исходного сервиса.
+- исходные ссылки на медиафайлы.
+- необходимые внутренние аргументы для различения типов обработки.
+- ключевые метаданные файла (сгенерированное имя, заголовок, автор, год
+ создания, данные об авторских правах).
+- минимальная информация об исходном запросе, которая может быть использована
+ для восстановления туннеля после ошибки ссылки во время скачивания.
+
+эти данные безвозвратно удаляются из оперативной памяти сервера через 90 секунд.
+никто не имеет доступа к кэшированным данным туннеля, даже владельцы инстансов,
+если исходный код кобальта не изменён.
+
+медиаданные из туннелей нигде не хранятся/кэшируются. всё обрабатывается в
+реальном времени, даже при ремуксинге и транскодировании. туннели кобальта
+работают как анонимный прокси.
+
+если твоё устройство поддерживает локальную обработку, то зашифрованный туннель
+содержит намного меньше информации, потому что она возвращается клиенту.
+
+смотри [соответствующий исходный код на
+github](https://github.com/imputnet/cobalt/tree/main/api/src/stream), чтобы
+узнать больше о том, как это работает.
+
+
+
+
+
+временно хранящиеся данные туннеля шифруются с использованием стандарта AES-256.
+ключи расшифровки включены только в ссылку доступа и никогда не
+логируются/кэшируются/хранятся где-либо. только конечный пользователь имеет
+доступ к ссылке и ключам шифрования. ключи генерируются уникально для каждого
+запрошенного туннеля.
+
+
+{#if env.PLAUSIBLE_ENABLED}
+
+
+
+мы используем [plausible](https://plausible.io/), чтобы знать приблизительное
+число активных пользователей кобальта, полностью анонимно. никакая
+идентифицирующая информация о тебе или твоих запросах никогда не хранится. все
+данные анонимизированы и агрегированы. мы сами хостим и управляем [инстансом
+plausible](https://{env.PLAUSIBLE_HOST}/), который использует кобальт.
+
+plausible не использует куки и полностью соответствует GDPR, CCPA и PECR.
+
+если ты хочешь отказаться от анонимной аналитики, то это можно сделать в
+[настройках приватности](/settings/privacy#analytics). после отказа скрипт
+plausible не будет загружаться.
+
+[узнай больше о преданности plausible к
+приватности](https://plausible.io/privacy-focused-web-analytics).
+
+{/if}
+
+
+
+
+мы используем сервисы cloudflare для:
+- защиты от ddos и абьюза.
+- защиты от ботов (cloudflare turnstile).
+- хостинга и деплоя статического веб-приложения (cloudflare workers).
+
+всё это необходимо для обеспечения лучшего опыта для всех. cloudflare — наиболее
+приватный и надёжный провайдер всех упомянутых решений из всех известных нам
+провайдеров.
+
+cloudflare полностью соответствует требованиям GDPR и HIPAA.
+
+[узнай больше о преданности cloudflare к
+приватности](https://www.cloudflare.com/trust-hub/privacy-and-data-protection/).
+
diff --git a/web/i18n/ru/about/terms.md b/web/i18n/ru/about/terms.md
new file mode 100644
index 00000000..edb6df38
--- /dev/null
+++ b/web/i18n/ru/about/terms.md
@@ -0,0 +1,69 @@
+
+
+
+
+
+эти условия применяются только при использовании официального инстанса кобальта.
+в других случаях, возможно, придётся обратиться к хостеру инстанса за точной
+информацией.
+
+
+
+
+
+функция сохранения упрощает скачивание контента из интернета, и мы не несём
+никакой ответственности за то, как будет использоваться сохранённый контент.
+
+серверы обработки работают как продвинутые прокси и никогда не записывают
+запрошенный контент на диск. всё происходит в оперативной памяти и полностью
+удаляется после завершения туннеля. у нас нет логов загрузок, и мы не можем
+никого идентифицировать.
+
+подробнее о том, как работают туннели, можно узнать в [политике
+конфиденциальности](/about/privacy).
+
+
+
+
+
+ты (конечный пользователь) несёшь ответственность за то, что делаешь с нашими
+инструментами, как используешь и распространяешь полученный контент. пожалуйста,
+уважай чужой труд и всегда указывай авторов. убедись, что ты не нарушаешь
+никаких условий или лицензий.
+
+при использовании в образовательных целях всегда ссылайся на источники и
+указывай авторов.
+
+добросовестное использование и указание авторства приносят пользу всем.
+
+
+
+
+
+у нас нет возможности автоматически выявлять злоупотребления, так как кобальт
+полностью анонимен. однако, есть возможность сообщить нам о такой деятельности
+по почте, и мы сделаем всё возможное, чтобы принять нужные меры вручную:
+abuse[at]imput.net
+
+**этот адрес не предназначен для поддержки пользователей. ты не получишь ответ,
+если твой запрос не связан со злоупотреблениями.**
+
+если у тебя возникли проблемы с работой кобальта, то ты можешь обратиться за
+помощью любым удобным способом на [странице поддержки и
+сообщества](/about/community).
+
diff --git a/web/i18n/ru/button.json b/web/i18n/ru/button.json
new file mode 100644
index 00000000..d87f75b8
--- /dev/null
+++ b/web/i18n/ru/button.json
@@ -0,0 +1,27 @@
+{
+ "download.audio": "скачать аудио",
+ "import": "импортировать",
+ "copied": "скопировано",
+ "copy": "скопировать",
+ "share": "поделиться",
+ "download": "скачать",
+ "no": "нет",
+ "yes": "да",
+ "save": "скачать",
+ "continue": "продолжить",
+ "done": "готово",
+ "reset": "сбросить",
+ "cancel": "отменить",
+ "export": "экспортировать",
+ "gotit": "понятно",
+ "copy.section": "скопировать ссылку на раздел",
+ "clear_input": "очистить поле ввода",
+ "show_input": "показать ввод",
+ "hide_input": "скрыть ввод",
+ "restore_input": "восстановить ввод",
+ "clear": "очистить",
+ "remove": "убрать",
+ "clear_cache": "очистить кэш",
+ "retry": "повторить",
+ "delete": "удалить"
+}
diff --git a/web/i18n/ru/dialog.json b/web/i18n/ru/dialog.json
new file mode 100644
index 00000000..e7a4a58a
--- /dev/null
+++ b/web/i18n/ru/dialog.json
@@ -0,0 +1,18 @@
+{
+ "reset.title": "cбросить все данные?",
+ "reset.body": "ты уверен что хочешь сбросить все настройки? это действие немедленно и необратимо.",
+ "picker.title": "что сохранить?",
+ "saving.title": "как сохранить?",
+ "saving.timeout": "кобальт попытался сохранить файл автоматически, но твой браузер остановил это. выбери способ вручную.",
+ "reset_settings.title": "сбросить все настройки?",
+ "reset_settings.body": "ты точно хочешь сбросить все настройки? это действие мгновенное и необратимое.",
+ "picker.description.phone": "нажми на то, что хочешь скачать. картинки также можно скачать долгим нажатием.",
+ "picker.description.desktop": "кликни на то, что хочешь скачать. картинки также можно скачать через контекстное меню.",
+ "picker.description.ios": "нажми на то, что хочешь скачать через команду siri. картинки также можно скачать долгим нажатием.",
+ "saving.blocked": "кобальт попытался открыть файл в новой вкладке, но твой браузер заблокировал это. разреши всплывающие окна для кобальта, чтобы избежать этого в следующий раз.",
+ "clear_cache.title": "очистить весь кэш?",
+ "import.body": "импорт неизвестных или повреждённых файлов может неожиданно изменить или сломать работу кобальта. импортируй только те файлы, которые ты экспортировал сам и не изменял. если кто-то попросил тебя импортировать этот файл — не делай этого.\n\nмы не несём ответственности за любой вред, причинённый импортом неизвестных файлов настроек.",
+ "safety.custom_instance.body": "сторонние инстансы могут быть опасны для твоей приватности и безопасности.\n\nвредоносные инстансы могут:\n1. перенаправлять тебя с кобальта и пытаться обмануть.\n2. записывать всю информацию о твоих запросах, хранить её вечно и использовать для слежки за тобой.\n3. скачивать вредоносные файлы (например, вирусы).\n4. заставлять тебя смотреть рекламу или платить за скачивание.\n\nпосле этого момента мы не сможем тебя защитить. пожалуйста, будь осторожен с выбором инстанса и всегда доверяй своей интуиции. если что-то кажется странным, то вернись на эту страницу, сбрось пользовательский инстанс и сообщи нам об этом на github.",
+ "clear_cache.body": "все файлы из очереди обработки будут удалены и локальные фичи займут больше времени на загрузку. это действие мгновенное и необратимое.",
+ "safety.title": "важное предупреждение о безопасности"
+}
diff --git a/web/i18n/ru/donate.json b/web/i18n/ru/donate.json
new file mode 100644
index 00000000..9b88340a
--- /dev/null
+++ b/web/i18n/ru/donate.json
@@ -0,0 +1,29 @@
+{
+ "card.once": "одноразовый донат",
+ "card.option.30": "обед для двоих",
+ "body.no_bullshit": "мы считаем, что интернет не должен быть страшным. поэтому в кобальте никогда не будет рекламы или другого вредоносного контента. это обещание, за которым мы стоим горой. всё, что мы делаем, создаётся с учётом конфиденциальности, доступности и простоты использования, что делает кобальт доступным для всех.",
+ "card.custom": "своя сумма (от $2)",
+ "card.processor": "через {{value}}",
+ "card.option.5": "чашка кофе",
+ "card.option.50": "10кг кошачьего корма",
+ "card.option.1599": "базовый макбук",
+ "card.option.4900": "10,000 яблок",
+ "share.title": "поделись кобальтом с другом",
+ "alternative.title": "альтернативные способы доната",
+ "alt.copy": "{{ value }}. адрес криптокошелька. нажми, чтобы скопировать.",
+ "alt.open": "{{ value }}. нажми, чтобы открыть.",
+ "body.motivation": "кобальт помогает продюсерам, преподавателям, видеомейкерам и многим другим заниматься тем, что они любят. это особый сервис, создающийся с любовью, а не ради прибыли.",
+ "body.keep_going": "если кобальт помог тебе, пожалуйста, подумай над тем, чтобы поддержать нашу работу! ты можешь поддержать нас донатом, либо поделившись кобальтом с другом. каждый донат очень ценится и помогает нам продолжать работу над кобальтом и другими проектами.",
+ "card.recurring": "регулярный донат",
+ "card.option.10": "большая пицца",
+ "card.option.15": "полный обед",
+ "card.custom.submit": "своя сумма",
+ "banner.title": "Поддержи безопасный\nи открытый Интернет",
+ "banner.subtitle": "поддержи imput или поделись\nкобальтом с другом",
+ "card.option.100": "один год доменов",
+ "card.option.200": "аэрогриль",
+ "card.option.500": "крутое офисное кресло",
+ "card.option.7398": "флагманский макбук",
+ "card.option.8629": "маленький земельный участок",
+ "card.option.9433": "джакузи класса люкс"
+}
diff --git a/web/i18n/ru/error.json b/web/i18n/ru/error.json
new file mode 100644
index 00000000..e7ed5a5a
--- /dev/null
+++ b/web/i18n/ru/error.json
@@ -0,0 +1,10 @@
+{
+ "api.link.invalid": "ваша ссылка недействительная либо этот сервис ещё не поддерживается. вы вставили правильную ссылку?",
+ "api.rate_exceeded": "вы делаете слишком много запросов. попробуйте снова через {{ limit }} секунд!",
+ "pipeline.missing_response_data": "инстанс обработки не ответил с нужной информацией о файле, поэтому я не могу создать задачи для локальной обработки. попробуй ещё раз через несколько секунд и сообщи о проблеме, если она не исчезнет!",
+ "captcha_too_long": "cloudflare turnstile слишком долго проверяет, что ты не бот. попробуй ещё раз, но если снова появится эта ошибка, то можно попробовать: отключить странные расширения браузера, сменить сеть, использовать другой браузер или проверить устройство на наличие вредоносных программ.",
+ "import.invalid": "в этом файле нет совместимых настроек кобальта для импорта. ты уверен, что это тот файл?",
+ "tunnel.probe": "не удалось протестировать этот туннель. возможно, твой браузер или настройки сети блокируют доступ к одному из серверов кобальта. ты уверен, что у тебя нет каких-то странных расширений для браузера?",
+ "import.unknown": "не удалось загрузить данные из файла. возможно, он повреждён или не того формата. вот ошибка, которую я получил:\n\n{{ value }}",
+ "import.no_data": "из этого файла нечего загружать. ты уверен, что это тот файл?"
+}
diff --git a/web/i18n/ru/error/api.json b/web/i18n/ru/error/api.json
new file mode 100644
index 00000000..280d6717
--- /dev/null
+++ b/web/i18n/ru/error/api.json
@@ -0,0 +1,50 @@
+{
+ "auth.jwt.invalid": "не удалось пройти аутентификацию с инстансом обработки, потому что токен доступа недействителен. попробуй ещё раз через пару секунд или перезагрузи страницу!",
+ "auth.turnstile.invalid": "не удалось пройти аутентификацию с инстансом обработки, потому что решение капчи недействительно. попробуй ещё раз через пару секунд или перезагрузи страницу!",
+ "auth.key.not_api_key": "для использования этого инстанса нужен ключ доступа, но его нет. добавь его в настройках!",
+ "auth.key.invalid": "ключ доступа недействителен. сбрось его в настройках инстанса и используй правильный!",
+ "auth.key.ua_not_allowed": "ты не можешь использовать этот ключ доступа с текущего юзер агента. попробуй другой клиент или устройство!",
+ "unreachable": "не удалось подключиться к инстансу обработки. проверь своё интернет-соединение и попробуй ещё раз!",
+ "rate_exceeded": "ты делаешь слишком много запросов. попробуй снова через {{ limit }}с.",
+ "capacity": "кобальт сейчас перегружен и не может обработать твой запрос. попробуй ещё раз через пару секунд!",
+ "service.unsupported": "этот сервис ещё не поддерживается. ты уверен, что вставил правильную ссылку?",
+ "service.audio_not_supported": "этот сервис не поддерживает извлечение аудио. попробуй ссылку с другого сервиса!",
+ "link.invalid": "твоя ссылка недействительна или этот сервис ещё не поддерживается. ты точно вставил правильную ссылку?",
+ "fetch.fail": "что-то пошло не так при получении инфы из {{ service }}, и я ничего не смог для тебя достать. если эта проблема не исчезнет, пожалуйста, сообщи о ней!",
+ "auth.jwt.missing": "не удалось пройти аутентификацию с инстансом обработки, потому что отсутствует токен доступа. попробуй ещё раз через пару секунд или перезагрузи страницу!",
+ "auth.key.missing": "для использования этого инстанса нужен ключ доступа, но его нет. добавь его в настройках!",
+ "generic": "что-то пошло не так, и я не смог ничего найти для тебя. попробуй ещё раз через пару секунд. если проблема останется, пожалуйста, сообщи об этом!",
+ "auth.turnstile.missing": "не удалось пройти аутентификацию с инстансом обработки, потому что отсутствует решение капчи. попробуй ещё раз через пару секунд или перезагрузи страницу!",
+ "unknown_response": "не удалось прочитать ответ от инстанса обработки. скорее всего, причина в том, что веб-приложение устарело. перезагрузи его и попробуй снова!",
+ "auth.key.not_found": "использованный тобой ключ доступа не найден. ты уверен, что у этого инстанса есть твой ключ?",
+ "invalid_body": "не удалось отправить запрос на инстанс обработки. скорее всего, причина в том, что веб-приложение устарело. перезагрузи его и попробуй снова!",
+ "auth.key.invalid_ip": "не удалось распарсить твой ip-адрес. что-то пошло совсем не так, пожалуйста, сообщи об этой ошибке!",
+ "auth.key.ip_not_allowed": "ты не можешь использовать этот ключ доступа с текущего ip-адреса. попробуй другой инстанс или сеть!",
+ "timed_out": "инстанс обработки слишком долго не отвечал. возможно, он сейчас перегружен, попробуй ещё раз через пару секунд!",
+ "service.disabled": "этот сервис обычно поддерживается кобальтом, но он отключён на этом инстансе. попробуй ссылку с другого сервиса!",
+ "link.unsupported": "{{ service }} поддерживается, но я не смог распознать твою ссылку. ты точно вставил правильную?",
+ "fetch.critical": "модуль {{ service }} вернул ошибку, которую я не узнаю. попробуй ещё раз через пару секунд, но если проблема останется, пожалуйста, сообщи о ней!",
+ "content.too_long": "запрошенное медиа слишком длинное. лимит длительности на этом инстансе — {{ limit }}мин. попробуй что-нибудь покороче!",
+ "content.video.unavailable": "я не могу получить доступ к этому видео. оно может быть ограничено со стороны {{ service }}. попробуй другую ссылку!",
+ "content.video.private": "это видео приватное, поэтому я не могу получить к нему доступ. измени его видимость или попробуй другое!",
+ "content.video.region": "это видео ограничено по региону, а инстанс обработки находится в другом месте. попробуй другую ссылку!",
+ "content.paid": "этот контент требует покупки. кобальт не может скачивать платный контент. попробуй другую ссылку!",
+ "content.post.private": "не удалось получить инфу об этом посте, потому что он от закрытого аккаунта. попробуй другую ссылку!",
+ "youtube.token_expired": "не удалось получить это видео, потому что токен youtube истёк и не был обновлён. попробуй ещё раз через пару секунд, но если так и не заработает, пожалуйста, сообщи об этой проблеме!",
+ "youtube.no_hls_streams": "не удалось найти ни одного подходящего HLS-потока для этого видео. попробуй скачать его без HLS!",
+ "youtube.api_error": "youtube что-то обновил в своём api, и я не смог получить инфу об этом видео. попробуй ещё раз через пару секунд, но если проблема останется, пожалуйста, сообщи о ней!",
+ "youtube.drm": "это youtube-видео защищено widevine DRM, так что я не могу его скачать. попробуй другую ссылку!",
+ "fetch.rate": "{{ service }} ограничил частоту запросов от инстанса обработки. попробуй ещё раз через пару секунд!",
+ "youtube.temporary_disabled": "скачивание с youtube временно отключено из-за ограничений со стороны youtube. мы уже ищем способы их обойти.\n\nприносим извинения за неудобства и делаем всё возможное, чтобы восстановить эту функциональность. следи за обновлениями в соцсетях или на github!",
+ "content.video.age": "это видео ограничено по возрасту, поэтому я не могу получить его анонимно. попробуй ещё раз или попробуй другую ссылку!",
+ "content.region": "этот контент ограничен по региону, а инстанс обработки находится в другом месте. попробуй другую ссылку!",
+ "youtube.no_matching_format": "youtube не вернул подходящую комбинацию видео и аудио форматов: либо видео, либо аудио отсутствует. возможно, форматы для этого видео перекодируются на стороне youtube, или же что-то пошло не так при их парсинге. попробуй ещё раз чуть позже!",
+ "youtube.no_session_tokens": "не удалось получить необходимые токены сессии для ютуба. это может быть вызвано ограничением со стороны ютуба. попробуй ещё раз через пару секунд, но если проблема останется, пожалуйста, сообщи о ней!",
+ "youtube.decipher": "youtube обновил свой алгоритм расшифровки, и из-за этого мне не удалось получить информацию о видео. попробуй ещё раз через пару секунд, но если проблема останется, пожалуйста, сообщи о ней!",
+ "fetch.short_link": "не удалось получить инфу по короткой ссылке. ты уверен, что она работает? если да, а ты всё равно видишь эту ошибку, пожалуйста, сообщи об этой проблеме!",
+ "fetch.empty": "не смог найти медиа, которое я мог бы скачать для тебя. ты уверен, что вставил правильную ссылку?",
+ "content.post.age": "этот пост ограничен по возрасту, поэтому я не могу получить его анонимно. попробуй ещё раз или попробуй другую ссылку!",
+ "youtube.login": "не удалось получить это видео, потому что youtube попросил доказать, что инстанс обработки — не бот. попробуй ещё раз через пару секунд, но если так и не заработает, пожалуйста, сообщи об этой проблеме!",
+ "content.video.live": "это видео сейчас идёт в прямом эфире, поэтому я ещё не могу его скачать. подожди, пока стрим закончится, и попробуй снова!",
+ "content.post.unavailable": "не удалось ничего найти об этом посте. его видимость может быть ограничена или он может не существовать. убедись, что твоя ссылка работает, и попробуй снова через пару секунд!"
+}
diff --git a/web/i18n/ru/error/queue.json b/web/i18n/ru/error/queue.json
new file mode 100644
index 00000000..5258ef77
--- /dev/null
+++ b/web/i18n/ru/error/queue.json
@@ -0,0 +1,17 @@
+{
+ "fetch.no_file_reader": "не смог записать файл в кэш",
+ "worker_didnt_start": "не смог запустить воркер обработки",
+ "ffmpeg.probe_failed": "не удалось проверить этот файл, возможно, он повреждён или не поддерживается",
+ "fetch.network_error": "скачивание было прервано из-за проблем с сетью",
+ "no_final_file": "финальный файл пропал",
+ "fetch.corrupted_file": "файл был скачан не полностью, попробуй ещё раз",
+ "fetch.crashed": "воркер обработки вылетел, смотри детали в консоли",
+ "fetch.bad_response": "не смог получить туннель файла",
+ "fetch.empty_tunnel": "туннель файла пустой, попробуй ещё раз через несколько минут",
+ "ffmpeg.no_input_type": "тип этого файла не поддерживается",
+ "ffmpeg.crashed": "воркер ffmpeg вылетел, смотри детали в консоли",
+ "ffmpeg.no_input_format": "формат этого файла не поддерживается",
+ "ffmpeg.out_of_memory": "не хватает памяти, не могу продолжить",
+ "ffmpeg.no_render": "рендер ffmpeg пустой, произошло что-то очень странное",
+ "ffmpeg.no_args": "воркер ffmpeg не получил нужные аргументы"
+}
diff --git a/web/i18n/ru/general.json b/web/i18n/ru/general.json
index 90cbfef5..d10e39a2 100644
--- a/web/i18n/ru/general.json
+++ b/web/i18n/ru/general.json
@@ -2,6 +2,5 @@
"cobalt": "кобальт",
"meowbalt": "мяубальт",
"beta": "бета",
-
- "embed.description": "сохраняй то, что любишь: без рекламы, трекеров и прочей чепухи. кобальт создан с любовью, а не с целью заработать."
+ "embed.description": "кобальт помогает тебе сохранять то, что ты любишь, без рекламы, трекеров и прочей ерунды. просто вставь ссылку!"
}
diff --git a/web/i18n/ru/notification.json b/web/i18n/ru/notification.json
new file mode 100644
index 00000000..14822cf3
--- /dev/null
+++ b/web/i18n/ru/notification.json
@@ -0,0 +1,4 @@
+{
+ "update.title": "доступно обновление!",
+ "update.subtext": "нажми, чтобы обновить"
+}
diff --git a/web/i18n/ru/queue.json b/web/i18n/ru/queue.json
new file mode 100644
index 00000000..62a8102a
--- /dev/null
+++ b/web/i18n/ru/queue.json
@@ -0,0 +1,13 @@
+{
+ "state.waiting": "в очереди",
+ "state.starting.fetch": "начинаю скачивание",
+ "state.running.remux": "ремуксирую",
+ "state.retrying": "повторяю",
+ "state.starting.encode": "начинаю транскодирование",
+ "title": "очередь обработки",
+ "state.starting": "начинаю",
+ "state.starting.remux": "начинаю ремуксинг",
+ "state.running.fetch": "скачиваю",
+ "state.running.encode": "транскодирую",
+ "stub": "тут пока что ничего нет, только мы вдвоём.\nпопробуй скачать что-нибудь!"
+}
diff --git a/web/i18n/ru/receiver.json b/web/i18n/ru/receiver.json
new file mode 100644
index 00000000..2f808fac
--- /dev/null
+++ b/web/i18n/ru/receiver.json
@@ -0,0 +1,7 @@
+{
+ "accept": "поддерживаемые форматы: {{ formats }}.",
+ "title": "перетащи или выбери файл",
+ "title.drop": "скинь файл сюда!",
+ "title.multiple": "перетащи или выбери файлы",
+ "title.drop.multiple": "скинь файлы сюда!"
+}
diff --git a/web/i18n/ru/remux.json b/web/i18n/ru/remux.json
new file mode 100644
index 00000000..497cb1c1
--- /dev/null
+++ b/web/i18n/ru/remux.json
@@ -0,0 +1,9 @@
+{
+ "description": "ремукс помогает решить проблемы с совместимостью файлов в старых приложениях. файлы обрабатываются быстро, без потери качества и локально на устройстве.",
+ "bullet.purpose.description": "ремукс исправляет любые проблемы с файлом, например, отсутствие информации о времени. он помогает повысить совместимость со старыми программами, такими как vegas pro и windows media player.",
+ "bullet.purpose.title": "что делает ремукс?",
+ "bullet.explainer.title": "как он работает?",
+ "bullet.explainer.description": "ремукс берёт существующие данные кодека и копирует их в новый медиаконтейнер. это происходит без потери качества, так как медиаданные не перекодируются.",
+ "bullet.privacy.title": "локальная обработка",
+ "bullet.privacy.description": "кобальт ремуксирует файлы локально. файлы никогда не покидают твоё устройство, поэтому обработка происходит практически мгновенно."
+}
diff --git a/web/i18n/ru/save.json b/web/i18n/ru/save.json
index ce64917a..60bb2998 100644
--- a/web/i18n/ru/save.json
+++ b/web/i18n/ru/save.json
@@ -10,5 +10,15 @@
"services.title": "поддерживаемые сервисы",
"services.title_show": "показать поддерживаемые сервисы",
"services.title_hide": "скрыть поддерживаемые сервисы",
- "services.disclaimer": "кобальт не аффилирован ни с одним из перечисленных выше сервисов.\n\nдеятельность meta platforms (владельца facebook и instagram) запрещена на территории РФ и признана экстремистской."
+ "services.disclaimer": "кобальт не аффилирован ни с одним из перечисленных выше сервисов.\n\nдеятельность meta platforms (владельца facebook и instagram) запрещена на территории РФ и признана экстремистской.",
+ "tutorial.step.1": "добавь команды-компаньоны:",
+ "tutorial.step.2": "нажми кнопку \"поделиться\" в диалоге сохранения кобальта.",
+ "tutorial.step.3": "выбери нужную команду в окне обмена.",
+ "tutorial.shortcut.photos": "в фото",
+ "tutorial.shortcut.files": "в файлы",
+ "tutorial.title": "как сохранить на ios?",
+ "tutorial.intro": "чтобы удобно сохранять файлы на ios, придётся использовать команду siri в меню обмена.",
+ "tutorial.outro": "эти команды siri будут работать только из приложения кобальта, использовать их из других приложений не получится.",
+ "tooltip.captcha": "cloudflare turnstile проверяет, что ты не бот. подожди, пожалуйста!",
+ "label.community_instance": "инстанс сообщества"
}
diff --git a/web/i18n/ru/settings.json b/web/i18n/ru/settings.json
new file mode 100644
index 00000000..5136d5d6
--- /dev/null
+++ b/web/i18n/ru/settings.json
@@ -0,0 +1,126 @@
+{
+ "theme.auto": "авто",
+ "theme.light": "светлая",
+ "audio.bitrate.kbps": "кб/с",
+ "theme.dark": "тёмная",
+ "audio.youtube.dub": "звуковая дорожка youtube",
+ "video.quality.max": "8k+",
+ "page.video": "видео",
+ "page.audio": "аудио",
+ "page.download": "скачивание",
+ "section.save": "скачивание",
+ "video.quality.1440": "1440p",
+ "video.quality.1080": "1080p",
+ "video.quality.720": "720p",
+ "video.quality.480": "480p",
+ "video.quality.360": "360p",
+ "video.quality.240": "240p",
+ "video.quality.144": "144p",
+ "metadata.file": "метаданные файла",
+ "saving.title": "метод сохранения",
+ "saving.ask": "спросить",
+ "saving.download": "скачать",
+ "saving.share": "поделиться",
+ "saving.copy": "скопировать",
+ "accessibility": "доступность",
+ "language": "язык",
+ "language.preferred.title": "предпочитаемый язык",
+ "privacy.analytics": "анонимная аналитика трафика",
+ "audio.tiktok.original.title": "скачивать оригинальный звук",
+ "privacy.tunnel": "туннелирование",
+ "privacy.tunnel.title": "всегда туннелировать файлы",
+ "video.tiktok.h265": "tiktok",
+ "audio.format.mp3": "mp3",
+ "audio.format.ogg": "ogg",
+ "audio.format.wav": "wav",
+ "audio.format.opus": "opus",
+ "page.privacy": "приватность",
+ "theme": "тема",
+ "video.quality": "качество видео",
+ "video.twitter.gif": "twitter/x",
+ "video.quality.2160": "4k",
+ "audio.format": "формат аудио",
+ "audio.bitrate": "битрейт аудио",
+ "audio.tiktok.original": "tiktok",
+ "metadata.disable.title": "отключить метаданные",
+ "language.auto.title": "автоматический выбор",
+ "metadata.disable.description": "название, исполнитель и другая информация не будут добавлены в файл.",
+ "language.preferred.description": "этот язык будет использоваться когда автоматический выбор отключен. любой непереведённый текст будет отображаться на английском языке.\n\nмы используем переводы, предоставленные сообществом. они могут быть неточными или неполными.",
+ "audio.youtube.dub.description": "cobalt будет использовать дублированную аудиодорожку для выбранного языка, если она доступна. в противном случае будет использоваться оригинальная.",
+ "language.auto.description": "если доступен перевод, то кобальт будет использовать язык твоего браузера. в ином случае будет использоваться английский.",
+ "theme.description": "авто тема переключается между светлой и тёмной темой в зависимости от системной темы.",
+ "page.debug": "инфа для гиков",
+ "section.general": "основные",
+ "page.appearance": "внешний вид",
+ "page.instances": "инстансы",
+ "page.advanced": "продвинутые",
+ "page.accessibility": "общедоступность",
+ "page.metadata": "метаданные",
+ "page.local": "локальная обработка",
+ "video.youtube.codec": "кодек и контейнер youtube",
+ "audio.youtube.dub.title": "предпочитаемый язык озвучки",
+ "metadata.filename.basic": "базовый",
+ "video.twitter.gif.title": "конвертировать зацикленные видео в GIF",
+ "metadata.filename.description": "стиль названий файлов используется только для файлов, туннелированных через кобальт. некоторые сервисы поддерживают только классический стиль.",
+ "youtube.dub.original": "оригинальный",
+ "metadata.filename.pretty": "красивый",
+ "metadata.filename.nerdy": "занудный",
+ "audio.tiktok.original.description": "кобальт будет скачивать оригинальный звук из видео без каких-либо изменений от автора поста.",
+ "metadata.filename": "стиль названий файлов",
+ "metadata.filename.classic": "классический",
+ "video.twitter.gif.description": "GIF конвертация неэффективна, финальный файл может быть огромным и в плохом качестве.",
+ "audio.youtube.better_audio.title": "предпочитать лучшее качество",
+ "audio.format.description": "все форматы кроме \"лучшего\" конвертируются из исходного формата, поэтому возможна небольшая потеря качества. когда выбран \"лучший\" формат, аудио остаётся в оригинальном формате, если это возможно.",
+ "audio.youtube.better_audio.description": "кобальт будет пытаться выбрать самое качественное аудио в режиме скачивания аудио. оно может быть недоступно в зависимости от ответа youtube, текущей нагрузки и состояния сервера. на кастомных инстансах эта опция может не поддерживаться.",
+ "audio.youtube.better_audio": "качество аудио с youtube",
+ "video.quality.description": "если предпочитаемое качество недоступно, то выбирается следующий лучший вариант.",
+ "video.youtube.codec.description": "h264: наилучшая совместимость, среднее качество. максимальное качество — 1080p.\nav1: наилучшее качество и сжатие. поддерживает 8k и HDR.\nvp9: то же качество, что и у av1, но файл в ~2x больше. поддерживает 4k & HDR.\n\nav1 и vp9 не очень широко поддерживаются, возможно придётся использовать дополнительное ПО для их проигрывания/обработки. кобальт выбирает следующий лучший кодек, если предпочитаемый недоступен.",
+ "audio.bitrate.description": "битрейт применяется только при конвертации аудио в формат с потерями. кобальт не может улучшить качество исходного аудио, поэтому выбор битрейта выше 128 кб/с может увеличить размер файла без заметной разницы в звуке. воспринимаемое качество может различаться в зависимости от формата.",
+ "video.h265": "high efficiency video codec",
+ "video.h265.title": "использовать h265 для видео",
+ "video.h265.description": "позволяет скачивать видео с tiktok и xiaohongshu в более высоком качестве, но с потерей совместимости.",
+ "video.youtube.hls": "форматы hls для youtube",
+ "video.youtube.hls.description": "в этом режиме доступны только кодеки h264 и vp9. оригинальный аудио кодек aac перекодируется для совместимости, поэтому качество аудио может быть хуже чем у варианта без HLS.\n\nэта функция экспериментальна, поэтому может быть убрана или изменена в будущем.",
+ "audio.format.best": "лучший",
+ "video.youtube.hls.title": "предпочитать hls для видео и аудио",
+ "metadata.filename.preview.video": "Название Видео - Автор Видео",
+ "metadata.filename.preview.audio": "Название Аудио - Автор Аудио",
+ "saving.description": "предпочтительный способ сохранения файла или ссылки с кобальта. если предпочитаемый метод недоступен или что-то пойдёт не так, кобальт спросит тебя как поступить.",
+ "accessibility.transparency.description": "уменьшает прозрачность поверхностей и выключает эффекты размытия. также может улучшить работу интерфейса на менее мощных устройствах.",
+ "accessibility.transparency.title": "уменьшить визуальную прозрачность",
+ "accessibility.visual": "интерфейс",
+ "accessibility.haptics": "вибрация",
+ "accessibility.behavior": "поведение",
+ "accessibility.auto_queue.description": "очередь обработки не будет открываться автоматически при добавлении новой задачи. прогресс всё равно будет отображаться, и ты всё равно сможешь открыть её вручную.",
+ "privacy.analytics.learnmore": "узнай больше о преданности plausible к приватности.",
+ "accessibility.motion.description": "анимации и переходы будут отключены, когда это возможно.",
+ "accessibility.haptics.title": "отключить вибрацию",
+ "accessibility.haptics.description": "вся вибрация будет отключена.",
+ "accessibility.auto_queue.title": "не открывать очередь обработки",
+ "privacy.analytics.description": "анонимная аналитика трафика нужна, чтобы знать приблизительное количество активных пользователей кобальта. идентифицирующая информация о тебе никогда не сохраняется. все обрабатываемые данные анонимизированы и агрегированы.\n\nмы используем собственный инстанс plausible, который не использует куки и полностью соответствует требованиям GDPR, CCPA и PECR.",
+ "privacy.tunnel.description": "cobalt скроет твой ip адрес, информацию о браузере и обойдёт местные сетевые ограничения. когда включено, у всех файлов будут читаемые названия вместо абракадабры.",
+ "accessibility.motion.title": "уменьшить движение",
+ "privacy.analytics.title": "не участвовать в аналитике",
+ "advanced.debug": "отладка",
+ "advanced.debug.description": "даёт доступ к странице с различной информацией, которая может быть полезна для отладки. никак не меняет поведение кобальта.",
+ "advanced.debug.title": "включить функции для зануд",
+ "processing.community": "инстансы сообщества",
+ "processing.enable_custom.description": "кобальт будет использовать сторонний инстанс обработки, если ты так решишь. несмотря на то, что у кобальта есть некоторые меры безопасности, мы не несём ответственности за любой ущерб, причинённый сторонним инстансом, так как мы его не контролируем.\n\nбудь осторожен с тем, какие инстансы ты используешь, и убедись, что их хостят люди, которым ты доверяешь.",
+ "processing.enable_custom.title": "использовать сторонний инстанс",
+ "local.saving": "обработка медиа",
+ "local.saving.description": "при скачивании медиа, ремуксинг и транскодирование будут выполняться на устройстве, а не в облаке. ты увидишь подробный прогресс в очереди обработки. инстансы обработки могут принудительно включать эту функцию для экономии ресурсов.\n\nэксклюзивные функции на устройстве не зависят от этого переключателя, они всегда работают локально.",
+ "local.saving.title": "скачивать и обрабатывать медиа локально",
+ "advanced.settings_data": "данные настроек",
+ "local.webcodecs.description": "при декодировании или кодировании файлов кобальт будет пытаться использовать webcodecs. эта функция позволяет обрабатывать медиафайлы с ускорением на GPU, так что всё декодирование и кодирование будет намного быстрее.\n\nдоступность и стабильность этой функции зависят от возможностей твоего устройства и браузера. что-то может сломаться или работать некорректно.",
+ "processing.access_key": "ключ доступа к инстансу",
+ "advanced.local_storage": "локальное хранилище",
+ "local.webcodecs": "webcodecs",
+ "local.webcodecs.title": "использовать webcodecs для локальной обработки",
+ "processing.access_key.title": "использовать ключ доступа",
+ "processing.custom_instance.input.alt_text": "домен стороннего инстанса",
+ "tabs": "навигация",
+ "tabs.hide_remux": "скрыть страницу ремукса",
+ "tabs.hide_remux.description": "если ты не пользуешься ремуксом, то его можно скрыть из панели навигации.",
+ "processing.access_key.description": "кобальт будет использовать этот ключ для запросов к инстансу обработки вместо других методов аутентификации. убедись, что инстанс поддерживает api ключи!",
+ "processing.access_key.input.alt_text": "ключ доступа u-u-i-d"
+}
diff --git a/web/i18n/ru/tabs.json b/web/i18n/ru/tabs.json
index 0b93cc7f..afe0d693 100644
--- a/web/i18n/ru/tabs.json
+++ b/web/i18n/ru/tabs.json
@@ -3,6 +3,6 @@
"settings": "настройки",
"updates": "новости",
"donate": "донаты",
- "about": "инфа",
+ "about": "инфо",
"remux": "ремукс"
}
diff --git a/web/i18n/ru/updates.json b/web/i18n/ru/updates.json
new file mode 100644
index 00000000..f6ab7698
--- /dev/null
+++ b/web/i18n/ru/updates.json
@@ -0,0 +1,4 @@
+{
+ "button.next": "перейти к предыдущему обновлению ({{ value }})",
+ "button.previous": "перейти к следующему обновлению ({{ value }})"
+}