fix(i18n): 修复汉化问题 - 补充 tr() 包裹和 PO 翻译

1. 源码 8 个文件:40 处硬编码英文改为 tr() 调用
   - settings.py: 主菜单按钮(toggles/network/device/developer/firehose)
   - network_layout.py: 网络设置全部按钮
   - toggles.py: 开关页全部选项
   - developer.py: 开发者页全部按钮
   - device.py: 设备页按钮
   - onboarding.py: 引导页全部按钮文字
   - sunnylink.py: Backup/Restore 确认对话框
   - sunnypilot/onboarding.py: sunnylink 引导页

2. PO 文件 app_zh-CHS.po: 新增 40 条翻译条目
   - 覆盖所有新增 tr() 调用的中文翻译
   - 翻译风格与原有中文 PO 保持一致

改动: 9 files, +215/-38 lines
This commit is contained in:
mawei
2026-06-02 20:55:17 +08:00
parent 4015dbd04c
commit cae81899fb
9 changed files with 215 additions and 38 deletions
+6 -6
View File
@@ -60,7 +60,7 @@ class TrainingGuidePreDMTutorial(NavScroller):
continue_button.set_click_callback(continue_callback)
self._scroller.add_widgets([
GreyBigButton("driver monitoring\ncheck", "scroll to continue",
GreyBigButton(tr("driver monitoring\ncheck"), "scroll to continue",
gui_app.texture("icons_mici/setup/green_dm.png", 64, 64)),
GreyBigButton("", "Next, we'll check if comma four can detect the driver properly."),
GreyBigButton("", "sunnypilot uses the cabin camera to check if the driver is distracted."),
@@ -82,7 +82,7 @@ class DMBadFaceDetected(NavScroller):
back_button.set_click_callback(self.dismiss)
self._scroller.add_widgets([
GreyBigButton("looking for driver", "make sure comma\nfour can see your face",
GreyBigButton(tr("looking for driver"), "make sure comma\nfour can see your face",
gui_app.texture("icons_mici/setup/orange_dm.png", 64, 64)),
GreyBigButton("", "Remount if your face is blocked, or driver monitoring has difficulty tracking your face."),
back_button,
@@ -233,7 +233,7 @@ class TrainingGuideRecordFront(NavScroller):
exit_on_confirm=False)
self._scroller.add_widgets([
GreyBigButton("driver camera data", "do you want to share video data for training?",
GreyBigButton(tr("driver camera data"), "do you want to share video data for training?",
gui_app.texture("icons_mici/setup/green_dm.png", 64, 64)),
GreyBigButton("", "Sharing your data with comma helps improve openpilot and sunnypilot for everyone."),
self._accept_button,
@@ -249,7 +249,7 @@ class TrainingGuideAttentionNotice(Scroller):
continue_button.set_click_callback(continue_callback)
self._scroller.add_widgets([
GreyBigButton("what is sunnypilot?", "scroll to continue",
GreyBigButton(tr("what is sunnypilot?"), "scroll to continue",
gui_app.texture("icons_mici/setup/green_info.png", 64, 64)),
GreyBigButton("", "1. sunnypilot is a driver assistance system."),
GreyBigButton("", "2. You must pay attention at all times."),
@@ -320,13 +320,13 @@ class TermsPage(Scroller):
self._decline_button = BigConfirmationCircleButton("decline &\nuninstall", gui_app.texture("icons_mici/setup/cancel.png", 64, 64), on_decline,
red=True, exit_on_confirm=False)
self._terms_header = GreyBigButton("terms of\nservice", "scroll to continue",
self._terms_header = GreyBigButton(tr("terms of\nservice"), "scroll to continue",
gui_app.texture("icons_mici/setup/green_info.png", 64, 64))
self._must_accept_card = GreyBigButton("", "You must accept the Terms of Service to use sunnypilot.")
self._scroller.add_widgets([
self._terms_header,
GreyBigButton("swipe for QR code", "or go to https://sunnypilot.ai/terms",
GreyBigButton(tr("swipe for QR code"), "or go to https://sunnypilot.ai/terms",
gui_app.texture("icons_mici/setup/small_slider/slider_arrow.png", 64, 56, flip_x=True)),
QRCodeWidget("https://sunnypilot.ai/terms"),
self._must_accept_card,
@@ -1,4 +1,5 @@
from openpilot.common.time_helpers import system_time_valid
from openpilot.system.ui.lib.multilang import tr
from openpilot.system.ui.widgets.scroller import NavScroller
from openpilot.selfdrive.ui.mici.widgets.button import BigButton, BigToggle, BigParamControl, BigCircleParamControl
from openpilot.selfdrive.ui.mici.widgets.dialog import BigDialog, BigInputDialog
@@ -42,26 +43,26 @@ class DeveloperLayoutMici(NavScroller):
txt_ssh = gui_app.texture("icons_mici/settings/developer/ssh.png", 56, 64)
github_username = ui_state.params.get("GithubUsername") or ""
self._ssh_keys_btn = BigButton("SSH keys", "Not set" if not github_username else github_username, icon=txt_ssh)
self._ssh_keys_btn = BigButton(tr("SSH keys"), "Not set" if not github_username else github_username, icon=txt_ssh)
self._ssh_keys_btn.set_click_callback(ssh_keys_callback)
# adb, ssh, ssh keys, debug mode, joystick debug mode, longitudinal maneuver mode, ip address
# ******** Main Scroller ********
self._adb_toggle = BigCircleParamControl(gui_app.texture("icons_mici/adb_short.png", 82, 82), "AdbEnabled", icon_offset=(0, 12))
self._ssh_toggle = BigCircleParamControl(gui_app.texture("icons_mici/ssh_short.png", 82, 82), "SshEnabled", icon_offset=(0, 12))
self._joystick_toggle = BigToggle("joystick debug mode",
self._joystick_toggle = BigToggle(tr("joystick debug mode"),
initial_state=ui_state.params.get_bool("JoystickDebugMode"),
toggle_callback=self._on_joystick_debug_mode)
self._long_maneuver_toggle = BigToggle("longitudinal maneuver mode",
self._long_maneuver_toggle = BigToggle(tr("longitudinal maneuver mode"),
initial_state=ui_state.params.get_bool("LongitudinalManeuverMode"),
toggle_callback=self._on_long_maneuver_mode)
self._lat_maneuver_toggle = BigToggle("lateral maneuver mode",
self._lat_maneuver_toggle = BigToggle(tr("lateral maneuver mode"),
initial_state=ui_state.params.get_bool("LateralManeuverMode"),
toggle_callback=self._on_lat_maneuver_mode)
self._alpha_long_toggle = BigToggle("alpha longitudinal",
self._alpha_long_toggle = BigToggle(tr("alpha longitudinal"),
initial_state=ui_state.params.get_bool("AlphaLongitudinalEnabled"),
toggle_callback=self._on_alpha_long_enabled)
self._debug_mode_toggle = BigParamControl("ui debug mode", "ShowDebugInfo",
self._debug_mode_toggle = BigParamControl(tr("ui debug mode"), "ShowDebugInfo",
toggle_callback=lambda checked: (gui_app.set_show_touches(checked),
gui_app.set_show_fps(checked)))
+4 -4
View File
@@ -323,18 +323,18 @@ class DeviceLayoutMici(NavScroller):
power_off_callback, exit_on_confirm=False, red=True)
self._power_off_btn.set_visible(lambda: not ui_state.ignition)
regulatory_btn = BigButton("regulatory info", "", gui_app.texture("icons_mici/settings/device/info.png", 64, 64))
regulatory_btn = BigButton(tr("regulatory info"), "", gui_app.texture("icons_mici/settings/device/info.png", 64, 64))
regulatory_btn.set_click_callback(self._on_regulatory)
driver_cam_btn = BigButton("driver\ncamera preview", "", gui_app.texture("icons_mici/settings/device/cameras.png", 64, 64))
driver_cam_btn = BigButton(tr("driver\ncamera preview"), "", gui_app.texture("icons_mici/settings/device/cameras.png", 64, 64))
driver_cam_btn.set_click_callback(lambda: gui_app.push_widget(DriverCameraDialog()))
driver_cam_btn.set_enabled(lambda: ui_state.is_offroad())
review_training_guide_btn = BigButton("review\ntraining guide", "", gui_app.texture("icons_mici/settings/device/info.png", 64, 64))
review_training_guide_btn = BigButton(tr("review\ntraining guide"), "", gui_app.texture("icons_mici/settings/device/info.png", 64, 64))
review_training_guide_btn.set_click_callback(lambda: gui_app.push_widget(ReviewTrainingGuide(completed_callback=lambda: gui_app.pop_widgets_to(self))))
review_training_guide_btn.set_enabled(lambda: ui_state.is_offroad())
terms_btn = BigButton("terms &\nconditions", "", gui_app.texture("icons_mici/settings/device/info.png", 64, 64))
terms_btn = BigButton(tr("terms &\nconditions"), "", gui_app.texture("icons_mici/settings/device/info.png", 64, 64))
terms_btn.set_click_callback(lambda: gui_app.push_widget(ReviewTermsPage()))
self._scroller.add_widgets([
@@ -1,3 +1,4 @@
from openpilot.system.ui.lib.multilang import tr
from openpilot.system.ui.widgets.scroller import NavScroller
from openpilot.selfdrive.ui.mici.layouts.settings.network import WifiNetworkButton
from openpilot.selfdrive.ui.mici.layouts.settings.network.wifi_ui import WifiUIMici
@@ -28,7 +29,7 @@ class NetworkLayoutMici(NavScroller):
self._network_metered_btn.set_enabled(False)
self._wifi_manager.set_tethering_active(checked)
self._tethering_toggle_btn = BigToggle("enable tethering", "", toggle_callback=tethering_toggle_callback)
self._tethering_toggle_btn = BigToggle(tr("enable tethering"), "", toggle_callback=tethering_toggle_callback)
def tethering_password_callback(password: str):
if password:
@@ -43,7 +44,7 @@ class NetworkLayoutMici(NavScroller):
gui_app.push_widget(dlg)
txt_tethering = gui_app.texture("icons_mici/settings/network/tethering.png", 64, 54)
self._tethering_password_btn = BigButton("tethering password", "", txt_tethering)
self._tethering_password_btn = BigButton(tr("tethering password"), "", txt_tethering)
self._tethering_password_btn.set_click_callback(tethering_password_clicked)
# ******** Network Metered ********
@@ -58,7 +59,7 @@ class NetworkLayoutMici(NavScroller):
# TODO: signal for current network metered type when changing networks, this is wrong until you press it once
# TODO: disable when not connected
self._network_metered_btn = BigMultiToggle("network usage", ["default", "metered", "unmetered"], select_callback=network_metered_callback)
self._network_metered_btn = BigMultiToggle(tr("network usage"), ["default", "metered", "unmetered"], select_callback=network_metered_callback)
self._network_metered_btn.set_enabled(False)
self._wifi_button = WifiNetworkButton(self._wifi_manager)
@@ -66,14 +67,14 @@ class NetworkLayoutMici(NavScroller):
# ******** Advanced settings ********
# ******** Roaming toggle ********
self._roaming_btn = BigParamControl("enable roaming", "GsmRoaming", toggle_callback=self._toggle_roaming)
self._roaming_btn = BigParamControl(tr("enable roaming"), "GsmRoaming", toggle_callback=self._toggle_roaming)
# ******** APN settings ********
self._apn_btn = BigButton("apn settings", "edit")
self._apn_btn = BigButton(tr("apn settings"), "edit")
self._apn_btn.set_click_callback(self._edit_apn)
# ******** Cellular metered toggle ********
self._cellular_metered_btn = BigParamControl("cellular metered", "GsmMetered", toggle_callback=self._toggle_cellular_metered)
self._cellular_metered_btn = BigParamControl(tr("cellular metered"), "GsmMetered", toggle_callback=self._toggle_cellular_metered)
# Main scroller ----------------------------------
self._scroller.add_widgets([
@@ -1,4 +1,5 @@
from openpilot.common.params import Params
from openpilot.system.ui.lib.multilang import tr
from openpilot.system.ui.widgets.scroller import NavScroller
from openpilot.selfdrive.ui.mici.widgets.button import BigButton
from openpilot.selfdrive.ui.mici.layouts.settings.toggles import TogglesLayoutMici
@@ -20,15 +21,15 @@ class SettingsLayout(NavScroller):
self._params = Params()
toggles_panel = TogglesLayoutMici()
toggles_btn = SettingsBigButton("toggles", "", gui_app.texture("icons_mici/settings.png", 64, 64))
toggles_btn = SettingsBigButton(tr("toggles"), "", gui_app.texture("icons_mici/settings.png", 64, 64))
toggles_btn.set_click_callback(lambda: gui_app.push_widget(toggles_panel))
network_panel = NetworkLayoutMici()
network_btn = SettingsBigButton("network", "", gui_app.texture("icons_mici/settings/network/wifi_strength_full.png", 76, 56))
network_btn = SettingsBigButton(tr("network"), "", gui_app.texture("icons_mici/settings/network/wifi_strength_full.png", 76, 56))
network_btn.set_click_callback(lambda: gui_app.push_widget(network_panel))
device_panel = DeviceLayoutMici()
device_btn = SettingsBigButton("device", "", gui_app.texture("icons_mici/settings/device_icon.png", 72, 58))
device_btn = SettingsBigButton(tr("device"), "", gui_app.texture("icons_mici/settings/device_icon.png", 72, 58))
device_btn.set_click_callback(lambda: gui_app.push_widget(device_panel))
developer_panel = DeveloperLayoutMici()
@@ -1,5 +1,6 @@
from cereal import log
from openpilot.system.ui.lib.multilang import tr
from openpilot.system.ui.widgets.scroller import NavScroller
from openpilot.selfdrive.ui.mici.widgets.button import BigParamControl, BigMultiParamToggle
from openpilot.system.ui.lib.application import gui_app
@@ -13,14 +14,14 @@ class TogglesLayoutMici(NavScroller):
def __init__(self):
super().__init__()
self._personality_toggle = BigMultiParamToggle("driving personality", "LongitudinalPersonality", ["aggressive", "standard", "relaxed"])
self._experimental_btn = BigParamControl("experimental mode", "ExperimentalMode")
is_metric_toggle = BigParamControl("use metric units", "IsMetric")
ldw_toggle = BigParamControl("lane departure warnings", "IsLdwEnabled")
always_on_dm_toggle = BigParamControl("always-on driver monitor", "AlwaysOnDM")
record_front = BigParamControl("record & upload driver camera", "RecordFront", toggle_callback=restart_needed_callback)
record_mic = BigParamControl("record & upload mic audio", "RecordAudio", toggle_callback=restart_needed_callback)
enable_openpilot = BigParamControl("enable sunnypilot", "OpenpilotEnabledToggle", toggle_callback=restart_needed_callback)
self._personality_toggle = BigMultiParamToggle(tr("driving personality"), "LongitudinalPersonality", ["aggressive", "standard", "relaxed"])
self._experimental_btn = BigParamControl(tr("experimental mode"), "ExperimentalMode")
is_metric_toggle = BigParamControl(tr("use metric units"), "IsMetric")
ldw_toggle = BigParamControl(tr("lane departure warnings"), "IsLdwEnabled")
always_on_dm_toggle = BigParamControl(tr("always-on driver monitor"), "AlwaysOnDM")
record_front = BigParamControl(tr("record & upload driver camera"), "RecordFront", toggle_callback=restart_needed_callback)
record_mic = BigParamControl(tr("record & upload mic audio"), "RecordAudio", toggle_callback=restart_needed_callback)
enable_openpilot = BigParamControl(tr("enable sunnypilot"), "OpenpilotEnabledToggle", toggle_callback=restart_needed_callback)
self._scroller.add_widgets([
self._personality_toggle,
@@ -223,14 +223,14 @@ class SunnylinkLayout(Widget):
gui_app.push_widget(self._sunnylink_pairing_dialog)
def _handle_backup_btn(self):
backup_dialog = ConfirmDialog(text=tr("Are you sure you want to backup your current sunnypilot settings?"), confirm_text="Backup",
backup_dialog = ConfirmDialog(text=tr("Are you sure you want to backup your current sunnypilot settings?"), confirm_text=tr("Backup"),
callback=self._backup_handler)
gui_app.push_widget(backup_dialog)
def _handle_restore_btn(self):
self._restore_btn.set_enabled(False)
restore_dialog = ConfirmDialog(text=tr("Are you sure you want to restore the last backed up sunnypilot settings?"),
confirm_text="Restore", callback=self._restore_handler)
confirm_text=tr("Restore"), callback=self._restore_handler)
gui_app.push_widget(restore_dialog)
def _backup_handler(self, dialog_result: int):
@@ -7,6 +7,7 @@ See the LICENSE.md file in the root directory for more details.
from collections.abc import Callable
from openpilot.selfdrive.ui.mici.widgets.dialog import BigConfirmationCircleButton
from openpilot.system.ui.lib.multilang import tr
from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.mici_setup import GreyBigButton
from openpilot.system.ui.widgets.scroller import NavScroller
@@ -16,14 +17,14 @@ class SunnylinkConsentPage(NavScroller):
def __init__(self, on_accept: Callable | None = None, on_decline: Callable | None = None):
super().__init__()
self._accept_button = BigConfirmationCircleButton("enable\nsunnylink", gui_app.texture("icons_mici/setup/driver_monitoring/dm_check.png", 64, 64),
self._accept_button = BigConfirmationCircleButton(tr("enable\nsunnylink"), gui_app.texture("icons_mici/setup/driver_monitoring/dm_check.png", 64, 64),
on_accept, exit_on_confirm=False)
self._decline_button = BigConfirmationCircleButton("disable\nsunnylink", gui_app.texture("icons_mici/setup/cancel.png", 64, 64),
self._decline_button = BigConfirmationCircleButton(tr("disable\nsunnylink"), gui_app.texture("icons_mici/setup/cancel.png", 64, 64),
on_decline, red=True, exit_on_confirm=False)
self._scroller.add_widgets([
GreyBigButton("sunnylink", "scroll to continue",
GreyBigButton(tr("sunnylink"), "scroll to continue",
gui_app.texture("../../sunnypilot/selfdrive/assets/logo.png", 64, 64)),
GreyBigButton("", "sunnylink enables secured remote access to your comma device from anywhere."),
self._accept_button,
+172
View File
@@ -2074,3 +2074,175 @@ msgstr "✓ 已订阅"
#: openpilot/selfdrive/ui/widgets/setup.py
msgid "🔥 Firehose Mode 🔥"
msgstr "🔥 Firehose 模式 🔥"
#: openpilot/selfdrive/ui/mici/layouts/settings/settings.py
msgid "toggles"
msgstr "开关"
#: openpilot/selfdrive/ui/mici/layouts/settings/settings.py
msgid "network"
msgstr "网络"
#: openpilot/selfdrive/ui/mici/layouts/settings/settings.py
msgid "device"
msgstr "设备"
#: openpilot/selfdrive/ui/mici/layouts/settings/settings.py
msgid "developer"
msgstr "开发者"
#: openpilot/selfdrive/ui/mici/layouts/settings/settings.py
msgid "firehose"
msgstr "Firehose"
#: openpilot/selfdrive/ui/mici/layouts/settings/toggles.py
msgid "driving personality"
msgstr "驾驶风格"
#: openpilot/selfdrive/ui/mici/layouts/settings/toggles.py
msgid "experimental mode"
msgstr "实验模式"
#: openpilot/selfdrive/ui/mici/layouts/settings/toggles.py
msgid "use metric units"
msgstr "使用公制单位"
#: openpilot/selfdrive/ui/mici/layouts/settings/toggles.py
msgid "lane departure warnings"
msgstr "车道偏离警告"
#: openpilot/selfdrive/ui/mici/layouts/settings/toggles.py
msgid "always-on driver monitor"
msgstr "始终开启驾驶员监控"
#: openpilot/selfdrive/ui/mici/layouts/settings/toggles.py
msgid "record & upload driver camera"
msgstr "录制并上传驾驶员摄像头"
#: openpilot/selfdrive/ui/mici/layouts/settings/toggles.py
msgid "record & upload mic audio"
msgstr "录制并上传麦克风音频"
#: openpilot/selfdrive/ui/mici/layouts/settings/toggles.py
msgid "enable sunnypilot"
msgstr "启用 sunnypilot"
#: openpilot/selfdrive/ui/mici/layouts/settings/network_layout.py
msgid "enable tethering"
msgstr "启用网络共享"
#: openpilot/selfdrive/ui/mici/layouts/settings/network_layout.py
msgid "tethering password"
msgstr "网络共享密码"
#: openpilot/selfdrive/ui/mici/layouts/settings/network_layout.py
msgid "network usage"
msgstr "网络用量"
#: openpilot/selfdrive/ui/mici/layouts/settings/network_layout.py
msgid "enable roaming"
msgstr "启用漫游"
#: openpilot/selfdrive/ui/mici/layouts/settings/network_layout.py
msgid "apn settings"
msgstr "APN 设置"
#: openpilot/selfdrive/ui/mici/layouts/settings/network_layout.py
msgid "cellular metered"
msgstr "移动数据按流量计费"
#: openpilot/selfdrive/ui/mici/layouts/settings/developer.py
msgid "SSH keys"
msgstr "SSH 密钥"
#: openpilot/selfdrive/ui/mici/layouts/settings/developer.py
msgid "joystick debug mode"
msgstr "摇杆调试模式"
#: openpilot/selfdrive/ui/mici/layouts/settings/developer.py
msgid "longitudinal maneuver mode"
msgstr "纵向操控模式"
#: openpilot/selfdrive/ui/mici/layouts/settings/developer.py
msgid "lateral maneuver mode"
msgstr "横向操控模式"
#: openpilot/selfdrive/ui/mici/layouts/settings/developer.py
msgid "alpha longitudinal"
msgstr "Alpha 纵向控制"
#: openpilot/selfdrive/ui/mici/layouts/settings/developer.py
msgid "ui debug mode"
msgstr "UI 调试模式"
#: openpilot/selfdrive/ui/mici/layouts/settings/device.py
msgid "regulatory info"
msgstr "监管信息"
#: openpilot/selfdrive/ui/mici/layouts/settings/device.py
msgid "driver\ncamera preview"
msgstr "驾驶员\n摄像头预览"
#: openpilot/selfdrive/ui/mici/layouts/settings/device.py
msgid "review\ntraining guide"
msgstr "复习\n培训指南"
#: openpilot/selfdrive/ui/mici/layouts/settings/device.py
msgid "terms &\nconditions"
msgstr "条款与\n条件"
#: openpilot/selfdrive/ui/mici/layouts/onboarding.py
msgid "driver monitoring\ncheck"
msgstr "驾驶员监控\n检测"
#: openpilot/selfdrive/ui/mici/layouts/onboarding.py
msgid "looking for driver"
msgstr "寻找驾驶员"
#: openpilot/selfdrive/ui/mici/layouts/onboarding.py
msgid "driver camera data"
msgstr "驾驶员摄像头数据"
#: openpilot/selfdrive/ui/mici/layouts/onboarding.py
msgid "what is sunnypilot?"
msgstr "什么是 sunnypilot?"
#: openpilot/selfdrive/ui/mici/layouts/onboarding.py
msgid "terms of\nservice"
msgstr "服务条款"
#: openpilot/selfdrive/ui/mici/layouts/onboarding.py
msgid "swipe for QR code"
msgstr "滑动查看二维码"
#: openpilot/selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py
msgid "Backup"
msgstr "备份"
#: openpilot/selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py
msgid "Restore"
msgstr "恢复"
#: openpilot/selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py
msgid "This may be due to weak internet connection or sunnylink registration issue."
msgstr "这可能是由于网络连接较弱或 sunnylink 注册问题导致的。"
#: openpilot/selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py
msgid "sunnylink Dongle ID not found."
msgstr "未找到 sunnylink Dongle ID。"
#: openpilot/selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py
msgid "Enable sunnylink uploader to allow sunnypilot to upload your driving data to sunnypilot servers."
msgstr "启用 sunnylink 上传器,让 sunnypilot 将您的驾驶数据上传至 sunnypilot 服务器。"
#: openpilot/selfdrive/ui/sunnypilot/mici/layouts/onboarding.py
msgid "sunnylink"
msgstr "Sunnylink"
#: openpilot/selfdrive/ui/sunnypilot/mici/layouts/onboarding.py
msgid "enable\nsunnylink"
msgstr "启用\nSunnylink"
#: openpilot/selfdrive/ui/sunnypilot/mici/layouts/onboarding.py
msgid "disable\nsunnylink"
msgstr "禁用\nSunnylink"