feat(protobufs): sync to firmware-current and consume workspace package (#1097)

* feat(protobufs): sync to firmware-current and consume workspace package

Sync the vendored .proto sources to firmware-current (v2.7.25+48), regenerate the v2 TS bindings, and consume the workspace @meshtastic/protobufs (workspace:*) in place of the stale JSR 2.7.20 — finishing the monorepo migration (core was already workspace:*).

Includes the one required breaking-change fix: admin nodedb_reset changed int32 to bool, so resetNodes() now sends value: true.

* build(protobufs): vendor generated bindings for workspace consumers

The package is consumed via workspace:* — its exports point at the TS source, which imports ./dist/meshtastic/*_pb.ts — so the generated output must exist at build time. CI builds web/core with no codegen step and the runners have no buf CLI, so the bindings are vendored here (kept gitignored; lint/format skip them). Regenerate with: pnpm --filter @meshtastic/protobufs gen

* fix(protobufs): clean script removes the actual generated output dir

buf writes bindings to packages/ts/dist, but clean was removing a non-existent root dist — so it never cleaned stale output. Addresses Copilot review feedback.

* refactor: move web app packages/web -> apps/web

Aligns the web app with the apps/web layout (matching the Vercel web-test Root Directory and the SDK-migration direction). Pure directory move plus root config: pnpm-workspace (adds apps/*), vitest projects, root tsconfig reference, and the pr/release-web/nightly workflows. vercel.json moved with the app. Build + 36 validation tests green.

* feat: config fields, module pages, key verification, telemetry capture

Incorporates the firmware-current feature work onto the protobuf foundation: new config fields (Display message bubbles; LoRa fem_lna_mode + serial_hal_only; Telemetry air_quality_screen_enabled); 4 new ModuleConfig pages (TrafficManagement, StatusMessage, TAK, RemoteHardware); the manual Key Verification flow (sendKeyVerification + ClientNotificationDialog stages + Verify Key button); live telemetry capture (nodeDB addDeviceMetrics) and admin hardening (toggleMutedNode, graceful PortNum default); plus the sdk-preview ConfigEditor demo and store/config tests. Build + lint + format + 131 tests green.

* chore: drop #1062 (unsaved-change-detection) to match upstream revert

#1062 was merged to main by accident (per @danditomaso) and is being reverted. Reverse-applied its diff here via 3-way so #1097 stays consistent with where main is headed, while keeping the feature changes layered on the same files (deviceStore/changeRegistry). Build + 131 tests + lint + format green.

* fix(nodes): clean up SNR display in node table and map popup

SNR is a ratio measured in dB, not dBm (which is absolute power); the
node table and map popup both mislabeled it and crammed three values
together: '0dBm/50%/50raw'. The trailing '%/raw' pair was the same
heuristic ((snr+10)*5) shown twice — once clamped, once not.

Render SNR in dB rounded to one decimal, color-coded by a 0-100%
signal-quality heuristic (green/yellow/red), with the quality percentage
as a muted secondary. Drop the redundant raw value. Adds unit.db; this
matches the existing SNRTooltip, which already renders dB.
This commit is contained in:
Ben Meadors
2026-06-15 13:23:28 -05:00
committed by GitHub
parent 7a8529b841
commit bbe9a0d5cd
695 changed files with 27038 additions and 786 deletions
@@ -0,0 +1,71 @@
{
"page": {
"sectionLabel": "Каналы",
"channelName": "Канал: {{channelName}}",
"broadcastLabel": "Первичный",
"channelIndex": "Канал {{index}}",
"import": "Импорт",
"export": "Экспорт"
},
"validation": {
"pskInvalid": "Введите корректный PSK длиной {{bits}} бит."
},
"settings": {
"label": "Настройки канала",
"description": "Шифрование, MQTT и прочие настройки"
},
"role": {
"label": "Роль",
"description": "Телеметрия устройства отправляется по ПЕРВИЧНОМУ каналу. Допускается только один ПЕРВИЧНЫЙ канал",
"options": {
"primary": "ПЕРВИЧНЫЙ",
"disabled": "ОТКЛЮЧЕН",
"secondary": "ВТОРИЧНЫЙ"
}
},
"psk": {
"label": "Pre-Shared Key (PSK)",
"description": "Поддерживаемая длина PSK: 256 бит, 128 бит, 8 бит, пустой (0 бит)",
"generate": "Сгенерировать"
},
"name": {
"label": "Имя",
"description": "Уникальное имя канала (до 12 байт); оставьте пустым для значения по умолчанию"
},
"uplinkEnabled": {
"label": "Аплинк включён",
"description": "Отправлять сообщения из локальной mesh-сети в MQTT"
},
"downlinkEnabled": {
"label": "Даунлинк включён",
"description": "Отправлять сообщения из MQTT в локальную mesh-сеть"
},
"positionPrecision": {
"label": "Местоположение",
"description": "Точность местоположения для обмена в канале. Можно отключить.",
"options": {
"none": "Не делиться местоположением",
"precise": "Точное местоположение",
"metric_km23": "В пределах 23 километров",
"metric_km12": "В пределах 12 километров",
"metric_km5_8": "В пределах 5,8 километра",
"metric_km2_9": "В пределах 2,9 километра",
"metric_km1_5": "В пределах 1,5 километра",
"metric_m700": "В пределах 700 метров",
"metric_m350": "В пределах 350 метров",
"metric_m200": "В пределах 200 метров",
"metric_m90": "В пределах 90 метров",
"metric_m50": "В пределах 50 метров",
"imperial_mi15": "В пределах 15 миль",
"imperial_mi7_3": "В пределах 7,3 мили",
"imperial_mi3_6": "В пределах 3,6 мили",
"imperial_mi1_8": "В пределах 1,8 мили",
"imperial_mi0_9": "В пределах 0,9 мили",
"imperial_mi0_5": "В пределах 0,5 мили",
"imperial_mi0_2": "В пределах 0,2 мили",
"imperial_ft600": "В пределах 600 футов",
"imperial_ft300": "В пределах 300 футов",
"imperial_ft150": "В пределах 150 футов"
}
}
}
@@ -0,0 +1,51 @@
{
"emptyState": "Результаты не найдены.",
"page": {
"title": "Командное меню"
},
"pinGroup": {
"label": "Закрепить группу команд"
},
"unpinGroup": {
"label": "Открепить группу команд"
},
"goto": {
"label": "Перейти",
"command": {
"messages": "Сообщения",
"map": "Карта",
"config": "Настройки",
"nodes": "Ноды"
}
},
"manage": {
"label": "Управление",
"command": {
"switchNode": "Переключить ноду",
"connectNewNode": "Подключить новую ноду"
}
},
"contextual": {
"label": "Контекстные",
"command": {
"qrCode": "QR-код",
"qrGenerator": "Генератор",
"qrImport": "Импорт",
"scheduleShutdown": "Запланировать выключение",
"scheduleReboot": "Перезагрузить устройство",
"resetNodeDb": "Сбросить базу нод",
"dfuMode": "Войти в режим DFU",
"factoryResetDevice": "Сброс устройства к заводским настройкам",
"factoryResetConfig": "Сброс настроек к заводским",
"disconnect": "Отключиться"
}
},
"debug": {
"label": "Отладка",
"command": {
"reconfigure": "Перенастроить",
"clearAllStoredMessages": "Очистить все сохранённые сообщения",
"clearAllStores": "Очистить всё локальное хранилище"
}
}
}
@@ -0,0 +1,131 @@
{
"button": {
"apply": "Применить",
"addConnection": "Добавить подключение",
"saveConnection": "Сохранить подключение",
"backupKey": "Резервная копия ключа",
"cancel": "Отмена",
"connect": "Подключиться",
"clearMessages": "Очистить сообщения",
"close": "Закрыть",
"confirm": "Подтвердить",
"delete": "Удалить",
"dismiss": "Скрыть",
"download": "Скачать",
"disconnect": "Отключиться",
"export": "Экспорт",
"generate": "Сгенерировать",
"regenerate": "Сгенерировать заново",
"import": "Импорт",
"message": "Сообщение",
"now": "Сейчас",
"ok": "ОК",
"print": "Печать",
"remove": "Удалить",
"requestNewKeys": "Запросить новые ключи",
"requestPosition": "Запросить позицию",
"reset": "Сброс",
"retry": "Повторить",
"save": "Сохранить",
"setDefault": "Сделать по умолчанию",
"unsetDefault": "Снять по умолчанию",
"scanQr": "Сканировать QR-код",
"traceRoute": "Трассировка маршрута",
"submit": "Отправить"
},
"app": {
"title": "Meshtastic",
"fullTitle": "Веб-клиент Meshtastic"
},
"loading": "Загрузка...",
"unit": {
"cps": "CPS",
"dbm": "dBm",
"hertz": "Гц",
"hop": {
"one": "прыжок",
"plural": "прыжков"
},
"hopsAway": {
"one": "{{count}} прыжок от вас",
"plural": "{{count}} прыжков от вас",
"unknown": "Неизвестно, сколько прыжков"
},
"megahertz": "МГц",
"kilohertz": "кГц",
"raw": "сырое",
"meter": { "one": "метр", "plural": "метров", "suffix": "м" },
"kilometer": { "one": "километр", "plural": "километров", "suffix": "км" },
"minute": { "one": "минута", "plural": "минут" },
"hour": { "one": "час", "plural": "часов" },
"millisecond": {
"one": "миллисекунда",
"plural": "миллисекунд",
"suffix": "мс"
},
"second": { "one": "секунда", "plural": "секунд" },
"day": {
"one": "день",
"plural": "дней",
"today": "Сегодня",
"yesterday": "Вчера"
},
"month": { "one": "месяц", "plural": "месяцев" },
"year": { "one": "год", "plural": "лет" },
"snr": "SNR",
"volt": { "one": "вольт", "plural": "вольт", "suffix": "В" },
"record": { "one": "запись", "plural": "записей" },
"degree": { "one": "градус", "plural": "градусов", "suffix": "°" }
},
"security": {
"0bit": "Пусто",
"8bit": "8 бит",
"128bit": "128 бит",
"256bit": "256 бит"
},
"unknown": {
"longName": "Неизвестно",
"shortName": "Н/Д",
"notAvailable": "Н/Д",
"num": "??"
},
"nodeUnknownPrefix": "!",
"unset": "НЕ ЗАДАНО",
"fallbackName": "Meshtastic {{last4}}",
"node": "Нода",
"formValidation": {
"unsavedChanges": "Есть несохранённые изменения",
"tooBig": {
"string": "Слишком длинно, ожидается не более {{maximum}} символов.",
"number": "Слишком большое значение, ожидается число не более {{maximum}}.",
"bytes": "Слишком большое значение, ожидается не более {{params.maximum}} байт."
},
"tooSmall": {
"string": "Слишком коротко, ожидается не менее {{minimum}} символов.",
"number": "Слишком маленькое значение, ожидается число не менее {{minimum}}."
},
"invalidFormat": {
"ipv4": "Неверный формат, ожидается IPv4-адрес.",
"key": "Неверный формат, ожидается Pre-Shared Key (PSK), закодированный в Base64."
},
"invalidType": {
"number": "Неверный тип, ожидается число."
},
"pskLength": {
"0bit": "Ключ должен быть пустым.",
"8bit": "Ключ должен быть Pre-Shared Key (PSK) длиной 8 бит.",
"128bit": "Ключ должен быть Pre-Shared Key (PSK) длиной 128 бит.",
"256bit": "Ключ должен быть Pre-Shared Key (PSK) длиной 256 бит."
},
"required": {
"generic": "Это поле обязательно.",
"managed": "Для управляемой ноды требуется хотя бы один ключ администратора.",
"key": "Ключ обязателен."
},
"invalidOverrideFreq": {
"number": "Неверный формат, ожидается значение в диапазоне 410–930 МГц или 0 (использовать по умолчанию)."
}
},
"yes": "Да",
"no": "Нет"
}
@@ -0,0 +1,470 @@
{
"page": {
"title": "Настройки",
"tabUser": "Пользователь",
"tabChannels": "Каналы",
"tabBluetooth": "Bluetooth",
"tabDevice": "Устройство",
"tabDisplay": "Экран",
"tabLora": "LoRa",
"tabNetwork": "Сеть",
"tabPosition": "Позиция",
"tabPower": "Питание",
"tabSecurity": "Безопасность"
},
"sidebar": {
"label": "Конфигурация"
},
"device": {
"title": "Настройки устройства",
"description": "Настройки устройства",
"buttonPin": {
"description": "Переопределение пина кнопки",
"label": "Пин кнопки"
},
"buzzerPin": {
"description": "Переопределение пина зуммера",
"label": "Пин зуммера"
},
"disableTripleClick": {
"description": "Отключить тройное нажатие",
"label": "Отключить тройное нажатие"
},
"doubleTapAsButtonPress": {
"description": "Считать двойной тап нажатием кнопки",
"label": "Двойной тап как нажатие"
},
"ledHeartbeatDisabled": {
"description": "Отключить стандартный мигающий LED",
"label": "Отключить индикатор"
},
"nodeInfoBroadcastInterval": {
"description": "Как часто рассылать информацию о ноде",
"label": "Интервал рассылки информации о ноде"
},
"posixTimezone": {
"description": "Строка POSIX часового пояса устройства",
"label": "Часовой пояс POSIX"
},
"rebroadcastMode": {
"description": "Как обрабатывать ретрансляцию",
"label": "Режим ретрансляции"
},
"role": {
"description": "Какую роль устройство выполняет в mesh-сети",
"label": "Роль"
}
},
"bluetooth": {
"title": "Настройки Bluetooth",
"description": "Настройки модуля Bluetooth",
"note": "Примечание: некоторые устройства (ESP32) не могут использовать Bluetooth и WiFi одновременно.",
"enabled": {
"description": "Включить или отключить Bluetooth",
"label": "Включено"
},
"pairingMode": {
"description": "Поведение выбора PIN.",
"label": "Режим сопряжения"
},
"pin": {
"description": "PIN для сопряжения",
"label": "PIN"
}
},
"display": {
"description": "Настройки экрана устройства",
"title": "Настройки экрана",
"headingBold": {
"description": "Сделать заголовок жирным",
"label": "Жирный заголовок"
},
"carouselDelay": {
"description": "Скорость переключения окон",
"label": "Задержка карусели"
},
"compassNorthTop": {
"description": "Зафиксировать север вверху компаса",
"label": "Север сверху"
},
"displayMode": {
"description": "Вариант компоновки экрана",
"label": "Режим отображения"
},
"displayUnits": {
"description": "Показывать метрические или имперские единицы",
"label": "Единицы измерения"
},
"flipScreen": {
"description": "Повернуть экран на 180 градусов",
"label": "Повернуть экран"
},
"gpsDisplayUnits": {
"description": "Формат отображения координат",
"label": "Единицы GPS"
},
"oledType": {
"description": "Тип OLED-экрана, подключённого к устройству",
"label": "Тип OLED"
},
"screenTimeout": {
"description": "Выключать экран через это время",
"label": "Тайм-аут экрана"
},
"twelveHourClock": {
"description": "Использовать 12-часовой формат времени",
"label": "12-часовой формат"
},
"wakeOnTapOrMotion": {
"description": "Пробуждать устройство по касанию или движению",
"label": "Пробуждать по касанию или движению"
}
},
"lora": {
"title": "Настройки mesh-сети",
"description": "Настройки LoRa для mesh-сети",
"bandwidth": {
"description": "Ширина канала в кГц",
"label": "Ширина полосы"
},
"boostedRxGain": {
"description": "Усиленный RX Gain",
"label": "Усиленный RX Gain"
},
"codingRate": {
"description": "Знаменатель скорости кодирования",
"label": "Скорость кодирования"
},
"frequencyOffset": {
"description": "Смещение частоты для компенсации ошибок калибровки кварца",
"label": "Смещение частоты"
},
"frequencySlot": {
"description": "Номер частотного канала LoRa",
"label": "Частотный слот"
},
"hopLimit": {
"description": "Максимальное число прыжков",
"label": "Лимит прыжков"
},
"ignoreMqtt": {
"description": "Не пересылать сообщения MQTT по mesh-сети",
"label": "Игнорировать MQTT"
},
"modemPreset": {
"description": "Используемый пресет модема",
"label": "Пресет модема"
},
"okToMqtt": {
"description": "Если установлено значение true, эта конфигурация указывает, что пользователь разрешает выгрузку пакета в MQTT. Если установлено значение false, удалённым нодам предлагается не пересылать пакеты в MQTT",
"label": "Разрешено в MQTT"
},
"overrideDutyCycle": {
"description": "Переопределить рабочий цикл",
"label": "Переопределить рабочий цикл"
},
"overrideFrequency": {
"description": "Переопределить частоту",
"label": "Переопределить частоту"
},
"region": {
"description": "Задаёт регион для вашей ноды",
"label": "Регион"
},
"spreadingFactor": {
"description": "Количество чирпов на символ",
"label": "Фактор расширения"
},
"transmitEnabled": {
"description": "Включить/выключить передачу (TX) для LoRa",
"label": "Передача включена"
},
"transmitPower": {
"description": "Максимальная мощность передачи",
"label": "Мощность передачи"
},
"usePreset": {
"description": "Использовать один из предопределённых пресетов модема",
"label": "Использовать пресет"
},
"meshSettings": {
"description": "Настройки LoRa для mesh-сети",
"label": "Настройки mesh-сети"
},
"waveformSettings": {
"description": "Настройки формы сигнала LoRa",
"label": "Настройки формы сигнала"
},
"radioSettings": {
"label": "Настройки радио",
"description": "Настройки LoRa-радиомодуля"
}
},
"network": {
"title": "Настройки WiFi",
"description": "Конфигурация WiFi-радио",
"note": "Примечание: некоторые устройства (ESP32) не могут использовать Bluetooth и WiFi одновременно.",
"addressMode": {
"description": "Выбор способа назначения адреса",
"label": "Режим адресации"
},
"dns": {
"description": "DNS-сервер",
"label": "DNS"
},
"ethernetEnabled": {
"description": "Включить или отключить Ethernet-порт",
"label": "Включено"
},
"gateway": {
"description": "Шлюз по умолчанию",
"label": "Шлюз"
},
"ip": {
"description": "IP-адрес",
"label": "IP"
},
"psk": {
"description": "Пароль сети",
"label": "PSK"
},
"ssid": {
"description": "Имя сети",
"label": "SSID"
},
"subnet": {
"description": "Маска подсети",
"label": "Подсеть"
},
"wifiEnabled": {
"description": "Включить или отключить WiFi-радио",
"label": "Включено"
},
"meshViaUdp": {
"label": "Mesh-сеть через UDP"
},
"ntpServer": {
"label": "NTP-сервер"
},
"rsyslogServer": {
"label": "Rsyslog-сервер"
},
"ethernetConfigSettings": {
"description": "Конфигурация Ethernet-порта",
"label": "Настройки Ethernet"
},
"ipConfigSettings": {
"description": "IP-конфигурация",
"label": "Настройки IP"
},
"ntpConfigSettings": {
"description": "Конфигурация NTP",
"label": "Настройки NTP"
},
"rsyslogConfigSettings": {
"description": "Конфигурация Rsyslog",
"label": "Настройки Rsyslog"
},
"udpConfigSettings": {
"description": "Конфигурация UDP поверх mesh-сети",
"label": "Настройки UDP"
}
},
"position": {
"title": "Настройки позиции",
"description": "Настройки модуля позиционирования",
"broadcastInterval": {
"description": "Как часто ваша позиция отправляется по mesh-сети",
"label": "Интервал рассылки"
},
"enablePin": {
"description": "Переопределение пина включения GPS-модуля",
"label": "Пин включения"
},
"fixedPosition": {
"description": "Не передавать GPS-позицию, а использовать указанную вручную",
"label": "Фиксированная позиция",
"latitude": {
"label": "Широта",
"description": "Десятичные градусы между -90 и 90 (например, 37.7749)"
},
"longitude": {
"label": "Долгота",
"description": "Десятичные градусы между -180 и 180 (например, -122.4194)"
},
"altitude": {
"label": "Высота",
"description": "Необязательно — введите высоту в {{unit}} над уровнем моря (например, 100). Оставьте пустым, если неизвестно, или добавьте высоту для антенн/мачт."
}
},
"gpsMode": {
"description": "Настройте, включён ли GPS устройства, выключен или отсутствует",
"label": "Режим GPS"
},
"gpsUpdateInterval": {
"description": "Как часто следует получать GPS-фикс",
"label": "Интервал обновления GPS"
},
"positionFlags": {
"description": "Необязательные поля для включения в сообщения о позиции. Чем больше полей выбрано, тем больше будет сообщение, что приводит к увеличению времени в эфире и риску потери пакетов.",
"label": "Флаги позиции"
},
"receivePin": {
"description": "Переопределение RX-пина GPS-модуля",
"label": "Пин приёма"
},
"smartPositionEnabled": {
"description": "Отправлять позицию только при значимом изменении",
"label": "Включить умную позицию"
},
"smartPositionMinDistance": {
"description": "Минимальная дистанция (в метрах), которую нужно пройти перед отправкой обновления",
"label": "Мин. дистанция умной позиции"
},
"smartPositionMinInterval": {
"description": "Минимальный интервал (в секундах), который должен пройти перед отправкой обновления",
"label": "Мин. интервал умной позиции"
},
"transmitPin": {
"description": "Переопределение TX-пина GPS-модуля",
"label": "Пин передачи"
},
"intervalsSettings": {
"description": "Как часто отправлять обновления позиции",
"label": "Интервалы"
},
"flags": {
"placeholder": "Выберите флаги позиции...",
"altitude": "Высота",
"altitudeGeoidalSeparation": "Геоидальная разность высот",
"altitudeMsl": "Высота — средний уровень моря",
"dop": "Размытость точности (DOP), по умолчанию используется PDOP",
"hdopVdop": "Если DOP задан, использовать значения HDOP/VDOP вместо PDOP",
"numSatellites": "Количество спутников",
"sequenceNumber": "Порядковый номер",
"timestamp": "Временная метка",
"unset": "Не задано",
"vehicleHeading": "Курс",
"vehicleSpeed": "Скорость"
}
},
"power": {
"adcMultiplierOverride": {
"description": "Используется для коррекции показаний напряжения батареи",
"label": "Переопределение коэффициента ADC"
},
"ina219Address": {
"description": "Адрес монитора батареи INA219",
"label": "Адрес INA219"
},
"lightSleepDuration": {
"description": "Сколько устройство будет в лёгком сне",
"label": "Длительность лёгкого сна"
},
"minimumWakeTime": {
"description": "Минимальное время бодрствования после получения пакета",
"label": "Минимальное время бодрствования"
},
"noConnectionBluetoothDisabled": {
"description": "Если устройство не получает Bluetooth-подключение, BLE-радио будет отключено через это время",
"label": "Отключение Bluetooth при отсутствии подключения"
},
"powerSavingEnabled": {
"description": "Выберите, если питание от источника с малым током (например, солнечного), чтобы максимально снизить потребление.",
"label": "Включить режим энергосбережения"
},
"shutdownOnBatteryDelay": {
"description": "Автоматически выключать ноду через это время при питании от батареи, 0 — без ограничения",
"label": "Задержка выключения от батареи"
},
"superDeepSleepDuration": {
"description": "Сколько устройство будет в сверхглубоком сне",
"label": "Длительность сверхглубокого сна"
},
"powerConfigSettings": {
"description": "Настройки модуля питания",
"label": "Настройки питания"
},
"sleepSettings": {
"description": "Настройки сна модуля питания",
"label": "Настройки сна"
}
},
"security": {
"description": "Параметры безопасности",
"title": "Настройки безопасности",
"button_backupKey": "Резервная копия ключа",
"adminChannelEnabled": {
"description": "Разрешить входящее управление устройством через небезопасный устаревший админ-канал",
"label": "Разрешить устаревший админ"
},
"enableDebugLogApi": {
"description": "Выводить живой отладочный лог по COM-порту, просматривать и экспортировать логи устройства с удалением координат по Bluetooth",
"label": "Включить API отладочных логов"
},
"managed": {
"description": "Если включено, параметры устройства можно менять удалённо только через ноду Remote Admin с помощью админ-сообщений. Не включайте эту опцию, если не настроена хотя бы одна подходящая нода Remote Admin и её публичный ключ не сохранён в одном из полей выше.",
"label": "Управляемый режим"
},
"privateKey": {
"description": "Используется для создания общего ключа с удалённым устройством",
"label": "Приватный ключ"
},
"publicKey": {
"description": "Отправляется другим нодам в mesh-сети, чтобы они могли вычислить общий секретный ключ",
"label": "Публичный ключ"
},
"primaryAdminKey": {
"description": "Первичный публичный ключ, которому разрешено отправлять админ-сообщения этой ноде",
"label": "Первичный админ-ключ"
},
"secondaryAdminKey": {
"description": "Вторичный публичный ключ, которому разрешено отправлять админ-сообщения этой ноде",
"label": "Вторичный админ-ключ"
},
"serialOutputEnabled": {
"description": "Консоль COM-порта через Stream API",
"label": "Вывод через COM-порт включён"
},
"tertiaryAdminKey": {
"description": "Третичный публичный ключ, которому разрешено отправлять админ-сообщения этой ноде",
"label": "Третичный админ-ключ"
},
"adminSettings": {
"description": "Настройки администратора",
"label": "Настройки администратора"
},
"loggingSettings": {
"description": "Настройки логирования",
"label": "Настройки логирования"
}
},
"user": {
"title": "Настройки пользователя",
"description": "Настройте имя устройства и параметры идентификации",
"longName": {
"label": "Полное имя",
"description": "Ваше полное отображаемое имя (1–40 символов)",
"validation": {
"min": "Полное имя должно быть не короче 1 символа",
"max": "Полное имя должно быть не длиннее 40 символов"
}
},
"shortName": {
"label": "Короткое имя",
"description": "Сокращённое имя (2–4 символа)",
"validation": {
"min": "Короткое имя должно быть не короче 2 символов",
"max": "Короткое имя должно быть не длиннее 4 символов"
}
},
"isUnmessageable": {
"label": "Недоступен для сообщений",
"description": "Используется для обозначения необслуживаемых или инфраструктурных нод, чтобы отключить обмен сообщениями для нод, которые никогда не отвечают."
},
"isLicensed": {
"label": "Лицензированный радиолюбитель (HAM)",
"description": "Включите, если вы лицензированный радиолюбитель; это отключает шифрование и несовместимо с сетью Meshtastic по умолчанию."
}
}
}
@@ -0,0 +1,34 @@
{
"page": {
"title": "Подключение к устройству Meshtastic",
"description": "Добавьте подключение по HTTP, Bluetooth или COM-порту. Сохранённые подключения будут храниться в вашем браузере."
},
"connectionType_ble": "BLE",
"connectionType_serial": "COM-порт",
"connectionType_network": "Сеть",
"deleteConnection": "Удалить подключение",
"areYouSure": "Это удалит {{name}}. Это действие нельзя отменить.",
"moreActions": "Другие действия",
"noConnections": {
"title": "Подключений пока нет.",
"description": "Создайте первое подключение. Оно подключится сразу и сохранится на будущее."
},
"lastConnectedAt": "Последнее подключение: {{date}}",
"neverConnected": "Никогда не подключалось",
"toasts": {
"connected": "Подключено",
"nowConnected": "Подключено: {{name}}",
"nowDisconnected": "Отключено: {{name}}",
"disconnected": "Отключено",
"failed": "Не удалось подключиться",
"checkConnection": "Проверьте устройство или настройки и попробуйте снова",
"defaultSet": "По умолчанию",
"defaultConnection": "Теперь подключение по умолчанию: {{nameisconnected}}",
"deleted": "Удалено",
"deletedByName": "Удалено: {{name}}",
"pickConnectionAgain": "Не удалось подключиться. Возможно, нужно заново выбрать устройство/порт.",
"added": "Подключение добавлено",
"savedByName": "{{name}} сохранено.",
"savedCantConnect": "Подключение сохранено, но подключиться не удалось."
}
}
@@ -0,0 +1,238 @@
{
"deleteMessages": {
"description": "Это действие очистит всю историю сообщений. Это нельзя отменить. Вы уверены, что хотите продолжить?",
"title": "Очистить все сообщения"
},
"import": {
"description": "Импортируйте набор каналов по URL Meshtastic. <br />Корректные URL Meshtastic начинаются с \"<italic>https://meshtastic.org/e/...</italic>\"",
"error": {
"invalidUrl": "Некорректный URL Meshtastic"
},
"channelPrefix": "Канал ",
"primary": "Первичный ",
"doNotImport": "Не импортировать",
"channelName": "Имя",
"channelSlot": "Слот",
"channelSetUrl": "URL набора каналов/QR-кода",
"useLoraConfig": "Импортировать конфигурацию LoRa",
"presetDescription": "Текущая конфигурация LoRa будет заменена.",
"title": "Импорт каналов"
},
"locationResponse": {
"title": "Местоположение: {{identifier}}",
"altitude": "Высота: ",
"coordinates": "Координаты: ",
"noCoordinates": "Нет координат"
},
"pkiRegenerateDialog": {
"title": "Сгенерировать Pre-Shared Key заново?",
"description": "Вы уверены, что хотите пересоздать Pre-Shared Key?",
"regenerate": "Сгенерировать заново"
},
"addConnection": {
"title": "Добавить подключение",
"description": "Выберите тип подключения и заполните параметры",
"validation": {
"requiresWebBluetooth": "Для этого типа подключения требуется <0>Web Bluetooth</0>. Используйте поддерживаемый браузер, например Chrome или Edge.",
"requiresWebSerial": "Для этого типа подключения требуется <0>Web Serial</0>. Используйте поддерживаемый браузер, например Chrome или Edge.",
"requiresSecureContext": "Этому приложению требуется <0>безопасный контекст</0>. Подключайтесь через HTTPS или localhost.",
"additionallyRequiresSecureContext": "Кроме того, требуется <0>безопасный контекст</0>. Подключайтесь через HTTPS или localhost."
},
"bluetoothConnection": {
"namePlaceholder": "Моя Bluetooth-нода",
"supported": {
"title": "Web Bluetooth поддерживается"
},
"notSupported": {
"title": "Web Bluetooth не поддерживается",
"description": "Ваш браузер или устройство не поддерживает Web Bluetooth"
},
"short": "BT: {{deviceName}}",
"long": "Bluetooth-устройство",
"device": "Устройство",
"selectDevice": "Выберите устройство",
"selected": "Bluetooth-устройство выбрано",
"notSelected": "Устройство не выбрано",
"helperText": "Используется служба Meshtastic Bluetooth для обнаружения."
},
"serialConnection": {
"namePlaceholder": "Моя COM-нода",
"helperText": "Выбор порта даёт разрешение, чтобы приложение могло открыть его для подключения.",
"supported": {
"title": "Web Serial поддерживается"
},
"notSupported": {
"title": "Web Serial не поддерживается",
"description": "Ваш браузер или устройство не поддерживает Web Serial"
},
"portSelected": {
"title": "Порт выбран",
"description": "Разрешения на порт предоставлены."
},
"port": "Порт",
"selectPort": "Выберите порт",
"deviceName": "USB {{vendorId}}:{{productId}}",
"notSelected": "Порт не выбран"
},
"httpConnection": {
"namePlaceholder": "Моя HTTP-нода",
"inputPlaceholder": "192.168.1.10 или meshtastic.local",
"heading": "URL или IP",
"useHttps": "Использовать HTTPS",
"invalidUrl": {
"title": "Неверный URL",
"description": "Введите корректный URL HTTP или HTTPS."
},
"connectionTest": {
"description": "Проверьте подключение перед сохранением, чтобы убедиться, что устройство доступно.",
"button": {
"loading": "Проверка...",
"label": "Проверить подключение"
},
"reachable": "Доступно",
"notReachable": "Недоступно",
"success": {
"title": "Проверка подключения успешна",
"description": "Устройство доступно."
},
"failure": {
"title": "Проверка подключения не удалась",
"description": "Не удалось связаться с устройством. Проверьте URL и попробуйте снова."
}
}
}
},
"nodeDetails": {
"message": "Сообщение",
"requestPosition": "Запросить позицию",
"traceRoute": "Трассировка маршрута",
"airTxUtilization": "Загрузка TX в эфире",
"allRawMetrics": "Все сырые метрики:",
"batteryLevel": "Уровень батареи",
"channelUtilization": "Загрузка канала",
"details": "Детали:",
"deviceMetrics": "Метрики устройства:",
"hardware": "Оборудование: ",
"lastHeard": "Последний раз слышен: ",
"nodeHexPrefix": "HEX ноды: ",
"nodeNumber": "Номер ноды: ",
"position": "Позиция:",
"role": "Роль: ",
"uptime": "Время работы: ",
"voltage": "Напряжение",
"title": "Детали ноды {{identifier}}",
"ignoreNode": "Игнорировать ноду",
"removeNode": "Удалить ноду",
"unignoreNode": "Не игнорировать ноду",
"security": "Безопасность:",
"publicKey": "Публичный ключ: ",
"messageable": "Доступен для сообщений: ",
"KeyManuallyVerifiedTrue": "Публичный ключ вручную подтверждён",
"KeyManuallyVerifiedFalse": "Публичный ключ не подтверждён вручную"
},
"pkiBackup": {
"loseKeysWarning": "Если вы потеряете ключи, потребуется сбросить устройство.",
"secureBackup": "Важно сделать резервную копию публичного и приватного ключей и хранить её безопасно!",
"footer": "=== КОНЕЦ КЛЮЧЕЙ ===",
"header": "=== КЛЮЧИ MESHTASTIC ДЛЯ {{longName}} ({{shortName}}) ===",
"privateKey": "Приватный ключ:",
"publicKey": "Публичный ключ:",
"fileName": "meshtastic_keys_{{longName}}_{{shortName}}.txt",
"title": "Резервное копирование ключей"
},
"pkiBackupReminder": {
"description": "Рекомендуем регулярно делать резервную копию ключевых данных. Хотите сделать копию сейчас?",
"title": "Напоминание о резервной копии",
"remindLaterPrefix": "Напомнить через",
"remindNever": "Никогда не напоминать",
"backupNow": "Сделать копию сейчас"
},
"pkiRegenerate": {
"description": "Вы уверены, что хотите пересоздать пару ключей?",
"title": "Пересоздать пару ключей"
},
"qr": {
"addChannels": "Добавить каналы",
"replaceChannels": "Заменить каналы",
"description": "Текущая конфигурация LoRa также будет передана.",
"sharableUrl": "Ссылка для обмена",
"title": "Сгенерировать QR-код"
},
"reboot": {
"title": "Перезагрузка устройства",
"description": "Перезагрузить сейчас или запланировать перезагрузку подключённой ноды. При желании можно перезагрузить в режим OTA (Over-the-Air).",
"ota": "Перезагрузить в режим OTA",
"enterDelay": "Укажите задержку",
"scheduled": "Перезагрузка запланирована",
"schedule": "Запланировать перезагрузку",
"now": "Перезагрузить сейчас",
"cancel": "Отменить запланированную перезагрузку"
},
"refreshKeys": {
"description": {
"acceptNewKeys": "Это удалит ноду с устройства и запросит новые ключи.",
"keyMismatchReasonSuffix": ". Это связано с тем, что текущий публичный ключ удалённой ноды не совпадает с ранее сохранённым ключом для этой ноды.",
"unableToSendDmPrefix": "Ваша нода не может отправить личное сообщение ноде: "
},
"acceptNewKeys": "Принять новые ключи",
"title": "Несоответствие ключей — {{identifier}}"
},
"removeNode": {
"description": "Вы уверены, что хотите удалить эту ноду?",
"title": "Удалить ноду?"
},
"shutdown": {
"title": "Запланировать выключение",
"description": "Выключить подключённую ноду через X минут."
},
"traceRoute": {
"routeToDestination": "Маршрут к месту назначения:",
"routeBack": "Маршрут обратно:"
},
"tracerouteResponse": {
"title": "Трассировка: {{identifier}}"
},
"unsafeRoles": {
"confirmUnderstanding": "Да, я понимаю, что делаю",
"conjunction": " и запись в блоге о ",
"postamble": " и понимаю последствия изменения роли.",
"preamble": "Я прочитал(а) ",
"choosingRightDeviceRole": "Как выбрать правильную роль устройства",
"deviceRoleDocumentation": "Документация по ролям устройств",
"title": "Вы уверены?"
},
"managedMode": {
"confirmUnderstanding": "Да, я понимаю, что делаю",
"title": "Вы уверены?",
"description": "Включение управляемого режима блокирует клиентские приложения (включая веб-клиент) от записи конфигурации в радио. После включения конфигурации радиомодуля можно менять только через сообщения удалённого администратора. Эта настройка не требуется для удалённого администрирования нод."
},
"clientNotification": {
"title": "Уведомление клиента",
"TraceRoute can only be sent once every 30 seconds": "Трассировку можно отправлять не чаще одного раза в 30 секунд",
"Compromised keys were detected and regenerated.": "Обнаружены скомпрометированные ключи и они были пересозданы."
},
"resetNodeDb": {
"title": "Сброс базы нод",
"description": "Это действие удалит все ноды из базы нод подключённого устройства и очистит всю историю сообщений в клиенте. Это нельзя отменить. Вы уверены, что хотите продолжить?",
"confirm": "Сбросить базу нод",
"failedTitle": "Произошла ошибка при сбросе базы нод. Повторите попытку."
},
"clearAllStores": {
"title": "Очистить всё локальное хранилище",
"description": "Это действие очистит все локально сохранённые данные, включая историю сообщений и базы нод для всех ранее подключённых устройств. После завершения потребуется заново подключиться к ноде. Это нельзя отменить. Вы уверены, что хотите продолжить?",
"confirm": "Очистить всё локальное хранилище",
"failedTitle": "Произошла ошибка при очистке локального хранилища. Повторите попытку."
},
"factoryResetDevice": {
"title": "Сброс устройства к заводским настройкам",
"description": "Это действие выполнит сброс подключённого устройства к заводским настройкам, удалив все конфигурации и данные на устройстве, а также все ноды и сообщения, сохранённые в клиенте. Это нельзя отменить. Вы уверены, что хотите продолжить?",
"confirm": "Сбросить устройство к заводским настройкам",
"failedTitle": "Произошла ошибка при выполнении сброса. Повторите попытку."
},
"factoryResetConfig": {
"title": "Сброс конфигурации к заводским настройкам",
"description": "Это действие выполнит сброс конфигурации на подключённом устройстве, удалив все конфигурации на устройстве. Это нельзя отменить. Вы уверены, что хотите продолжить?",
"confirm": "Сбросить конфигурацию к заводским настройкам",
"failedTitle": "Произошла ошибка при выполнении сброса. Повторите попытку."
}
}
@@ -0,0 +1,40 @@
{
"maplibre": {
"GeolocateControl.FindMyLocation": "Найти моё местоположение",
"NavigationControl.ZoomIn": "Увеличить",
"NavigationControl.ZoomOut": "Уменьшить",
"CooperativeGesturesHandler.WindowsHelpText": "Используйте Ctrl + прокрутку, чтобы приблизить карту",
"CooperativeGesturesHandler.MacHelpText": "Используйте ⌘ + прокрутку, чтобы приблизить карту",
"CooperativeGesturesHandler.MobileHelpText": "Используйте два пальца, чтобы перемещать карту"
},
"layerTool": {
"nodeMarkers": "Показать ноды",
"directNeighbors": "Показать прямые соединения",
"remoteNeighbors": "Показать удалённые соединения",
"positionPrecision": "Показать точность позиции",
"traceroutes": "Показать трассировки",
"waypoints": "Показать путевые точки",
"heatmap": "Показать тепловую карту",
"density": "Плотность"
},
"mapMenu": {
"locateAria": "Найти мою ноду",
"layersAria": "Изменить стиль карты"
},
"waypointDetail": {
"edit": "Редактировать",
"description": "Описание:",
"createdBy": "Кем изменено:",
"createdDate": "Создано:",
"updated": "Обновлено:",
"expires": "Истекает:",
"distance": "Расстояние:",
"bearing": "Абсолютный азимут:",
"lockedTo": "Закреплено за:",
"latitude": "Широта:",
"longitude": "Долгота:"
},
"myNode": {
"tooltip": "Это устройство"
}
}
@@ -0,0 +1,39 @@
{
"page": {
"title": "Сообщения: {{chatName}}",
"placeholder": "Введите сообщение"
},
"emptyState": {
"title": "Выберите чат",
"text": "Сообщений пока нет."
},
"selectChatPrompt": {
"text": "Выберите канал или ноду, чтобы начать переписку."
},
"sendMessage": {
"placeholder": "Введите сообщение...",
"sendButton": "Отправить"
},
"actionsMenu": {
"addReactionLabel": "Добавить реакцию",
"replyLabel": "Ответить"
},
"deliveryStatus": {
"delivered": {
"label": "Сообщение доставлено",
"displayText": "Сообщение доставлено"
},
"failed": {
"label": "Не удалось доставить сообщение",
"displayText": "Доставка не удалась"
},
"unknown": {
"label": "Статус сообщения неизвестен",
"displayText": "Неизвестный статус"
},
"waiting": {
"label": "Отправка сообщения",
"displayText": "Ожидание доставки"
}
}
}
@@ -0,0 +1,448 @@
{
"page": {
"tabAmbientLighting": "Подсветка",
"tabAudio": "Аудио",
"tabCannedMessage": "Шаблоны",
"tabDetectionSensor": "Датчик обнаружения",
"tabExternalNotification": "Внешн. уведомл.",
"tabMqtt": "MQTT",
"tabNeighborInfo": "Инфо о соседях",
"tabPaxcounter": "Paxcounter",
"tabRangeTest": "Тест дальности",
"tabSerial": "COM-порт",
"tabStoreAndForward": "S&F",
"tabTelemetry": "Телеметрия"
},
"ambientLighting": {
"title": "Настройки подсветки",
"description": "Настройки модуля подсветки",
"ledState": {
"label": "Состояние LED",
"description": "Включить или выключить LED"
},
"current": {
"label": "Ток",
"description": "Устанавливает ток для LED-выхода. По умолчанию 10"
},
"red": {
"label": "Красный",
"description": "Устанавливает яркость красного LED. Значения 0–255"
},
"green": {
"label": "Зелёный",
"description": "Устанавливает яркость зелёного LED. Значения 0–255"
},
"blue": {
"label": "Синий",
"description": "Устанавливает яркость синего LED. Значения 0–255"
}
},
"audio": {
"title": "Настройки аудио",
"description": "Настройки аудио-модуля",
"codec2Enabled": {
"label": "Codec 2 включён",
"description": "Включить аудиокодирование Codec 2"
},
"pttPin": {
"label": "Пин PTT",
"description": "GPIO-пин для PTT"
},
"bitrate": {
"label": "Битрейт",
"description": "Битрейт для аудиокодирования"
},
"i2sWs": {
"label": "i2S WS",
"description": "GPIO-пин для i2S WS"
},
"i2sSd": {
"label": "i2S SD",
"description": "GPIO-пин для i2S SD"
},
"i2sDin": {
"label": "i2S DIN",
"description": "GPIO-пин для i2S DIN"
},
"i2sSck": {
"label": "i2S SCK",
"description": "GPIO-пин для i2S SCK"
}
},
"cannedMessage": {
"title": "Настройки шаблонных сообщений",
"description": "Настройки модуля шаблонных сообщений",
"moduleEnabled": {
"label": "Модуль включён",
"description": "Включить шаблонные сообщения"
},
"rotary1Enabled": {
"label": "Энкодер #1 включён",
"description": "Включить энкодер"
},
"inputbrokerPinA": {
"label": "Пин энкодера A",
"description": "Значение GPIO (1–39) для порта A энкодера"
},
"inputbrokerPinB": {
"label": "Пин энкодера B",
"description": "Значение GPIO (1–39) для порта B энкодера"
},
"inputbrokerPinPress": {
"label": "Пин нажатия энкодера",
"description": "Значение GPIO (1–39) для нажатия энкодера"
},
"inputbrokerEventCw": {
"label": "Событие по часовой",
"description": "Выберите событие ввода."
},
"inputbrokerEventCcw": {
"label": "Событие против часовой",
"description": "Выберите событие ввода."
},
"inputbrokerEventPress": {
"label": "Событие нажатия",
"description": "Выберите событие ввода"
},
"updown1Enabled": {
"label": "Вверх/вниз включён",
"description": "Включить энкодер вверх/вниз"
},
"allowInputSource": {
"label": "Разрешённый источник ввода",
"description": "Выберите из: '_any', 'rotEnc1', 'upDownEnc1', 'cardkb'"
},
"sendBell": {
"label": "Отправлять звонок",
"description": "Отправляет символ звонка с каждым сообщением"
}
},
"detectionSensor": {
"title": "Настройки датчика обнаружения",
"description": "Настройки модуля датчика обнаружения",
"enabled": {
"label": "Включено",
"description": "Включить или отключить модуль датчика обнаружения"
},
"minimumBroadcastSecs": {
"label": "Мин. интервал рассылки",
"description": "Минимальный интервал в секундах между отправкой сообщений по mesh-сети при изменении состояния"
},
"stateBroadcastSecs": {
"label": "Интервал рассылки состояния",
"description": "Интервал в секундах между отправкой сообщений с текущим состоянием, независимо от изменений"
},
"sendBell": {
"label": "Отправлять звонок",
"description": "Отправлять ASCII-звонок с тревожным сообщением"
},
"name": {
"label": "Понятное имя",
"description": "Используется для форматирования сообщения, отправляемого по mesh-сети. Максимум 20 символов"
},
"monitorPin": {
"label": "Пин мониторинга",
"description": "GPIO-пин для мониторинга изменений состояния"
},
"detectionTriggerType": {
"label": "Тип триггера",
"description": "Тип события-триггера"
},
"usePullup": {
"label": "Использовать подтяжку",
"description": "Использовать режим INPUT_PULLUP для GPIO-пина"
}
},
"externalNotification": {
"title": "Настройки внешних уведомлений",
"description": "Настройка модуля внешних уведомлений",
"enabled": {
"label": "Модуль включён",
"description": "Включить внешние уведомления"
},
"outputMs": {
"label": "Длительность (мс)",
"description": "Длительность (мс)"
},
"output": {
"label": "Выход",
"description": "Выход"
},
"outputVibra": {
"label": "Выход вибро",
"description": "Выход вибро"
},
"outputBuzzer": {
"label": "Выход зуммера",
"description": "Выход зуммера"
},
"active": {
"label": "Активен",
"description": "Активен"
},
"alertMessage": {
"label": "Сообщение тревоги",
"description": "Сообщение тревоги"
},
"alertMessageVibra": {
"label": "Вибро при сообщении",
"description": "Вибро при сообщении"
},
"alertMessageBuzzer": {
"label": "Зуммер при сообщении",
"description": "Зуммер при сообщении"
},
"alertBell": {
"label": "Звонок тревоги",
"description": "Запускать тревогу при получении входящего звонка?"
},
"alertBellVibra": {
"label": "Вибро при звонке",
"description": "Вибро при звонке"
},
"alertBellBuzzer": {
"label": "Зуммер при звонке",
"description": "Зуммер при звонке"
},
"usePwm": {
"label": "Использовать PWM",
"description": "Использовать PWM"
},
"nagTimeout": {
"label": "Тайм-аут напоминания",
"description": "Тайм-аут напоминания"
},
"useI2sAsBuzzer": {
"label": "Использовать пин I²S как зуммер",
"description": "Назначить пин I²S как выход зуммера"
}
},
"mqtt": {
"title": "Настройки MQTT",
"description": "Настройки модуля MQTT",
"enabled": {
"label": "Включено",
"description": "Включить или отключить MQTT"
},
"address": {
"label": "Адрес сервера MQTT",
"description": "Адрес сервера MQTT для стандартных/пользовательских серверов"
},
"username": {
"label": "Имя пользователя MQTT",
"description": "Имя пользователя MQTT для стандартных/пользовательских серверов"
},
"password": {
"label": "Пароль MQTT",
"description": "Пароль MQTT для стандартных/пользовательских серверов"
},
"encryptionEnabled": {
"label": "Шифрование включено",
"description": "Включить или отключить шифрование MQTT. Примечание: если опция не включена, все сообщения отправляются брокеру MQTT без шифрования, даже если на каналах аплинка заданы ключи шифрования. Это включает данные позиции."
},
"jsonEnabled": {
"label": "JSON включён",
"description": "Отправлять/получать JSON-пакеты по MQTT"
},
"tlsEnabled": {
"label": "TLS включён",
"description": "Включить или отключить TLS"
},
"root": {
"label": "Корневой топик",
"description": "Корневой топик MQTT для стандартных/пользовательских серверов"
},
"proxyToClientEnabled": {
"label": "Прокси MQTT-клиента",
"description": "Использует сетевое подключение для проксирования MQTT-сообщений клиенту."
},
"mapReportingEnabled": {
"label": "Отправка отчётов карты включена",
"description": "Ваша нода будет периодически отправлять незашифрованный пакет отчёта карты на настроенный MQTT-сервер; он включает ID, короткое и полное имя, приблизительное местоположение, модель оборудования, роль, версию прошивки, регион LoRa, пресет модема и имя первичного канала."
},
"mapReportSettings": {
"publishIntervalSecs": {
"label": "Интервал публикации отчёта (с)",
"description": "Интервал в секундах для публикации отчётов карты"
},
"positionPrecision": {
"label": "Приблизительное местоположение",
"description": "Передаваемая позиция будет точной в пределах этого расстояния",
"options": {
"metric_km23": "В пределах 23 км",
"metric_km12": "В пределах 12 км",
"metric_km5_8": "В пределах 5,8 км",
"metric_km2_9": "В пределах 2,9 км",
"metric_km1_5": "В пределах 1,5 км",
"metric_m700": "В пределах 700 м",
"metric_m350": "В пределах 350 м",
"metric_m200": "В пределах 200 м",
"metric_m90": "В пределах 90 м",
"metric_m50": "В пределах 50 м",
"imperial_mi15": "В пределах 15 миль",
"imperial_mi7_3": "В пределах 7,3 мили",
"imperial_mi3_6": "В пределах 3,6 мили",
"imperial_mi1_8": "В пределах 1,8 мили",
"imperial_mi0_9": "В пределах 0,9 мили",
"imperial_mi0_5": "В пределах 0,5 мили",
"imperial_mi0_2": "В пределах 0,2 мили",
"imperial_ft600": "В пределах 600 футов",
"imperial_ft300": "В пределах 300 футов",
"imperial_ft150": "В пределах 150 футов"
}
}
}
},
"neighborInfo": {
"title": "Настройки информации о соседях",
"description": "Настройки модуля информации о соседях",
"enabled": {
"label": "Включено",
"description": "Включить или отключить модуль информации о соседях"
},
"updateInterval": {
"label": "Интервал обновления",
"description": "Интервал в секундах между попытками отправки информации о соседях по mesh-сети"
}
},
"paxcounter": {
"title": "Настройки Paxcounter",
"description": "Настройки модуля Paxcounter",
"enabled": {
"label": "Модуль включён",
"description": "Включить Paxcounter"
},
"paxcounterUpdateInterval": {
"label": "Интервал обновления (сек.)",
"description": "Сколько ждать между отправкой пакетов Paxcounter"
},
"wifiThreshold": {
"label": "Порог WiFi RSSI",
"description": "При каком уровне WiFi RSSI увеличивать счётчик. По умолчанию -80."
},
"bleThreshold": {
"label": "Порог BLE RSSI",
"description": "При каком уровне BLE RSSI увеличивать счётчик. По умолчанию -80."
}
},
"rangeTest": {
"title": "Настройки теста дальности",
"description": "Настройки модуля теста дальности",
"enabled": {
"label": "Модуль включён",
"description": "Включить тест дальности"
},
"sender": {
"label": "Интервал сообщений",
"description": "Сколько ждать между отправкой тестовых пакетов"
},
"save": {
"label": "Сохранять CSV в хранилище",
"description": "Только ESP32"
}
},
"serial": {
"title": "Настройки COM-порта",
"description": "Настройки модуля COM-порта",
"enabled": {
"label": "Модуль включён",
"description": "Включить вывод в COM-порт"
},
"echo": {
"label": "Эхо",
"description": "Все отправляемые вами пакеты будут возвращаться на устройство"
},
"rxd": {
"label": "Пин приёма",
"description": "Установите GPIO-пин для RXD."
},
"txd": {
"label": "Пин передачи",
"description": "Установите GPIO-пин для TXD."
},
"baud": {
"label": "Скорость (бод)",
"description": "Скорость передачи по COM-порту"
},
"timeout": {
"label": "Тайм-аут",
"description": "Секунды ожидания, прежде чем считать пакет «завершённым»"
},
"mode": {
"label": "Режим",
"description": "Выберите режим"
},
"overrideConsoleSerialPort": {
"label": "Переопределить консольный COM-порт",
"description": "Если к консоли подключён COM-порт, этот параметр его переопределит."
}
},
"storeForward": {
"title": "Настройки Store & Forward",
"description": "Настройки модуля Store & Forward",
"enabled": {
"label": "Модуль включён",
"description": "Включить Store & Forward"
},
"heartbeat": {
"label": "Heartbeat включён",
"description": "Включить heartbeat Store & Forward"
},
"records": {
"label": "Количество записей",
"description": "Количество записей для хранения"
},
"historyReturnMax": {
"label": "Максимум возврата истории",
"description": "Максимальное число записей для возврата"
},
"historyReturnWindow": {
"label": "Окно возврата истории",
"description": "Возвращать записи из этого временного окна (минуты)"
}
},
"telemetry": {
"title": "Настройки телеметрии",
"description": "Настройки модуля телеметрии",
"deviceUpdateInterval": {
"label": "Метрики устройства",
"description": "Интервал обновления метрик устройства (секунды)"
},
"environmentUpdateInterval": {
"label": "Интервал обновления метрик окружения (секунды)",
"description": ""
},
"environmentMeasurementEnabled": {
"label": "Модуль включён",
"description": "Включить телеметрию окружения"
},
"environmentScreenEnabled": {
"label": "Показывать на экране",
"description": "Показывать модуль телеметрии на OLED-экране"
},
"environmentDisplayFahrenheit": {
"label": "Показывать Фаренгейт",
"description": "Показывать температуру в Фаренгейтах"
},
"airQualityEnabled": {
"label": "Качество воздуха включено",
"description": "Включить телеметрию качества воздуха"
},
"airQualityInterval": {
"label": "Интервал обновления качества воздуха",
"description": "Как часто отправлять данные о качестве воздуха по mesh-сети"
},
"powerMeasurementEnabled": {
"label": "Измерение питания включено",
"description": "Включить телеметрию измерения питания"
},
"powerUpdateInterval": {
"label": "Интервал обновления питания",
"description": "Как часто отправлять данные о питании по mesh-сети"
},
"powerScreenEnabled": {
"label": "Экран питания включён",
"description": "Включить экран телеметрии питания"
}
}
}
@@ -0,0 +1,62 @@
{
"nodeDetail": {
"publicKeyEnabled": {
"label": "Публичный ключ включён"
},
"noPublicKey": {
"label": "Нет публичного ключа"
},
"directMessage": {
"label": "Личное сообщение {{shortName}}"
},
"favorite": {
"label": "Избранное",
"tooltip": "Добавить или удалить эту ноду из избранного"
},
"notFavorite": {
"label": "Не в избранном"
},
"error": {
"label": "Ошибка",
"text": "Произошла ошибка при получении сведений о ноде. Повторите попытку позже."
},
"status": {
"heard": "Слышен",
"mqtt": "MQTT"
},
"elevation": {
"label": "Высота"
},
"channelUtil": {
"label": "Загрузка канала"
},
"airtimeUtil": {
"label": "Загрузка эфира"
}
},
"nodesTable": {
"headings": {
"longName": "Полное имя",
"connection": "Подключение",
"lastHeard": "Последний раз слышен",
"encryption": "Шифрование",
"model": "Модель",
"macAddress": "MAC-адрес"
},
"connectionStatus": {
"direct": "Прямое",
"away": "от вас",
"viaMqtt": ", через MQTT"
},
"lastHeardStatus": {
"never": "Никогда"
}
},
"actions": {
"added": "Добавлено",
"removed": "Удалено",
"ignoreNode": "Игнорировать ноду",
"unignoreNode": "Перестать игнорировать ноду",
"requestPosition": "Запросить позицию"
}
}
+216
View File
@@ -0,0 +1,216 @@
{
"navigation": {
"title": "Навигация",
"messages": "Сообщения",
"map": "Карта",
"settings": "Настройки",
"channels": "Каналы",
"radioConfig": "Настройки радио",
"deviceConfig": "Настройки устройства",
"moduleConfig": "Настройки модулей",
"manageConnections": "Управление подключениями",
"nodes": "Ноды"
},
"app": {
"title": "Meshtastic",
"logo": "Логотип Meshtastic"
},
"sidebar": {
"collapseToggle": {
"button": {
"open": "Открыть боковую панель",
"close": "Закрыть боковую панель"
}
},
"deviceInfo": {
"volts": "{{voltage}} В",
"firmware": {
"title": "Прошивка",
"version": "v{{version}}",
"buildDate": "Дата сборки: {{date}}"
}
}
},
"batteryStatus": {
"charging": "{{level}}% зарядки",
"pluggedIn": "Подключено к питанию",
"title": "Батарея"
},
"search": {
"nodes": "Поиск нод...",
"channels": "Поиск каналов...",
"commandPalette": "Поиск команд..."
},
"toast": {
"positionRequestSent": { "title": "Запрос позиции отправлен." },
"requestingPosition": { "title": "Запрашиваем позицию, пожалуйста, подождите..." },
"sendingTraceroute": { "title": "Отправляем трассировку, пожалуйста, подождите..." },
"tracerouteSent": { "title": "Трассировка отправлена." },
"savedChannel": { "title": "Канал сохранён: {{channelName}}" },
"messages": {
"pkiEncryption": { "title": "Чат использует шифрование PKI." },
"pskEncryption": { "title": "Чат использует шифрование PSK." }
},
"configSaveError": {
"title": "Ошибка сохранения настроек",
"description": "При сохранении настроек произошла ошибка."
},
"validationError": {
"title": "Есть ошибки в настройках",
"description": "Исправьте ошибки конфигурации перед сохранением."
},
"saveSuccess": {
"title": "Сохранение настроек",
"description": "Изменение конфигурации {{case}} сохранено."
},
"saveAllSuccess": {
"title": "Сохранено",
"description": "Все изменения конфигурации сохранены."
},
"favoriteNode": {
"title": "{{action}} {{nodeName}} {{direction}}",
"action": {
"added": "Добавлено",
"removed": "Удалено",
"to": "в избранное",
"from": "из избранного"
}
},
"ignoreNode": {
"title": "{{action}} {{nodeName}} {{direction}}",
"action": {
"added": "Добавлено",
"removed": "Удалено",
"to": "в список игнорирования",
"from": "из списка игнорирования"
}
}
},
"notifications": {
"copied": {
"label": "Скопировано!"
},
"copyToClipboard": {
"label": "Копировать в буфер обмена"
},
"hidePassword": {
"label": "Скрыть пароль"
},
"showPassword": {
"label": "Показать пароль"
},
"deliveryStatus": {
"delivered": "Доставлено",
"failed": "Доставка не удалась",
"waiting": "Ожидание",
"unknown": "Неизвестно"
}
},
"general": {
"label": "Общие"
},
"hardware": {
"label": "Оборудование"
},
"metrics": {
"label": "Метрики"
},
"role": {
"label": "Роль"
},
"filter": {
"label": "Фильтр"
},
"advanced": {
"label": "Дополнительно"
},
"clearInput": {
"label": "Очистить ввод"
},
"resetFilters": {
"label": "Сбросить фильтры"
},
"nodeName": {
"label": "Имя/номер ноды",
"placeholder": "Meshtastic 1234"
},
"airtimeUtilization": {
"label": "Загрузка эфира (%)",
"short": "Загрузка эф. (%)"
},
"batteryLevel": {
"label": "Уровень батареи (%)",
"labelText": "Уровень батареи (%): {{value}}"
},
"batteryVoltage": {
"label": "Напряжение батареи (В)",
"title": "Напряжение"
},
"channelUtilization": {
"label": "Загрузка канала (%)",
"short": "Загрузка кан. (%)"
},
"hops": {
"direct": "Прямой",
"label": "Количество прыжков",
"text": "Количество прыжков: {{value}}"
},
"lastHeard": {
"label": "Последний раз слышен",
"labelText": "Последний раз слышен: {{value}}",
"nowLabel": "Сейчас"
},
"snr": {
"label": "SNR (дБ)"
},
"favorites": {
"label": "Избранное"
},
"hide": {
"label": "Скрыть"
},
"showOnly": {
"label": "Показывать только"
},
"viaMqtt": {
"label": "Подключено через MQTT"
},
"hopsUnknown": {
"label": "Неизвестное число прыжков"
},
"showUnheard": {
"label": "Неизвестно время последнего приёма"
},
"languagePicker": {
"label": "Язык",
"changeLanguage": "Изменить язык"
},
"theme": {
"dark": "Тёмная",
"light": "Светлая",
"system": "Автоматически",
"changeTheme": "Изменить цветовую схему"
},
"errorPage": {
"title": "Это немного неловко...",
"description1": "Очень жаль, но в веб-клиенте произошла ошибка, из-за которой он аварийно завершился. <br /> Этого не должно быть, и мы работаем над исправлением.",
"description2": "Лучший способ предотвратить это в будущем — сообщить нам о проблеме.",
"reportInstructions": "Пожалуйста, включите в отчёт следующую информацию:",
"reportSteps": {
"step1": "Что вы делали, когда произошла ошибка",
"step2": "Что вы ожидали",
"step3": "Что произошло на самом деле",
"step4": "Любую другую важную информацию"
},
"reportLink": "Вы можете сообщить о проблеме в нашем <0>GitHub</0>",
"connectionsLink": "Вернуться к <0>подключениям</0>",
"detailsSummary": "Детали ошибки",
"errorMessageLabel": "Сообщение об ошибке:",
"stackTraceLabel": "Стек вызовов:",
"fallbackError": "{{error}}"
},
"footer": {
"text": "Работает на <0>▲ Vercel</0> | Meshtastic® — зарегистрированный товарный знак Meshtastic LLC. | <1>Юридическая информация</1>",
"commitSha": "SHA коммита: {{sha}}"
}
}