43c76fb978
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Successful in 25s
ci-pangolin / Lint — shellcheck (push) Successful in 29s
ci-pangolin / Cleartext Scan — Android 禁明文 (push) Successful in 22s
ci-pangolin / OpenAPI Sync Check (push) Successful in 40s
ci-pangolin / Portable SQL — 可移植性 (mysql/sqlite) (push) Successful in 19s
ci-pangolin / Flutter — analyze + test (push) Failing after 4m59s
ci-pangolin / Codegen Drift — token 生成物未漂移 (push) Successful in 1m51s
ci-pangolin / DS-flow — 原型/跨端同源/代码色单源闸 (push) Successful in 5s
ci-pangolin / Go — build + test (push) Failing after 1m33s
ci-pangolin / E2E Smoke — L4 进程级端到端 (push) Failing after 14s
ci-pangolin / Go — integration (mysql/redis testcontainers) (push) Failing after 4m59s
ci-pangolin / Golden — 视觉回归 (全量:components/auth/desktop/tablet) (push) Failing after 4s
# Conflicts: # docs/index.html # server/cmd/server/main.go
431 lines
13 KiB
Dart
431 lines
13 KiB
Dart
// strings_en.dart — English copy resources (single-language display)
|
||
//
|
||
// Red-line words forbidden: VPN / 翻墙 / 科学上网 / 突破封锁 / 自由穿越 / Go anywhere.
|
||
// Positioning: network acceleration / experience optimization + privacy.
|
||
// Plan numbers follow design/CLAUDE.md §7.
|
||
import 'app_text.dart';
|
||
|
||
class StringsEn extends AppText {
|
||
const StringsEn();
|
||
|
||
@override
|
||
AppLang get lang => AppLang.en;
|
||
|
||
@override
|
||
String get brand => 'Pangolin';
|
||
@override
|
||
String get online => '● Online';
|
||
@override
|
||
String get offline => '○ Offline';
|
||
@override
|
||
String get capOff => 'Tap to connect';
|
||
@override
|
||
String get capConnecting => 'Connecting…';
|
||
@override
|
||
String get capOn => 'Connected · Encrypted';
|
||
@override
|
||
String get connectNow => 'CONNECT';
|
||
@override
|
||
String get secure => 'SECURE';
|
||
|
||
@override
|
||
String get tabConnect => 'Connect';
|
||
@override
|
||
String get tabServers => 'Servers';
|
||
@override
|
||
String get tabStats => 'Stats';
|
||
@override
|
||
String get tabMe => 'Account';
|
||
|
||
@override
|
||
String get currentNode => 'Current node';
|
||
@override
|
||
String get download => 'Down';
|
||
@override
|
||
String get upload => 'Up';
|
||
@override
|
||
String get latency => 'Ping';
|
||
|
||
@override
|
||
String get quotaToday => 'Left today';
|
||
@override
|
||
String get minutes => 'min';
|
||
@override
|
||
String get quotaFree => 'Free · 10 min/day';
|
||
@override
|
||
String get planFreeTag => 'Free';
|
||
@override
|
||
String get watchAd => 'Watch ad to start';
|
||
@override
|
||
String get adUnlocked => 'Unlocked for today';
|
||
@override
|
||
String get quotaLeftLabel => 'Left';
|
||
@override
|
||
String get quotaUsedUp => 'Daily free time used up';
|
||
@override
|
||
String get watchAdMore => 'Watch ad for more time';
|
||
@override
|
||
String get quotaExhaustedNotice => 'Daily free time used up. Watch an ad to add time or upgrade.';
|
||
@override
|
||
String get adPlaying => 'Ad playing…';
|
||
@override
|
||
String adRewarded(int minutes) => '+$minutes min added';
|
||
@override
|
||
String get adFailed => 'Failed to add time, please retry';
|
||
@override
|
||
String get quotaDesktopTitle => 'Daily free time used up';
|
||
@override
|
||
String get quotaDesktopBody => 'Watch ads in the mobile app to add time, or upgrade for unlimited access.';
|
||
@override
|
||
String get gotIt => 'Got it';
|
||
|
||
@override
|
||
String get chooseNode => 'Choose server';
|
||
@override
|
||
String get searchPh => 'Search country / city';
|
||
@override
|
||
String get smartSelect => 'Smart select';
|
||
@override
|
||
String nodeSwitchTitle(String name) => 'Switch to $name?';
|
||
@override
|
||
String get nodeSwitchBody => 'This disconnects the current link and reconnects to this node.';
|
||
@override
|
||
String get nodeSwitchConfirm => 'Switch';
|
||
@override
|
||
String get nodeUnhealthySwitched => 'Current node unreachable — switched automatically';
|
||
@override
|
||
String get nodeUnhealthyError => 'Current node is unreachable — reconnect or switch node';
|
||
@override
|
||
String get nodeReconnecting => 'Network unstable, reconnecting…';
|
||
@override
|
||
String get smartSub => 'Picks the best node for your network';
|
||
@override
|
||
String get recommended => 'Recommended';
|
||
|
||
@override
|
||
String get statsTitle => 'Statistics';
|
||
@override
|
||
String get trafficMonth => 'Traffic';
|
||
@override
|
||
String get avgPing => 'Avg ping';
|
||
@override
|
||
String get durMonth => 'Time';
|
||
@override
|
||
String get weekTraffic => 'This week (GB)';
|
||
@override
|
||
List<String> get days7 => const ['M', 'T', 'W', 'T', 'F', 'S', 'S'];
|
||
@override
|
||
String get byDevice => 'By device';
|
||
@override
|
||
String get noDeviceUsage => 'No device usage yet';
|
||
@override
|
||
String get periodMonth => 'This month';
|
||
@override
|
||
String get periodWeek => 'This week';
|
||
@override
|
||
String get periodToday => 'Today';
|
||
@override
|
||
String get statDown => 'Download';
|
||
@override
|
||
String get statUp => 'Upload';
|
||
@override
|
||
String get statDuration => 'Duration';
|
||
@override
|
||
String get chartTwoWeeks => 'Last 2 weeks';
|
||
@override
|
||
String get allDevices => 'All devices';
|
||
|
||
@override
|
||
String get meTitle => 'Account';
|
||
@override
|
||
String get proMember => 'PRO member';
|
||
@override
|
||
String get freePlanName => 'Free';
|
||
@override
|
||
String get expires => 'Expires';
|
||
@override
|
||
String get upgradeBtn => 'Renew / Upgrade';
|
||
@override
|
||
String get accInfoTitle => 'Account info';
|
||
@override
|
||
String get accEmail => 'Email';
|
||
@override
|
||
String get accPassword => 'Password';
|
||
@override
|
||
String get accChange => 'Change';
|
||
@override
|
||
String get deviceLimitTitle => 'Device limit reached';
|
||
@override
|
||
String get deviceLimitDesc => 'Your plan allows up to %s devices. Remove one to continue.';
|
||
@override
|
||
String get deviceLimitRemoveOldest => 'Remove least recently used';
|
||
@override
|
||
String get myDevices => 'My devices';
|
||
@override
|
||
String get devicesSub => 'Up to 3 devices on PRO';
|
||
@override
|
||
String get thisDevice => 'This device';
|
||
@override
|
||
String get remove => 'Remove';
|
||
@override
|
||
String get devOnline => 'Online';
|
||
@override
|
||
String get devOffline => 'Offline';
|
||
@override
|
||
String get devLastOnline => 'Last online';
|
||
@override
|
||
String get devNeverLogin => 'Never logged in';
|
||
@override
|
||
String get devForceLogout => 'Force logout';
|
||
@override
|
||
String get devClearLogin => 'Clear login info';
|
||
@override
|
||
String get devRename => 'Rename';
|
||
@override
|
||
String get devRenameHint => 'Device name';
|
||
@override
|
||
String get devSave => 'Save';
|
||
@override
|
||
String get devForceLogoutConfirm => 'This revokes the device\'s login session — it will be kicked offline and must sign in again. The device stays in the list.';
|
||
@override
|
||
String get devClearLoginConfirm => 'This removes the device from the list entirely and revokes its login session and data-plane credential. The device must sign in again to be used.';
|
||
@override
|
||
String get devCancel => 'Cancel';
|
||
@override
|
||
String get sessionRevokedTitle => 'This device was signed out';
|
||
@override
|
||
String get sessionRevokedBody => 'Your account signed this device out from another device. Please sign in again.';
|
||
@override
|
||
String get sessionRevokedOk => 'Sign in again';
|
||
@override
|
||
String get redeemEntry => 'Redeem & buy';
|
||
@override
|
||
String get contactEntry => 'Contact us';
|
||
@override
|
||
String get signOut => 'Sign out';
|
||
@override
|
||
String get language => 'Language';
|
||
@override
|
||
String get darkAppearance => 'Dark appearance';
|
||
@override
|
||
String get stateOn => 'On';
|
||
@override
|
||
String get followLight => 'Off';
|
||
@override
|
||
String get protocol => 'Protocol';
|
||
@override
|
||
String get settingsTitle => 'Settings';
|
||
@override
|
||
String get autostart => 'Launch at startup';
|
||
@override
|
||
String get autostartSub => 'Run automatically on system start';
|
||
@override
|
||
String get autoConnect => 'Auto-connect';
|
||
@override
|
||
String get autoConnectSub => 'Connect automatically on launch';
|
||
@override
|
||
String autoConnectingTo(String name) => 'Auto-connecting to $name…';
|
||
@override
|
||
String get smartRoute => 'Smart routing';
|
||
@override
|
||
String get smartRouteSub => 'Accelerate abroad, direct at home';
|
||
@override
|
||
String get killSwitch => 'Kill Switch';
|
||
@override
|
||
String get killSwitchSub => 'Block traffic if the link drops';
|
||
@override
|
||
String get checkUpdate => 'Check for updates';
|
||
@override
|
||
String get webUserCenter => 'User Center (Web)';
|
||
@override
|
||
String updateAvailableTitle(String version) => 'New version v$version available';
|
||
@override
|
||
String get updateNotesFallback => 'This update includes fixes and stability improvements.';
|
||
@override
|
||
String get updateLater => 'Later';
|
||
@override
|
||
String get updateDownload => 'Download update';
|
||
@override
|
||
String get updateUpToDate => 'You are up to date';
|
||
@override
|
||
String get updateCheckFailed => 'Update check failed, try again later';
|
||
|
||
@override
|
||
String get choosePlan => 'Choose plan';
|
||
@override
|
||
String get freePlan => 'Free';
|
||
@override
|
||
String get proPlan => 'Pro';
|
||
@override
|
||
String get teamPlan => 'Team';
|
||
@override
|
||
String get perMonth => '/mo';
|
||
@override
|
||
String get current => 'Current';
|
||
@override
|
||
String get upgrade => 'Upgrade';
|
||
@override
|
||
String get choose => 'Choose';
|
||
@override
|
||
String get mostPopular => 'Popular';
|
||
@override
|
||
List<String> get featsFree => const [
|
||
'1 basic node only',
|
||
'10 min per day',
|
||
'Watch an ad to start',
|
||
'7-day free trial on sign-up',
|
||
];
|
||
@override
|
||
List<String> get featsPro =>
|
||
const ['80+ locations', 'Unlimited · fast', '5 devices', 'Streaming optimized'];
|
||
@override
|
||
List<String> get featsTeam =>
|
||
const ['Everything in Pro', '10 seats', 'Central billing', 'Priority support'];
|
||
|
||
@override
|
||
String get redeemTitle => 'Redeem & buy';
|
||
@override
|
||
String get redeemCodeTitle => 'Redeem a code';
|
||
@override
|
||
String get redeemPh => 'Enter activation code';
|
||
@override
|
||
String get redeemBtn => 'Redeem';
|
||
@override
|
||
String get redeemOk => 'Activated · PRO unlocked';
|
||
@override
|
||
String get buyTitle => 'Where to buy';
|
||
@override
|
||
String get buySub => 'In-app payment is unavailable. Get a code via:';
|
||
@override
|
||
String get chStore => 'Self-serve store';
|
||
@override
|
||
String get chEmail => 'Email support';
|
||
|
||
@override
|
||
String get contactTitle => 'Contact us';
|
||
@override
|
||
String get contactIntro =>
|
||
'Need help? Reach us via any channel below — usually replies in minutes.';
|
||
@override
|
||
String get contactEmail => 'Email support';
|
||
@override
|
||
String get contactStore => 'Self-serve store';
|
||
@override
|
||
String get contactHoursTitle => 'Support hours';
|
||
@override
|
||
String get contactHours => 'Daily 9:00 – 24:00 (GMT+8)';
|
||
|
||
@override
|
||
String get authTagline => 'Fast · Stable · Effortless';
|
||
@override
|
||
String get tabLogin => 'Log in';
|
||
@override
|
||
String get tabRegister => 'Sign up';
|
||
@override
|
||
String get emailLabel => 'Email';
|
||
@override
|
||
String get emailPh => 'your@email.com';
|
||
@override
|
||
String get pwLabel => 'Password';
|
||
@override
|
||
String get pwPh => 'Enter password';
|
||
@override
|
||
String get setPwPh => 'Set a password (for multi-device login)';
|
||
@override
|
||
String get codeLabel => 'Verification code';
|
||
@override
|
||
String codeSentTo(String email) => 'Code sent to $email';
|
||
@override
|
||
String get sendCode => 'Send code';
|
||
@override
|
||
String get resend => 'Resend';
|
||
@override
|
||
String get doLogin => 'Log in';
|
||
@override
|
||
String get doNext => 'Next';
|
||
@override
|
||
String get doCreate => 'Create account';
|
||
@override
|
||
String get forgotPw => 'Forgot password?';
|
||
@override
|
||
String get tos => 'By continuing you agree to our Terms & Privacy Policy';
|
||
|
||
@override
|
||
String get obSkip => 'Skip';
|
||
@override
|
||
String get obNext => 'Next';
|
||
@override
|
||
String get obAllow => 'Allow & continue';
|
||
@override
|
||
String get obStart => 'Get started';
|
||
@override
|
||
String get ob1Title => 'Connect worldwide';
|
||
@override
|
||
String get ob1Sub => '80+ locations, auto-fastest routing, rock-solid.';
|
||
@override
|
||
String get ob2Title => 'Allow network setup';
|
||
@override
|
||
String get ob2Sub => 'The system will ask to add a network profile to build the encrypted tunnel.';
|
||
@override
|
||
String get ob3Title => 'Private by design';
|
||
@override
|
||
String get ob3Sub => 'End-to-end encrypted. We keep zero browsing logs.';
|
||
|
||
@override
|
||
String get purchaseTitle => 'Purchase';
|
||
@override
|
||
String get paymentTitle => 'Payment';
|
||
@override
|
||
String get buyNow => 'Buy now';
|
||
@override
|
||
String get payMethodAlipay => 'Alipay';
|
||
@override
|
||
String get payMethodCrypto => 'USDT (TRC20)';
|
||
@override
|
||
String get choosePayMethod => 'Choose payment method';
|
||
@override
|
||
String get proMonthly => 'Pro · Monthly';
|
||
@override
|
||
String get proQuarterly => 'Pro · Quarterly';
|
||
@override
|
||
String get proYearly => 'Pro · Yearly';
|
||
@override
|
||
String get perQuarter => '/quarter';
|
||
@override
|
||
String get perYear => '/year';
|
||
@override
|
||
String get payAmountLabel => 'Amount';
|
||
@override
|
||
String get payAddressLabel => 'Address';
|
||
@override
|
||
String get payNetworkLabel => 'Network';
|
||
@override
|
||
String get payExactAmountHint => 'Send the exact amount; activates automatically';
|
||
@override
|
||
String get copied => 'Copied';
|
||
@override
|
||
String get openAlipay => 'Pay with Alipay';
|
||
@override
|
||
String get openAlipayHint => 'Return after paying; this page refreshes automatically';
|
||
@override
|
||
String get openAlipayFailed => "Couldn't open Alipay; check it's installed or try again";
|
||
@override
|
||
String get awaitingPayment => 'Awaiting payment';
|
||
@override
|
||
String get paySucceeded => 'Activated';
|
||
@override
|
||
String get payExpiresAt => 'Valid until';
|
||
@override
|
||
String get payDone => 'Done';
|
||
@override
|
||
String get payFailed => 'Payment failed';
|
||
@override
|
||
String get payRetry => 'Retry';
|
||
@override
|
||
String get switchPayMethod => 'Switch payment method';
|
||
@override
|
||
String get cancelOrder => 'Cancel order';
|
||
@override
|
||
String get qrNotSupported => 'Copy and open in Alipay';
|
||
}
|