export const DEFAULT_LOCALE = 'zh-CN'; export const supportedLocales = ['zh-CN', 'en-US']; const messages = { 'zh-CN': { 'common.account': '账号', 'common.addDomain': '添加域名', 'common.cancel': '取消', 'common.confirm': '确认', 'common.copy': '复制', 'common.copied': '已复制', 'common.delete': '删除', 'common.details': '详情', 'common.error': '操作失败', 'common.loadingConfig': '加载运行配置中', 'common.logout': '退出登录', 'common.manual': '手动', 'common.next': '下一步', 'common.notConfigured': '未配置', 'common.notFound': '暂无', 'common.previous': '上一步', 'common.refresh': '刷新', 'common.save': '保存', 'common.status': '状态', 'common.user': '用户', 'common.unsetSendingIp': '未设置发信 IP', 'auth.email': '邮箱', 'auth.emailPlaceholder': 'name@example.com', 'auth.backToLogin': '返回登录', 'auth.forgotPassword': '忘记密码?', 'auth.forgotPasswordButton': '发送重置邮件', 'auth.forgotPasswordTitle': '找回密码', 'auth.login': '登录', 'auth.loginEyebrow': 'Sign in', 'auth.loginTitle': '登录控制台', 'auth.newPassword': '新密码', 'auth.password': '密码', 'auth.register': '注册', 'auth.registerButton': '注册并进入', 'auth.registerEyebrow': 'Register', 'auth.registerTitle': '创建账号', 'auth.resendVerification': '重发验证邮件', 'auth.resendVerificationButton': '发送验证邮件', 'auth.resendVerificationTitle': '重发验证邮件', 'auth.resetPasswordButton': '重置密码', 'auth.resetPasswordTitle': '重置密码', 'auth.resetTokenMissing': '重置链接缺少 token,请重新发起密码重置。', 'auth.submitLogin': '登录', 'auth.username': '用户名', 'auth.usernameOrEmail': '用户名或邮箱', 'auth.valueDns': 'DNS 自动化', 'auth.valueIsolation': '多用户隔离', 'auth.valueObservability': '发送可观测', 'auth.subtitle': '发信域名、DNS、SMTP 与 API Token 的统一控制台', 'auth.requestFailed': '请求失败。', 'dashboard.title': '统计概览', 'dashboard.verifiedDomains': '已验证域名', 'dashboard.todaySent': '今日发送量', 'dashboard.successRate': '成功率', 'dashboard.bounceRate': '退信率', 'dashboard.complaintRate': '投诉率', 'dashboard.lastSentAt': '最近一次发送', 'dashboard.dnsIssues': 'DNS 异常数量', 'dashboard.smtpStatus': 'SMTP 状态', 'dashboard.smtpReady': '可用', 'dashboard.smtpNotConfigured': '未配置', 'dashboard.trend': '发送趋势', 'dashboard.statusDistribution': '状态分布', 'dashboard.domainRanking': '域名发送排行', 'dashboard.domainHealth': '域名健康', 'dashboard.hourlyHeatmap': '小时发送分布', 'dashboard.recentFailures': '最近失败原因', 'dashboard.recentLogs': '最近发送记录', 'dashboard.noTrend': '暂无发送趋势数据', 'dashboard.noDomains': '暂无域名', 'dashboard.noFailures': '暂无失败记录', 'dashboard.defaultPasswordWarning': '当前仍在使用默认管理密码,请修改 .env 后重启服务。', 'dashboard.acceptedMail': '已接收邮件', 'dashboard.failedMail': '失败邮件', 'dashboard.dnsActionHint': '优先处理 DNS 异常域名,避免影响新域名投递。', 'dashboard.statusQueued': '已接收', 'dashboard.statusFailed': '失败', 'dashboard.statusUnknown': '未知', 'domains.title': '发信域名', 'domains.domain': '域名', 'domains.senderHost': '发信主机', 'domains.sendingIp': '发信 IP', 'domains.dnsApi': 'DNS API', 'domains.smtp': 'SMTP', 'domains.lastSent': '最近发送', 'domains.overallStatus': '整体状态', 'domains.actions': '操作', 'domains.searchPlaceholder': '搜索域名或发信主机', 'domains.statusPlaceholder': '整体状态', 'domains.healthy': '健康', 'domains.pending': '等待生效', 'domains.needsAction': '需要处理', 'domains.waitingDns': '等待 DNS 生效', 'domains.sendable': '可发送', 'domains.waitingVerify': '待验证', 'domains.oneClickDns': '一键 DNS', 'domains.check': '检查', 'domains.test': '测试', 'domains.deleteConfirm': '确认删除该域名?', 'domainDetail.back': '返回域名列表', 'domainDetail.overview': '域名概览', 'domainDetail.danger': '危险操作', 'domainDetail.deleteHint': '删除域名会移除该域名配置,但不会删除 DNS 服务商中的记录。', 'domainDetail.editTitle': '修改域名配置', 'domainDetail.lastCheck': '最后检查', 'domainDetail.notChecked': '尚未检查', 'domainDetail.noDnsResult': '尚未生成 DNS 检查结果', 'domainDetail.currentDnsResult': '当前 DNS 检测结果', 'domainDetail.recheckAll': '重新检查全部', 'domainDetail.copyAll': '复制全部配置', 'domainDetail.noPublicDns': '暂无公共 DNS 查询数据', 'domainDetail.notFoundRecord': '未发现', 'domainDetail.needAttention': '需要关注', 'domainDetail.noSmtpPassword': '请在 SMTP 页面重新设置后复制', 'domainDetail.noApiToken': '尚未创建', 'domainDetail.apiExample': '发送 API 示例', 'domainDetail.placeholder': '配置将在后续版本接入', 'dnsRecord.hostname': '主机名', 'dnsRecord.targetValue': '目标值', 'dnsRecord.currentValue': '当前值', 'dnsRecord.emptyCurrent': '未查询到记录', 'dnsRecord.ptrHint': 'PTR 通常需要在服务器商、云厂商或 IP 提供商处配置,DNS API 一般无法直接写入。', 'dnsRecord.recheck': '重新检测', 'dnsRecord.copyLabel': '复制', 'dnsRecord.rootTxt': '根域 TXT', 'dnsRecord.verificationTxt': '验证 TXT', 'dnsRecord.dkimTxt': 'DKIM TXT', 'dnsRecord.dmarcTxt': 'DMARC TXT', 'dnsRecord.senderA': '发信主机 A', 'dnsRecord.ptr': '发信 IP PTR', 'domainHealth.sendingDomain': 'Sending domain', 'domainHealth.dnsProgress': 'DNS 检查进度', 'domainHealth.passed': '通过', 'domainHealth.dnsIssues': 'DNS 异常', 'domainHealth.dnsApi': 'DNS API', 'domainHealth.oneClickDns': '一键配置 DNS', 'domainHealth.checkNow': '立即检查', 'domainHealth.sendTest': '发送测试邮件', 'domainHealth.edit': '修改配置', 'addDomain.title': '添加发信域名', 'addDomain.stepDomain': '域名信息', 'addDomain.stepDns': 'DNS 配置方式', 'addDomain.stepPolicy': 'DKIM / SPF / DMARC', 'addDomain.stepConfirm': '确认并创建', 'addDomain.create': '确认创建', 'addDomain.domainExtra': '填写根域名,不需要 http、路径或邮箱地址。', 'addDomain.domainRequired': '请输入发信域名', 'addDomain.senderHostRequired': '请输入发信主机', 'addDomain.sendingIpRequired': '请输入发信 IP', 'addDomain.dnsExtra': '未选择时仍可创建域名,稍后手动配置 DNS 或绑定凭据。', 'addDomain.manualDns': '手动配置 DNS', 'addDomain.dnsHint': '选择 DNS API 后,域名详情页可以使用“一键配置 DNS”写入验证、DKIM、SPF、DMARC 和发信主机 A 记录。', 'addDomain.selectorRequired': '请输入 DKIM selector', 'addDomain.spfExtra': '兼容第三方 SPF include', 'addDomain.generatedTitle': '创建后会生成以下配置', 'addDomain.recordVerification': '域名验证 TXT', 'addDomain.recordDkim': 'DKIM TXT', 'addDomain.recordSpf': 'SPF TXT', 'addDomain.recordDmarc': 'DMARC TXT', 'addDomain.recordSenderA': '发信主机 A 记录', 'addDomain.recordPtr': 'PTR 反向解析检查提示', 'addDomain.immediateCheck': '创建后立即检查 DNS', 'logs.title': '发送记录', 'logs.time': '时间', 'logs.recipient': '收件人', 'logs.domain': '发件域名', 'logs.errorReason': '错误原因', 'logs.viewDetail': '查看详情', 'logs.domainPlaceholder': '发信域名', 'logs.statusPlaceholder': '状态', 'logs.recipientPlaceholder': '搜索收件人', 'logs.detailTitle': '发送详情', 'logs.deliveryLog': '完整投递日志', 'logs.copyDeliveryLog': '复制投递日志', 'logs.noDeliveryLog': '暂无结构化投递日志,可能是历史发送记录。', 'logs.sender': '发件人', 'logs.subject': '主题', 'logs.messageId': 'Message ID', 'logs.finalResponse': '最终响应', 'logs.messageBytes': '邮件字节数', 'logs.queueId': 'Postfix 队列 ID', 'logs.deliveredAt': '最终投递时间', 'logs.deliveryAttempts': '投递尝试', 'logs.noDeliveryAttempts': '暂无最终投递回执,可能仍在队列中或属于历史记录。', 'logs.statusQueued': '队列中', 'logs.statusSent': '已送达', 'logs.statusDeferred': '暂时失败', 'logs.statusBounced': '已退信', 'logs.statusFailed': '失败', 'smtp.connectionTitle': 'SMTP 连接信息', 'smtp.loginCredentialsTitle': '发信登录凭据', 'smtp.username': '用户名', 'smtp.password': '密码', 'smtp.usernameRequired': '请输入 SMTP Username', 'smtp.passwordRequired': '请输入 SMTP Password', 'smtp.passwordSet': '已设置', 'smtp.passwordEmpty': '未设置', 'smtp.passwordUnavailable': '请重新设置后复制', 'smtp.create': '新增凭据', 'smtp.createTitle': '新增发信登录凭据', 'smtp.editTitle': '编辑发信登录凭据', 'smtp.deleteConfirm': '确认删除该 SMTP 登录凭据?', 'smtp.passwordExtra': '留空保存时会保留原密码;当前密码可在上方连接信息中复制。', 'smtp.regenerate': '重新生成密码', 'smtp.resetToCopy': '请重新设置后复制', 'smtpRelay.title': '高级:外部 SMTP 出口', 'smtpRelay.create': '新增出口', 'smtpRelay.createTitle': '新增发信 SMTP 出口', 'smtpRelay.editTitle': '编辑发信 SMTP 出口', 'smtpRelay.name': '名称', 'smtpRelay.nameRequired': '请输入出口名称', 'smtpRelay.server': '服务器', 'smtpRelay.hostRequired': '请输入 SMTP Host', 'smtpRelay.portRequired': '请输入 SMTP Port', 'smtpRelay.username': '用户名', 'smtpRelay.password': '密码', 'smtpRelay.passwordSet': '已设置', 'smtpRelay.passwordEmpty': '未设置', 'smtpRelay.passwordExtra': '编辑时会回显已保存密码;清空该字段保存会移除密码。', 'smtpRelay.generatePassword': '生成密码', 'smtpRelay.heloExtra': '留空时使用系统默认 HELO。', 'smtpRelay.default': '默认', 'smtpRelay.domainDefault': '默认发信 SMTP 出口', 'smtpRelay.domainDefaultExtra': '未选择时按请求指定、用户默认出口、系统全局 SMTP 的顺序选择。', 'smtpRelay.useResolutionOrder': '按默认选择顺序', 'smtpRelay.deleteConfirm': '确认删除该 SMTP 出口?绑定到该出口的域名会改为按默认顺序选择。', 'dnsApi.title': 'DNS API 凭据', 'dnsApi.createTitle': '新增 DNS API', 'dnsApi.editTitle': '编辑', 'dnsApi.zone': 'Zone / 根域名', 'dnsApi.zoneRequired': '请输入 Zone 或根域名', 'dnsApi.cloudflareZoneExtra': 'Cloudflare 可填写任一可访问 Zone 用于测试;一键配置时会按当前发信域名自动匹配 Zone。', 'dnsApi.tokenExtra': '需要 Zone DNS Edit 权限。', 'dnsApi.keepSecret': '留空表示保留原密钥。', 'dnsApi.save': '保存修改', 'dnsApi.create': '新增凭据', 'dnsApi.secretHint': '密钥只在服务端加密保存,不会在列表中回显。', 'settings.checkItem': '检查项', 'settings.deliveryChecks': '发信环境检查', 'settings.noPermission': '当前账号没有系统设置权限。', 'settings.save': '保存设置', 'admin.title': '管理员面板', 'admin.users': '用户', 'admin.resources': '资源', 'admin.migration': '合并迁移', 'admin.systemEmail': '系统邮件', 'admin.auditLogs': '审计日志', 'metrics.accepted': '已接收', 'metrics.failed': '失败', 'metrics.recipients': '收件人', 'metrics.total': '总量', 'status.success': '已通过', 'status.pending': '等待生效', 'status.error': '配置错误', 'status.idle': '未配置', 'tokens.createTitle': '创建 API Token', 'tokens.name': '名称', 'tokens.namePlaceholder': 'Production API', 'tokens.nameRequired': '请输入 Token 名称', 'tokens.create': '创建 Token', 'tokens.listTitle': 'API Tokens', 'tokens.prefix': 'Token 前缀', 'tokens.fullToken': '完整 Token', 'tokens.copyFull': '复制完整 Token', 'tokens.copyPrefix': '复制前缀', 'tokens.createdTitle': 'API Token 已创建', 'tokens.createdWarning': '完整 Token 只会显示这一次。关闭后无法再次查看,请立即复制并保存到安全位置。', 'tokens.createdSuccess': 'Token 已创建', 'tokens.deletedSuccess': 'Token 已删除', 'tokens.secretUnavailable': '完整 Token 仅在创建时显示', 'tokens.lastUsed': '最近使用', 'tokens.neverUsed': '未使用', 'tokens.createdAt': '创建时间', 'tokens.actions': '操作', 'tokens.deleteConfirm': '确认删除该 Token?', 'tokens.copyCreated': '复制完整 Token', 'tokens.prefixOnlyHelp': '历史 Token 不保存明文,只能复制前缀用于识别。', 'tokens.docsTitle': '发送 API 使用文档', 'tokens.endpoint': 'API Endpoint', 'tokens.authHeader': '认证方式', 'tokens.authHeaderValue': 'Authorization: Bearer ', 'tokens.contentType': 'Content-Type', 'tokens.requestFields': '请求字段', 'tokens.fieldFrom': 'from:发件地址,域名必须已添加并通过验证。', 'tokens.fieldTo': 'to:收件人地址,支持单个邮箱或邮箱数组。', 'tokens.fieldSubject': 'subject:邮件主题。', 'tokens.fieldText': 'text:纯文本正文。', 'tokens.fieldHtml': 'html:HTML 正文,可选。', 'tokens.curlExample': 'curl 示例', 'tokens.nodeExample': 'Node / Fetch 示例', 'tokens.requestExample': '请求 Body 示例', 'tokens.responseExample': '成功响应示例', 'tokens.securityTips': '安全建议', 'tokens.securityTipStore': '只在服务端环境保存 Token,不要放进浏览器前端代码或公开仓库。', 'tokens.securityTipRotate': '不同环境使用不同 Token,泄露后立即删除并重新创建。', 'tokens.securityTipDomain': 'From 域名必须属于当前账号,建议先完成 DNS 验证再接入生产发送。', 'tokens.noTokenHint': '创建 Token 后可复制完整密钥;历史 Token 只显示前缀,示例中使用占位符。', 'webhooks.title': 'Webhooks', 'webhooks.subtitle': '在投递状态变为已送达、退信或失败时,向你的 HTTPS 端点推送通知。', 'webhooks.create': '新建 Webhook', 'webhooks.createTitle': '新建 Webhook', 'webhooks.editTitle': '编辑 Webhook', 'webhooks.name': '名称', 'webhooks.namePlaceholder': 'Production deliveries', 'webhooks.nameRequired': '请输入 Webhook 名称', 'webhooks.url': '回调 URL', 'webhooks.urlPlaceholder': 'https://example.com/webhooks/mailhub', 'webhooks.urlRequired': '请输入回调 URL', 'webhooks.urlHint': '生产环境请使用 HTTPS。签名校验使用 X-MailHub-Signature 请求头。', 'webhooks.events': '订阅事件', 'webhooks.eventsRequired': '请至少选择一个事件', 'webhooks.eventSent': '已送达', 'webhooks.eventBounced': '已退信', 'webhooks.eventFailed': '失败', 'webhooks.enabled': '启用', 'webhooks.disabled': '已停用', 'webhooks.scope': '作用域', 'webhooks.scopeAccount': '账号级', 'webhooks.scopeDomain': '域名级', 'webhooks.domain': '域名', 'webhooks.domainAccount': '整个账号', 'webhooks.domainOverrideHelp': '若某域名对某一事件存在任何已启用的端点,则该事件不会再投递到账号级端点。', 'webhooks.secret': '签名密钥', 'webhooks.secretPrefix': '密钥前缀', 'webhooks.secretCreatedTitle': 'Webhook 密钥已创建', 'webhooks.secretRotatedTitle': 'Webhook 密钥已轮换', 'webhooks.secretCreatedWarning': '完整密钥只会显示这一次。关闭后无法再次查看,请立即复制并保存到安全位置。', 'webhooks.copySecret': '复制完整密钥', 'webhooks.rotateSecret': '轮换密钥', 'webhooks.rotateConfirm': '确认轮换该 Webhook 的签名密钥?旧密钥将立即失效。', 'webhooks.test': '发送测试', 'webhooks.testQueued': '测试投递已入队', 'webhooks.deleteConfirm': '确认删除该 Webhook?相关投递记录也会一并删除。', 'webhooks.empty': '暂无 Webhook。创建后即可接收投递状态回调。', 'webhooks.listTitle': '端点列表', 'webhooks.actions': '操作', 'webhooks.deliveriesTitle': '投递记录', 'webhooks.deliveriesEmpty': '暂无投递记录', 'webhooks.deliveriesFilterWebhook': '按 Webhook 筛选', 'webhooks.deliveriesFilterStatus': '按状态筛选', 'webhooks.deliveriesFilterEvent': '按事件筛选', 'webhooks.allWebhooks': '全部 Webhook', 'webhooks.allStatuses': '全部状态', 'webhooks.allEvents': '全部事件', 'webhooks.statusPending': '待投递', 'webhooks.statusProcessing': '投递中', 'webhooks.statusSuccess': '成功', 'webhooks.statusDead': '已放弃', 'webhooks.attemptCount': '尝试次数', 'webhooks.responseStatus': 'HTTP 状态', 'webhooks.error': '错误', 'webhooks.replay': '重放', 'webhooks.replaySuccess': '投递已重新入队', 'webhooks.lastAttemptAt': '最近尝试', 'webhooks.nextAttemptAt': '下次尝试', 'webhooks.createdAt': '创建时间', 'webhooks.viewDeliveries': '查看投递', 'webhooks.docsTitle': '回调说明', 'webhooks.docsSignature': '使用 HMAC-SHA256 校验请求体;签名放在 X-MailHub-Signature。', 'webhooks.docsEvents': '事件类型:sent、bounced、failed(终端状态)。', 'testMail.title': '发送测试邮件', 'testMail.fromRequired': '请输入发件人', 'testMail.toRequired': '请输入收件人', 'actions.domainCreated': '域名已创建', 'actions.dnsCheckCompleted': 'DNS 检查已完成', 'actions.dnsCheckRefreshed': 'DNS 检查已刷新', 'actions.dnsApplyCompleted': 'DNS 写入请求已完成', 'actions.dnsApplyPartial': 'DNS 写入部分失败', 'actions.domainSaved': '域名配置已保存', 'actions.domainDeleted': '域名已删除', 'actions.testMailQueued': '已提交到发信队列', 'actions.dnsApiCreated': 'DNS API 已新增', 'actions.dnsApiUpdated': 'DNS API 已更新', 'actions.dnsApiDeleted': 'DNS API 已删除', 'actions.dnsApiTestCompleted': '连接测试完成', 'actions.smtpCreated': 'SMTP 登录凭据已新增', 'actions.smtpUpdated': 'SMTP 登录凭据已更新', 'actions.smtpDeleted': 'SMTP 登录凭据已删除', 'actions.smtpRelayCreated': 'SMTP 出口已新增', 'actions.smtpRelayUpdated': 'SMTP 出口已更新', 'actions.smtpRelayDeleted': 'SMTP 出口已删除', 'actions.settingsSaved': '系统设置已保存', 'actions.webhookCreated': 'Webhook 已创建', 'actions.webhookUpdated': 'Webhook 已更新', 'actions.webhookDeleted': 'Webhook 已删除', 'actions.webhookSecretRotated': 'Webhook 密钥已轮换', 'actions.webhookTestQueued': 'Webhook 测试已入队', 'actions.webhookDeliveryReplayed': 'Webhook 投递已重放', 'nav.dashboard': '仪表盘', 'nav.domains': '发信域名', 'nav.dnsApi': 'DNS API', 'nav.smtp': 'SMTP 凭据', 'nav.tokens': 'API Token', 'nav.logs': '发送记录', 'nav.webhooks': 'Webhooks', 'nav.admin': '管理员', 'nav.settings': '系统设置', 'nav.group.overview': '概览', 'nav.group.delivery': '投递', 'nav.group.system': '系统' }, 'en-US': { 'common.account': 'Account', 'common.addDomain': 'Add Domain', 'common.cancel': 'Cancel', 'common.confirm': 'Confirm', 'common.copy': 'Copy', 'common.copied': 'Copied', 'common.delete': 'Delete', 'common.details': 'Details', 'common.error': 'Operation failed', 'common.loadingConfig': 'Loading runtime config', 'common.logout': 'Log out', 'common.manual': 'Manual', 'common.next': 'Next', 'common.notConfigured': 'Not configured', 'common.notFound': 'None', 'common.previous': 'Previous', 'common.refresh': 'Refresh', 'common.save': 'Save', 'common.status': 'Status', 'common.user': 'User', 'common.unsetSendingIp': 'Sending IP not set', 'auth.email': 'Email', 'auth.emailPlaceholder': 'name@example.com', 'auth.backToLogin': 'Back to sign in', 'auth.forgotPassword': 'Forgot password?', 'auth.forgotPasswordButton': 'Send reset email', 'auth.forgotPasswordTitle': 'Recover password', 'auth.login': 'Sign in', 'auth.loginEyebrow': 'Sign in', 'auth.loginTitle': 'Sign in to console', 'auth.newPassword': 'New password', 'auth.password': 'Password', 'auth.register': 'Register', 'auth.registerButton': 'Create account', 'auth.registerEyebrow': 'Register', 'auth.registerTitle': 'Create account', 'auth.resendVerification': 'Resend verification email', 'auth.resendVerificationButton': 'Send verification email', 'auth.resendVerificationTitle': 'Resend verification email', 'auth.resetPasswordButton': 'Reset password', 'auth.resetPasswordTitle': 'Reset password', 'auth.resetTokenMissing': 'The reset link is missing a token. Please request a new password reset.', 'auth.submitLogin': 'Sign in', 'auth.username': 'Username', 'auth.usernameOrEmail': 'Username or email', 'auth.valueDns': 'DNS automation', 'auth.valueIsolation': 'User isolation', 'auth.valueObservability': 'Delivery visibility', 'auth.subtitle': 'One console for sending domains, DNS, SMTP, and API tokens', 'auth.requestFailed': 'Request failed.', 'dashboard.title': 'Analytics', 'dashboard.verifiedDomains': 'Verified domains', 'dashboard.todaySent': 'Sent today', 'dashboard.successRate': 'Success rate', 'dashboard.bounceRate': 'Bounce rate', 'dashboard.complaintRate': 'Complaint rate', 'dashboard.lastSentAt': 'Last sent', 'dashboard.dnsIssues': 'DNS issues', 'dashboard.smtpStatus': 'SMTP status', 'dashboard.smtpReady': 'Ready', 'dashboard.smtpNotConfigured': 'Not configured', 'dashboard.trend': 'Sending trend', 'dashboard.statusDistribution': 'Status distribution', 'dashboard.domainRanking': 'Domain ranking', 'dashboard.domainHealth': 'Domain health', 'dashboard.hourlyHeatmap': 'Hourly distribution', 'dashboard.recentFailures': 'Recent failures', 'dashboard.recentLogs': 'Recent sending logs', 'dashboard.noTrend': 'No trend data yet', 'dashboard.noDomains': 'No domains yet', 'dashboard.noFailures': 'No failures yet', 'dashboard.defaultPasswordWarning': 'The default admin password is still in use. Update .env and restart the service.', 'dashboard.acceptedMail': 'Accepted mail', 'dashboard.failedMail': 'Failed mail', 'dashboard.dnsActionHint': 'Handle domains with DNS issues first to protect delivery for new senders.', 'dashboard.statusQueued': 'Accepted', 'dashboard.statusFailed': 'Failed', 'dashboard.statusUnknown': 'Unknown', 'domains.title': 'Sending domains', 'domains.domain': 'Domain', 'domains.senderHost': 'Sending host', 'domains.sendingIp': 'Sending IP', 'domains.dnsApi': 'DNS API', 'domains.smtp': 'SMTP', 'domains.lastSent': 'Last sent', 'domains.overallStatus': 'Overall status', 'domains.actions': 'Actions', 'domains.searchPlaceholder': 'Search domain or sending host', 'domains.statusPlaceholder': 'Overall status', 'domains.healthy': 'Healthy', 'domains.pending': 'Pending', 'domains.needsAction': 'Needs action', 'domains.waitingDns': 'Waiting for DNS', 'domains.sendable': 'Sendable', 'domains.waitingVerify': 'Waiting verification', 'domains.oneClickDns': 'One-click DNS', 'domains.check': 'Check', 'domains.test': 'Test', 'domains.deleteConfirm': 'Delete this domain?', 'domainDetail.back': 'Back to domains', 'domainDetail.overview': 'Domain overview', 'domainDetail.danger': 'Danger zone', 'domainDetail.deleteHint': 'Deleting the domain removes MailHub configuration, but does not delete records at your DNS provider.', 'domainDetail.editTitle': 'Edit domain settings', 'domainDetail.lastCheck': 'Last check', 'domainDetail.notChecked': 'Not checked', 'domainDetail.noDnsResult': 'No DNS check result yet', 'domainDetail.currentDnsResult': 'Current DNS results', 'domainDetail.recheckAll': 'Recheck all', 'domainDetail.copyAll': 'Copy all records', 'domainDetail.noPublicDns': 'No public DNS query data', 'domainDetail.notFoundRecord': 'Not found', 'domainDetail.needAttention': 'Needs attention', 'domainDetail.noSmtpPassword': 'Reset it on the SMTP page before copying', 'domainDetail.noApiToken': 'No token yet', 'domainDetail.apiExample': 'Sending API example', 'domainDetail.placeholder': 'configuration will be connected in a later version', 'dnsRecord.hostname': 'Hostname', 'dnsRecord.targetValue': 'Target value', 'dnsRecord.currentValue': 'Current value', 'dnsRecord.emptyCurrent': 'No record found', 'dnsRecord.ptrHint': 'PTR is usually configured at your server, cloud, or IP provider. DNS APIs usually cannot write it directly.', 'dnsRecord.recheck': 'Recheck', 'dnsRecord.copyLabel': 'Copy', 'dnsRecord.rootTxt': 'Root TXT', 'dnsRecord.verificationTxt': 'Verification TXT', 'dnsRecord.dkimTxt': 'DKIM TXT', 'dnsRecord.dmarcTxt': 'DMARC TXT', 'dnsRecord.senderA': 'Sending host A', 'dnsRecord.ptr': 'Sending IP PTR', 'domainHealth.sendingDomain': 'Sending domain', 'domainHealth.dnsProgress': 'DNS check progress', 'domainHealth.passed': 'passed', 'domainHealth.dnsIssues': 'DNS issues', 'domainHealth.dnsApi': 'DNS API', 'domainHealth.oneClickDns': 'Configure DNS', 'domainHealth.checkNow': 'Check now', 'domainHealth.sendTest': 'Send test email', 'domainHealth.edit': 'Edit settings', 'addDomain.title': 'Add sending domain', 'addDomain.stepDomain': 'Domain', 'addDomain.stepDns': 'DNS method', 'addDomain.stepPolicy': 'DKIM / SPF / DMARC', 'addDomain.stepConfirm': 'Confirm', 'addDomain.create': 'Create domain', 'addDomain.domainExtra': 'Use the root domain without http, paths, or email addresses.', 'addDomain.domainRequired': 'Enter the sending domain', 'addDomain.senderHostRequired': 'Enter the sending host', 'addDomain.sendingIpRequired': 'Enter the sending IP', 'addDomain.dnsExtra': 'You can create the domain without a credential and configure DNS manually later.', 'addDomain.manualDns': 'Manual DNS', 'addDomain.dnsHint': 'With a DNS API credential, the detail page can write verification, DKIM, SPF, DMARC, and sending host A records.', 'addDomain.selectorRequired': 'Enter the DKIM selector', 'addDomain.spfExtra': 'Third-party SPF includes', 'addDomain.generatedTitle': 'MailHub will generate', 'addDomain.recordVerification': 'Domain verification TXT', 'addDomain.recordDkim': 'DKIM TXT', 'addDomain.recordSpf': 'SPF TXT', 'addDomain.recordDmarc': 'DMARC TXT', 'addDomain.recordSenderA': 'Sending host A record', 'addDomain.recordPtr': 'PTR reverse DNS check hint', 'addDomain.immediateCheck': 'Check DNS immediately after creation', 'logs.title': 'Sending logs', 'logs.time': 'Time', 'logs.recipient': 'Recipient', 'logs.domain': 'Sending domain', 'logs.errorReason': 'Error reason', 'logs.viewDetail': 'View detail', 'logs.domainPlaceholder': 'Sending domain', 'logs.statusPlaceholder': 'Status', 'logs.recipientPlaceholder': 'Search recipient', 'logs.detailTitle': 'Sending detail', 'logs.deliveryLog': 'Full delivery log', 'logs.copyDeliveryLog': 'Copy delivery log', 'logs.noDeliveryLog': 'No structured delivery log. This may be a historical event.', 'logs.sender': 'Sender', 'logs.subject': 'Subject', 'logs.messageId': 'Message ID', 'logs.finalResponse': 'Final response', 'logs.messageBytes': 'Message bytes', 'logs.queueId': 'Postfix Queue ID', 'logs.deliveredAt': 'Delivered at', 'logs.deliveryAttempts': 'Delivery attempts', 'logs.noDeliveryAttempts': 'No final delivery receipt yet. The message may still be queued or historical.', 'logs.statusQueued': 'Queued', 'logs.statusSent': 'Sent', 'logs.statusDeferred': 'Deferred', 'logs.statusBounced': 'Bounced', 'logs.statusFailed': 'Failed', 'smtp.connectionTitle': 'SMTP connection', 'smtp.loginCredentialsTitle': 'Sending login credentials', 'smtp.username': 'Username', 'smtp.password': 'Password', 'smtp.usernameRequired': 'Enter SMTP username', 'smtp.passwordRequired': 'Enter SMTP password', 'smtp.passwordSet': 'Set', 'smtp.passwordEmpty': 'Empty', 'smtp.passwordUnavailable': 'Reset before copying', 'smtp.create': 'New credential', 'smtp.createTitle': 'New sending login credential', 'smtp.editTitle': 'Edit sending login credential', 'smtp.deleteConfirm': 'Delete this SMTP login credential?', 'smtp.passwordExtra': 'Leave empty to keep the current password. Copy the current password from the connection section above.', 'smtp.regenerate': 'Regenerate password', 'smtp.resetToCopy': 'Reset before copying', 'smtpRelay.title': 'Advanced: external SMTP relays', 'smtpRelay.create': 'New relay', 'smtpRelay.createTitle': 'New outbound SMTP relay', 'smtpRelay.editTitle': 'Edit outbound SMTP relay', 'smtpRelay.name': 'Name', 'smtpRelay.nameRequired': 'Enter the relay name', 'smtpRelay.server': 'Server', 'smtpRelay.hostRequired': 'Enter SMTP Host', 'smtpRelay.portRequired': 'Enter SMTP Port', 'smtpRelay.username': 'Username', 'smtpRelay.password': 'Password', 'smtpRelay.passwordSet': 'Set', 'smtpRelay.passwordEmpty': 'Empty', 'smtpRelay.passwordExtra': 'Saved passwords are shown when editing. Save an empty value to remove the password.', 'smtpRelay.generatePassword': 'Generate password', 'smtpRelay.heloExtra': 'Leave empty to use the system default HELO.', 'smtpRelay.default': 'Default', 'smtpRelay.domainDefault': 'Default outbound SMTP relay', 'smtpRelay.domainDefaultExtra': 'When empty, MailHub uses request relay, user default relay, then system SMTP.', 'smtpRelay.useResolutionOrder': 'Use default selection order', 'smtpRelay.deleteConfirm': 'Delete this SMTP relay? Bound domains will fall back to the default selection order.', 'dnsApi.title': 'DNS API credentials', 'dnsApi.createTitle': 'New DNS API', 'dnsApi.editTitle': 'Edit', 'dnsApi.zone': 'Zone / root domain', 'dnsApi.zoneRequired': 'Enter the Zone or root domain', 'dnsApi.cloudflareZoneExtra': 'For Cloudflare, use any accessible Zone for testing. One-click DNS matches the current sending domain automatically.', 'dnsApi.tokenExtra': 'Requires Zone DNS Edit permission.', 'dnsApi.keepSecret': 'Leave empty to keep the existing secret.', 'dnsApi.save': 'Save changes', 'dnsApi.create': 'Create credential', 'dnsApi.secretHint': 'Secrets are encrypted server-side and never shown in the list.', 'settings.checkItem': 'Check', 'settings.deliveryChecks': 'Sending Environment Checks', 'settings.noPermission': 'This account cannot access system settings.', 'settings.save': 'Save settings', 'admin.title': 'Admin Panel', 'admin.users': 'Users', 'admin.resources': 'Resources', 'admin.migration': 'Merge', 'admin.systemEmail': 'System Email', 'admin.auditLogs': 'Audit Logs', 'metrics.accepted': 'Accepted', 'metrics.failed': 'Failed', 'metrics.recipients': 'Recipients', 'metrics.total': 'Total', 'status.success': 'Passed', 'status.pending': 'Pending', 'status.error': 'Misconfigured', 'status.idle': 'Not configured', 'tokens.createTitle': 'Create API Token', 'tokens.name': 'Name', 'tokens.namePlaceholder': 'Production API', 'tokens.nameRequired': 'Enter a token name', 'tokens.create': 'Create Token', 'tokens.listTitle': 'API Tokens', 'tokens.prefix': 'Token Prefix', 'tokens.fullToken': 'Full Token', 'tokens.copyFull': 'Copy full token', 'tokens.copyPrefix': 'Copy prefix', 'tokens.createdTitle': 'API Token created', 'tokens.createdWarning': 'The full token is shown only once. Copy it now and store it somewhere secure.', 'tokens.createdSuccess': 'Token created', 'tokens.deletedSuccess': 'Token deleted', 'tokens.secretUnavailable': 'Full token is only shown at creation time', 'tokens.lastUsed': 'Last used', 'tokens.neverUsed': 'Never used', 'tokens.createdAt': 'Created at', 'tokens.actions': 'Actions', 'tokens.deleteConfirm': 'Delete this token?', 'tokens.copyCreated': 'Copy full token', 'tokens.prefixOnlyHelp': 'Historical tokens do not store plaintext. The prefix is only for identification.', 'tokens.docsTitle': 'Sending API guide', 'tokens.endpoint': 'API Endpoint', 'tokens.authHeader': 'Authentication', 'tokens.authHeaderValue': 'Authorization: Bearer ', 'tokens.contentType': 'Content-Type', 'tokens.requestFields': 'Request fields', 'tokens.fieldFrom': 'from: sender address. The domain must be added and verified.', 'tokens.fieldTo': 'to: recipient address. Single email or an array of emails.', 'tokens.fieldSubject': 'subject: email subject.', 'tokens.fieldText': 'text: plain text body.', 'tokens.fieldHtml': 'html: optional HTML body.', 'tokens.curlExample': 'curl example', 'tokens.nodeExample': 'Node / Fetch example', 'tokens.requestExample': 'Request body example', 'tokens.responseExample': 'Success response example', 'tokens.securityTips': 'Security tips', 'tokens.securityTipStore': 'Store tokens only on the server side. Do not put them in browser code or public repositories.', 'tokens.securityTipRotate': 'Use separate tokens per environment. Delete and recreate immediately after a leak.', 'tokens.securityTipDomain': 'The From domain must belong to this account. Verify DNS before production sending.', 'tokens.noTokenHint': 'Copy the full secret right after creation. Historical tokens show prefixes only, so examples use a placeholder.', 'webhooks.title': 'Webhooks', 'webhooks.subtitle': 'Push delivery updates to your HTTPS endpoint when mail is sent, bounced, or failed.', 'webhooks.create': 'Create webhook', 'webhooks.createTitle': 'Create webhook', 'webhooks.editTitle': 'Edit webhook', 'webhooks.name': 'Name', 'webhooks.namePlaceholder': 'Production deliveries', 'webhooks.nameRequired': 'Enter a webhook name', 'webhooks.url': 'Callback URL', 'webhooks.urlPlaceholder': 'https://example.com/webhooks/mailhub', 'webhooks.urlRequired': 'Enter a callback URL', 'webhooks.urlHint': 'Use HTTPS in production. Verify requests with the X-MailHub-Signature header.', 'webhooks.events': 'Events', 'webhooks.eventsRequired': 'Select at least one event', 'webhooks.eventSent': 'Sent', 'webhooks.eventBounced': 'Bounced', 'webhooks.eventFailed': 'Failed', 'webhooks.enabled': 'Enabled', 'webhooks.disabled': 'Disabled', 'webhooks.scope': 'Scope', 'webhooks.scopeAccount': 'Account', 'webhooks.scopeDomain': 'Domain', 'webhooks.domain': 'Domain', 'webhooks.domainAccount': 'Entire account', 'webhooks.domainOverrideHelp': 'If this domain has any enabled endpoint for an event, account-level endpoints for that event are skipped.', 'webhooks.secret': 'Signing secret', 'webhooks.secretPrefix': 'Secret prefix', 'webhooks.secretCreatedTitle': 'Webhook secret created', 'webhooks.secretRotatedTitle': 'Webhook secret rotated', 'webhooks.secretCreatedWarning': 'The full secret is shown only once. Copy it now and store it somewhere secure.', 'webhooks.copySecret': 'Copy full secret', 'webhooks.rotateSecret': 'Rotate secret', 'webhooks.rotateConfirm': 'Rotate this webhook signing secret? The previous secret stops working immediately.', 'webhooks.test': 'Send test', 'webhooks.testQueued': 'Test delivery queued', 'webhooks.deleteConfirm': 'Delete this webhook? Related delivery records will also be removed.', 'webhooks.empty': 'No webhooks yet. Create one to receive delivery status callbacks.', 'webhooks.listTitle': 'Endpoints', 'webhooks.actions': 'Actions', 'webhooks.deliveriesTitle': 'Deliveries', 'webhooks.deliveriesEmpty': 'No deliveries yet', 'webhooks.deliveriesFilterWebhook': 'Filter by webhook', 'webhooks.deliveriesFilterStatus': 'Filter by status', 'webhooks.deliveriesFilterEvent': 'Filter by event', 'webhooks.allWebhooks': 'All webhooks', 'webhooks.allStatuses': 'All statuses', 'webhooks.allEvents': 'All events', 'webhooks.statusPending': 'Pending', 'webhooks.statusProcessing': 'Processing', 'webhooks.statusSuccess': 'Success', 'webhooks.statusDead': 'Dead', 'webhooks.attemptCount': 'Attempts', 'webhooks.responseStatus': 'HTTP status', 'webhooks.error': 'Error', 'webhooks.replay': 'Replay', 'webhooks.replaySuccess': 'Delivery re-queued', 'webhooks.lastAttemptAt': 'Last attempt', 'webhooks.nextAttemptAt': 'Next attempt', 'webhooks.createdAt': 'Created at', 'webhooks.viewDeliveries': 'View deliveries', 'webhooks.docsTitle': 'Callback notes', 'webhooks.docsSignature': 'Verify the body with HMAC-SHA256; the signature is in X-MailHub-Signature.', 'webhooks.docsEvents': 'Event types: sent, bounced, and failed (terminal statuses).', 'testMail.title': 'Send test email', 'testMail.fromRequired': 'Enter the sender', 'testMail.toRequired': 'Enter the recipient', 'actions.domainCreated': 'Domain created', 'actions.dnsCheckCompleted': 'DNS check completed', 'actions.dnsCheckRefreshed': 'DNS check refreshed', 'actions.dnsApplyCompleted': 'DNS write request completed', 'actions.dnsApplyPartial': 'DNS write partially failed', 'actions.domainSaved': 'Domain settings saved', 'actions.domainDeleted': 'Domain deleted', 'actions.testMailQueued': 'Submitted to sending queue', 'actions.dnsApiCreated': 'DNS API created', 'actions.dnsApiUpdated': 'DNS API updated', 'actions.dnsApiDeleted': 'DNS API deleted', 'actions.dnsApiTestCompleted': 'Connection test completed', 'actions.smtpCreated': 'SMTP login credential created', 'actions.smtpUpdated': 'SMTP login credential updated', 'actions.smtpDeleted': 'SMTP login credential deleted', 'actions.smtpRelayCreated': 'SMTP relay created', 'actions.smtpRelayUpdated': 'SMTP relay updated', 'actions.smtpRelayDeleted': 'SMTP relay deleted', 'actions.settingsSaved': 'System settings saved', 'actions.webhookCreated': 'Webhook created', 'actions.webhookUpdated': 'Webhook updated', 'actions.webhookDeleted': 'Webhook deleted', 'actions.webhookSecretRotated': 'Webhook secret rotated', 'actions.webhookTestQueued': 'Webhook test queued', 'actions.webhookDeliveryReplayed': 'Webhook delivery replayed', 'nav.dashboard': 'Dashboard', 'nav.domains': 'Domains', 'nav.dnsApi': 'DNS API', 'nav.smtp': 'SMTP Credentials', 'nav.tokens': 'API Tokens', 'nav.logs': 'Sending Logs', 'nav.webhooks': 'Webhooks', 'nav.admin': 'Admin', 'nav.settings': 'Settings', 'nav.group.overview': 'Overview', 'nav.group.delivery': 'Delivery', 'nav.group.system': 'System' } }; export function normalizeLocale(locale = DEFAULT_LOCALE) { const value = String(locale || '').trim(); if (supportedLocales.includes(value)) return value; const lower = value.toLowerCase(); if (lower.startsWith('zh')) return 'zh-CN'; if (lower.startsWith('en')) return 'en-US'; return DEFAULT_LOCALE; } export function createTranslator(locale = DEFAULT_LOCALE) { const normalized = normalizeLocale(locale); return (key) => messages[normalized]?.[key] || messages[DEFAULT_LOCALE]?.[key] || key; } export function getLocaleLabel(locale) { return { 'zh-CN': '简体中文', 'en-US': 'English' }[normalizeLocale(locale)] || String(locale || DEFAULT_LOCALE); }