diff --git a/js/i18n.js b/js/i18n.js index 53d9abd..c909ae0 100644 --- a/js/i18n.js +++ b/js/i18n.js @@ -10,6 +10,7 @@ export const TRANSLATIONS = { fr: { 'lang.name': 'Français' }, ja: { 'lang.name': '日本語' }, ko: { 'lang.name': '한국어' }, + ru: { 'lang.name': 'Русский' }, }; // ── Module state ────────────────────────────────────────────────────────────── diff --git a/js/i18n/ru.js b/js/i18n/ru.js new file mode 100644 index 0000000..805827a --- /dev/null +++ b/js/i18n/ru.js @@ -0,0 +1,219 @@ +export default { + "theme.dark": "Тёмная тема", + "theme.light": "Светлая тема", + "theme.toggleTitle": "Переключить светлый / тёмный режим", + "theme.toggleAriaLabel": "Переключить светлый/тёмный режим", + "dropHint.text": "Перетащите файл .stl, .obj или .3mf сюда
или ", + "ui.wireframe": "Каркас", + "ui.perspective": "Перспективный вид", + "ui.controlsHint": "Перетаскивание левой кнопкой: орбита · Правой кнопкой: панорама · Колесико: масштаб", + "ui.meshInfo": "{n} треугольников · {mb} МБ · {sx} × {sy} × {sz} мм", + "ui.loadStl": "Загрузить модель…", + "ui.localProcessingNote": "Вся обработка выполняется локально в вашем браузере — данные не загружаются.", + "sections.displacementMap": "Карта смещения", + "ui.uploadCustomMap": "Загрузить пользовательскую карту", + "ui.noMapSelected": "Карта не выбрана", + "ui.customMap": "Пользовательская карта", + "ui.removeCustomMap": "Удалить пользовательскую карту", + "ui.loadingTextures": "Загрузка текстур…", + "sections.projection": "Проекция", + "labels.mode": "Режим", + "projection.triplanar": "Трипланарная", + "projection.cubic": "Кубическая (Box)", + "projection.cylindrical": "Цилиндрическая", + "projection.spherical": "Сферическая", + "projection.planarXY": "Плоская XY", + "projection.planarXZ": "Плоская XZ", + "projection.planarYZ": "Плоская YZ", + "sections.transform": "Трансформация", + "labels.scaleU": "Масштаб U", + "labels.scaleV": "Масштаб V", + "labels.offsetU": "Смещение U", + "labels.offsetV": "Смещение V", + "labels.rotation": "Поворот", + "tooltips.proportionalScaling": "Пропорциональное масштабирование (U = V)", + "tooltips.proportionalScalingAria": "Пропорциональное масштабирование (U = V)", + "sections.displacement": "Глубина текстуры", + "labels.textureHeight": "Высота текстуры (мм)", + "labels.invertDisplacement": "Инвертировать (вдавливать вместо выдавливания)", + "labels.seamBlend": "Смягчение шва ⓘ", + "tooltips.seamBlend": "Смягчает резкий шов на стыке граней проекции. Эффективно для кубического и цилиндрического режимов.", + "labels.transitionSmoothing": "Сглаживание перехода ⓘ", + "tooltips.transitionSmoothing": "Ширина зоны смешивания возле краёв шва. Меньшие значения сохраняют переходы близко к шву; большие — смешивают более широкую полосу.", + "labels.textureSmoothing": "Сглаживание текстуры ⓘ", + "tooltips.textureSmoothing": "Применяет размытие по Гауссу к карте смещения. Большие значения дают более мягкие, плавные детали поверхности. 0 = выключено.", + "labels.capAngle": "Угол крышки ⓘ", + "tooltips.capAngle": "Угол (в градусах) от вертикали, при котором включается проекция верхней/нижней крышки. Меньшие значения ограничивают проекцию крышки почти плоскими гранями.", + "sections.masking": "Маскирование", + "sections.maskAngles": "По углу ⓘ", + "tooltips.maskAngles": "0° = без маскирования. Поверхности в пределах этого угла от горизонтали не будут текстурированы.", + "labels.bottomFaces": "Нижние грани", + "tooltips.bottomFaces": "Подавить текстуру на поверхностях, обращённых вниз, в пределах этого угла от горизонтали", + "labels.topFaces": "Верхние грани", + "tooltips.topFaces": "Подавить текстуру на поверхностях, обращённых вверх, в пределах этого угла от горизонтали", + "sections.surfaceMasking": "По поверхности ⓘ", + "sections.surfaceSelection": "Выбор поверхности", + "tooltips.surfaceMasking": "Маскируйте поверхности, чтобы контролировать, какие области получат смещение.", + "tooltips.surfaceSelection": "Выбранные поверхности отображаются зелёным и будут единственными, которые получат смещение при экспорте.", + "excl.modeExclude": "Исключить", + "excl.modeExcludeTitle": "Режим исключения: закрашенные поверхности не будут получать смещение текстуры", + "excl.modeIncludeOnly": "Только включить", + "excl.modeIncludeOnlyTitle": "Режим «только включить»: только закрашенные поверхности будут получать смещение текстуры", + "excl.toolBrush": "Кисть", + "excl.toolBrushTitle": "Кисть: закрасьте треугольники, чтобы исключить их", + "excl.toolFill": "Заливка", + "excl.toolFillTitle": "Заливка ведром: заливка поверхности до порогового угла", + "excl.shiftHint": "Удерживайте Shift для стирания", + "labels.type": "Тип", + "brushType.single": "Одиночный", + "brushType.circle": "Круг", + "labels.size": "Размер", + "labels.maxAngle": "Макс. угол", + "tooltips.maxAngle": "Максимальный двугранный угол между соседними треугольниками, через который может перейти заливка", + "ui.clearAll": "Очистить всё", + "excl.initExcluded": "0 граней замаскировано", + "excl.faceExcluded": "{n} грань замаскирована", + "excl.facesExcluded": "{n} граней замаскировано", + "excl.faceSelected": "{n} грань выбрана", + "excl.facesSelected": "{n} граней выбрано", + "excl.hintExclude": "Замаскированные поверхности отображаются оранжевым и не будут получать смещение при экспорте.", + "excl.hintInclude": "Выбранные поверхности отображаются зелёным и будут единственными, которые получат смещение при экспорте.", + "precision.label": "Точность (Beta) ⓘ", + "precision.labelTitle": "Подразделить сетку в фоне, чтобы кисть выбирала с более мелкой гранулярностью", + "precision.outdated": "⚠ Устарело", + "precision.refreshTitle": "Повторно подразделить сетку в соответствии с текущим размером кисти", + "precision.triCount": "{n} △", + "precision.refining": "Уточнение…", + "precision.warningBody": "Примерно ~{n} треугольников. Это может замедлить ваш браузер. Продолжить?", + "labels.boundaryFalloff": "Плавная маска ⓘ", + "tooltips.boundaryFalloff": "Постепенно уменьшает смещение до нуля возле замаскированных границ, предотвращая перекрытие треугольников на стыке текстурированных и нетекстурированных областей.", + "labels.symmetricDisplacement": "Симметричное смещение ⓘ", + "tooltips.symmetricDisplacement": "Когда включено, 50% серый = нет смещения; белый выдавливает наружу, чёрный вдавливает внутрь. Сохраняет объём детали примерно постоянным.", + "labels.displacementPreview": "3D предпросмотр ⓘ", + "tooltips.displacementPreview": "Подразделяет сетку и смещает вершины в реальном времени, чтобы вы могли оценить фактическую глубину. Требует ресурсов GPU на сложных моделях.", + "ui.placeOnFace": "Разместить на грани", + "ui.placeOnFaceTitle": "Нажмите на грань, чтобы сориентировать её вниз на рабочую платформу", + "ui.rotate": "Повернуть", + "ui.rotateTitle": "Вручную повернуть модель вокруг осей X, Y, Z", + "ui.rotateApply": "Применить", + "ui.rotateReset": "Сбросить", + "progress.subdividingPreview": "Подготовка предпросмотра…", + "warnings.textureHeightOverlap": "⚠ Высота текстуры превышает 10% наименьшего размера модели — возможны перекрытия геометрии в экспортированном STL.", + "sections.advancedFeatures": "Расширенные / бета-функции ⓘ", + "tooltips.advancedFeatures": "Экспериментальные инструменты — поведение может меняться между версиями.", + "ui.advancedBlurb": "Экспериментальные инструменты. Поведение может меняться между версиями.", + "ui.bakeTexturesHeading": "Запекание текстур", + "ui.bakeTexturesDesc": "Применить текущую текстуру к сетке и загрузить результат в качестве рабочей модели, чтобы продолжить редактирование.", + "ui.bakeTextures": "Запечь текстуры", + "tooltips.bakeTextures": "Применить текущую текстуру к сетке и перезагрузить результат как рабочую модель.", + "ui.bakeMaskNewFaces": "Замаскировать только что запечённые грани от дальнейшего текстурирования", + "ui.noDownwardZHeading": "Защита от нависаний", + "ui.noDownwardZDesc": "Некоторые текстуры смещают вершины поверхности вниз, создавая новые нависания. При включении вершины никогда не перемещаются в направлении −Z во время текстурирования. Перемещение по X и Y не затрагивается.", + "ui.noDownwardZ": "Предотвратить смещение вершин вниз (−Z)", + "ui.smoothBottomHeading": "Сгладить дно", + "ui.smoothBottomDesc": "Привязывает любую вершину в пределах 0.1 мм от нижней плоскости к ней после текстурирования. Сохраняет поверхность контакта с платформой идеально плоской, чтобы слайсеры не затеняли мелкие перепады высот на нижних участках.", + "ui.smoothBottom": "Привязать вершины, близкие к нижней плоскости, к нижней плоскости", + "ui.enableMeshRegularization": "Включить регуляризацию сетки", + "alerts.bakeFailed": "Запекание не удалось: {msg}", + "progress.finalizing": "Завершение…", + "sections.export": "Экспорт ⓘ", + "tooltips.export": "Меньшая длина ребра = более мелкая детализация смещения. Затем результат децимируется до лимита треугольников.", + "labels.resolution": "Разрешение (мм)", + "tooltips.resolution": "Рёбра длиннее этого значения будут разделены при экспорте", + "warnings.resolutionTooCoarse": "⚠ Разрешение грубее 1/100 диагонали ограничивающего объёма модели — мелкие детали будут потеряны. Уменьшите значение для более точного результата.", + "labels.smartRes": "Предложенные значения (измените по вкусу)", + "tooltips.smartRes": "Устанавливает Разрешение и Макс. треугольники на основе детализации активной текстуры, площади поверхности модели и амплитуды смещения.", + "ui.smartResInfo": "Smart: {edge} мм · макс {tris} тр · PPE {ppe} · пиксель {pix} мм · поверхность {area} см²", + "ui.smartResBudgetCapped": "Ограничено по памяти", + "labels.outputTriangles": "Выходные треугольники", + "tooltips.outputTriangles": "Сетка сначала полностью подразделяется, затем децимируется до этого количества", + "warnings.safetyCapHit": "⚠ Достигнут предохранительный лимит в 16 млн треугольников при подразделении — результат может быть грубее запрошенной длины ребра.", + "ui.exportStl": "Экспорт STL", + "ui.export3mf": "Экспорт 3MF", + "tooltips.exportStl": "Широкая совместимость со всеми слайсерами", + "tooltips.export3mf": "Меньший размер файла — может не приниматься всеми слайсерами", + "progress.writing3mf": "Запись 3MF…", + "progress.subdividing": "Подразделение сетки…", + "progress.refining": "Уточнение: {cur} треугольников, самое длинное ребро {edge}", + "progress.regularizing": "Регуляризация узких треугольников…", + "progress.applyingDisplacement": "Применение смещения к {n} треугольникам…", + "progress.displacingVertices": "Смещение вершин…", + "progress.decimatingTo": "Упрощение {from} → {to} треугольников…", + "progress.decimating": "Упрощение: {cur} → {to} треугольников", + "progress.writingStl": "Запись STL…", + "progress.done": "Готово!", + "progress.processing": "Обработка…", + "license.btn": "Лицензия и условия", + "license.title": "Лицензия и условия", + "license.item1": "Бесплатно для использования в любых целях, включая коммерческие работы (например, текстурирование STL для клиентов или продуктов).", + "license.item2": "Упоминание автора приветствуется, но не обязательно при использовании этого инструмента как есть.", + "license.item3": "Поддержать этот инструмент? Магазин на CNCKitchen.STORE или отправьте чаевые через PayPal / Ko-fi.", + "license.item4": "Этот инструмент предоставляется как есть без каких-либо гарантий. Используйте на свой страх и риск.", + "license.item5": "Поддержка не предоставляется. Автор не обязан исправлять ошибки, отвечать на вопросы или обновлять этот инструмент. Тем не менее, сообщения об ошибках и запросы функций всегда приветствуются по адресу texturizer@cnckitchen.com.", + "license.item6": "Автор не несёт ответственности за любой ущерб, потерю данных или проблемы, возникшие в результате использования этого инструмента.", + "license.item7": "Хотите лицензировать или встроить этот инструмент для своего бизнеса или сайта? Свяжитесь с нами по адресу contact@cnckitchen.com.", + "license.item8": "Исходный код доступен на GitHub.", + "imprint.btn": "Выходные данные и конфиденциальность", + "imprint.title": "Выходные данные и политика конфиденциальности", + "imprint.sectionImprint": "Выходные данные (Impressum)", + "imprint.info": "CNC Kitchen
Stefan Hermann
Bahnhofstr. 2
88145 Hergatz
Германия", + "imprint.contact": "Email: contact@cnckitchen.com
Телефон: +49 175 2011824
Номер телефона только для юридических/деловых запросов — не для поддержки.", + "imprint.odr": "Платформа онлайн-урегулирования споров ЕС: https://ec.europa.eu/consumers/odr", + "imprint.sectionPrivacy": "Политика конфиденциальности (Datenschutzerklärung)", + "imprint.privacyIntro": "Ответственная сторона (Verantwortlicher gem. Art. 4 Abs. 7 DSGVO): Stefan Hermann, Bahnhofstr. 2, 88145 Hergatz, Германия.", + "imprint.privacyHosting": "Этот сайт размещён на GitHub Pages (GitHub Inc. / Microsoft Corp., 88 Colin P Kelly Jr St, San Francisco, CA 94107, USA). При посещении этого сайта GitHub может обрабатывать ваш IP-адрес в журналах сервера. Правовое основание: ст. 6(1)(f) DSGVO (законный интерес в предоставлении веб-сайта). См. Заявление о конфиденциальности GitHub.", + "imprint.privacyLocal": "Этот инструмент хранит пользовательские настройки (язык, тему) в localStorage вашего браузера. Эти данные никогда не покидают ваше устройство и не передаются на сервер.", + "imprint.privacyNoCookies": "Этот веб-сайт не использует файлы cookie, аналитику или любые технологии отслеживания.", + "imprint.privacyExternal": "Этот сайт содержит ссылки на внешние веб-сайты (например CNCKitchen.STORE, PayPal, Ko-fi). Эти сайты имеют свои собственные политики конфиденциальности, на которые мы не можем повлиять.", + "imprint.privacyRights": "В соответствии с GDPR вы имеете право на доступ, исправление, удаление, ограничение обработки, переносимость данных, а также право подать жалобу в надзорный орган.", + "sponsor.title": "Спасибо за использование BumpMesh от CNC Kitchen!", + "sponsor.body": "Этот инструмент предоставляется абсолютно бесплатно CNC Kitchen.
Пока обрабатывается ваш STL, почему бы не заглянуть в магазин, который помогает нам продолжать создавать для вас крутые вещи?", + "sponsor.visitStore": "🛒 Посетить CNCKitchen.STORE", + "sponsor.donate": "💙 Отправить чаевые через PayPal", + "sponsor.donateKofi": "☕ Отправить чаевые через Ko-fi", + "sponsor.dontShow": "Больше не показывать это", + "sponsor.closeAndContinue": "Закрыть и продолжить", + "cta.store": "Поддержать этот инструмент? Магазин на CNCKitchen.STORE или отправьте чаевые через PayPal / Ko-fi", + "cta.storeDismiss": "Отклонить", + "alerts.loadFailed": "Не удалось загрузить модель: {msg}", + "alerts.exportFailed": "Экспорт не удался: {msg}", + "alerts.exportOOM": "Экспорт не удался: у модели закончилась память во время подразделения.\n\nЭто происходит, когда сетка требует слишком много треугольников при запрошенном разрешении.\n\nКак исправить:\n\u2022 Увеличьте значение Разрешения (мм), чтобы получить меньше треугольников", + "alerts.fileTooLarge": "Файл слишком большой ({size} МБ). Максимум: {max} МБ.", + "alerts.degenerateTrianglesRemoved": "{n} недопустимых треугольников (координаты NaN или нулевая площадь) были удалены из сетки при загрузке. Модель по-прежнему будет работать корректно.", + "diag.runAdvanced": "Запустить расширенную проверку", + "diag.runAdvancedTitle": "Проверить на пересекающиеся и перекрывающиеся треугольники (может занять время на больших сетках)", + "diag.running": "Проверка…", + "diag.meshOk": "✔ Сетка выглядит хорошо", + "diag.openEdges": "{n} открытых рёбер — сетка не герметична", + "diag.nonManifoldEdges": "{n} не-многообразие рёбер", + "diag.multipleShells": "{n} несвязанных оболочек", + "diag.intersectingTris": "{n} пар пересекающихся треугольников", + "diag.overlappingTris": "{n} перекрывающихся/дублирующих треугольников", + "diag.advancedOk": "✔ Пересечений или наложений не найдено", + "diag.recommendFix": "Исправьте эти проблемы в вашем CAD-программном обеспечении, слайсере или онлайн перед текстурированием.", + "diag.show": "Показать", + "diag.hide": "Скрыть", + "header.exportProject": "Сохранить проект (.bumpmesh)", + "header.importProject": "Загрузить проект (.bumpmesh)", + "header.resetSettings": "Сбросить настройки по умолчанию", + "header.undo": "Отменить (Ctrl+Z)", + "header.redo": "Повторить (Ctrl+Shift+Z)", + "alerts.resetConfirm": "Сбросить все настройки до значений по умолчанию?", + "header.exportSettingsLabel": "Настройки", + "header.exportModelLabel": "Модель (STL)", + "header.exportTextureLabel": "Пользовательская текстура", + "header.exportGo": "Сохранить", + "alerts.importFailed": "Не удалось загрузить проект: {msg}", + "labels.snapSeamless": "Привязать к бесшовной обёртке ⓘ", + "tooltips.snapSeamless": "Привязывает масштаб U к целому числу оборотов, чтобы текстура бесшовно оборачивалась вокруг цилиндра.", + "labels.cylinderAxis": "Ось цилиндра", + "ui.cylinderAutofit": "Автоподгонка", + "tooltips.cylinderAutofit": "Подгоняет окружность к обращённым наружу вершинам детали (метод наименьших квадратов).", + "ui.cylinderReset": "Сброс", + "tooltips.cylinderReset": "Сбрасывает ось к центру ограничивающего объёма и радиусу, полученному из ограничивающего объёма.", + "ui.cylinderPanelAria": "Размещение оси цилиндра", + "ui.cylinderPanelLabel": "Определить проекцию цилиндра", + "ui.cylinderNoModel1": "Загрузите модель для позиционирования", + "ui.cylinderNoModel2": "оси цилиндра", + "ui.cylinderPanelMinimize": "Свернуть / восстановить" +}; \ No newline at end of file