/* dparts.jsx — 穿山甲 VPN desktop · atoms (inline Lucide paths) */
const DLUCIDE = {
power: '',
'shield-check': '',
globe: '',
'loader-circle': '',
'chart-no-axes-column': '',
settings: '',
check: '',
zap: '',
'arrow-down': '',
'arrow-up': '',
search: '',
moon: '',
sun: '',
crown: '',
mail: '',
lock: '',
'check-circle': '',
'arrow-left': '',
'chevron-right': '',
send: '',
'message-circle': '',
'external-link': '',
'shopping-bag': '',
laptop: '',
smartphone: '',
'monitor-smartphone': '',
'log-out': '',
ticket: '',
clock: '',
'play-circle': '',
compass: '',
'refresh-cw': '',
'credit-card': '',
user: '',
};
function DIcon({ name, size = 20, stroke = 2, color = 'currentColor', style = {} }) {
return ;
}
function DMark({ size = 28, color = 'var(--accent)' }) {
return (
);
}
function DCC({ code, active, size = 34 }) {
return
{code}
;
}
function DSignal({ ping }) {
const lvl = ping < 40 ? 3 : ping < 90 ? 2 : 1;
return ;
}
const DSTRINGS = {
connect:{zh:'连接',en:'Connect'}, servers:{zh:'选择节点',en:'Choose server'}, stats:{zh:'统计',en:'Stats'}, settings:{zh:'设置',en:'Settings'},
navConnect:{zh:'连接',en:'Connect'}, navServers:{zh:'节点',en:'Servers'}, navStats:{zh:'统计',en:'Stats'}, navSettings:{zh:'设置',en:'Settings'},
proMember:{zh:'PRO 会员',en:'PRO member'}, until:{zh:'至 2026-12-31',en:'until 2026-12-31'},
connected:{zh:'已连接',en:'Connected'}, notConnected:{zh:'未连接',en:'Not connected'},
capOff:{zh:'未连接',en:'Not connected'}, subOff:{zh:'点击下方按钮开始保护',en:'Tap the button below to start'},
capConnecting:{zh:'连接中…',en:'Connecting…'}, subConnecting:{zh:'正在建立加密隧道',en:'Establishing encrypted tunnel'},
capOn:{zh:'已连接',en:'Connected'}, subOn:{zh:'你的网络已加密保护',en:'Your network is encrypted'},
connectNow:{zh:'点击连接',en:'CONNECT'},
search:{zh:'搜索国家 / 城市',en:'Search country / city'},
trafficMonth:{zh:'本月流量',en:'Traffic'}, avgPing:{zh:'平均延迟',en:'Avg ping'}, durMonth:{zh:'本月时长',en:'Time'},
weekTraffic:{zh:'本周流量 (GB)',en:'This week (GB)'},
autostart:{zh:'开机自启动',en:'Launch at login'}, autostartSub:{zh:'登录系统时自动启动穿山甲',en:'Start Pangolin when you log in'},
smartRoute:{zh:'智能分流',en:'Smart routing'}, smartRouteSub:{zh:'海外应用加速,本地直连',en:'Accelerate overseas apps, keep local direct'},
killSwitch:{zh:'Kill Switch',en:'Kill Switch'}, killSwitchSub:{zh:'断线时阻断网络,防止 IP 泄露',en:'Block traffic if the VPN drops'},
language:{zh:'语言',en:'Language'}, darkAppearance:{zh:'深色外观',en:'Dark appearance'}, stateOn:{zh:'已开启',en:'On'}, followLight:{zh:'跟随浅色',en:'Off'},
protocol:{zh:'协议',en:'Protocol'}, version:{zh:'版本',en:'Version'},
days:{zh:['周一','周二','周三','周四','周五','周六','周日'],en:['Mon','Tue','Wed','Thu','Fri','Sat','Sun']},
/* auth */
authTagline:{zh:'极速 · 稳定 · 省心',en:'Fast · Stable · Effortless'},
tabLogin:{zh:'登录',en:'Log in'}, tabRegister:{zh:'注册',en:'Sign up'},
emailLabel:{zh:'邮箱',en:'Email'}, emailPh:{zh:'你的邮箱地址',en:'your@email.com'},
pwLabel:{zh:'密码',en:'Password'}, pwPh:{zh:'输入密码',en:'Enter password'}, setPwPh:{zh:'设置登录密码(用于多端登录)',en:'Set a password (for multi-device login)'},
codeLabel:{zh:'邮箱验证码',en:'Verification code'}, codeSentTo:{zh:'验证码已发送至',en:'Code sent to'},
sendCode:{zh:'发送验证码',en:'Send code'}, resend:{zh:'重新发送',en:'Resend'},
doLogin:{zh:'登录',en:'Log in'}, doNext:{zh:'下一步',en:'Next'}, doCreate:{zh:'创建账户',en:'Create account'},
forgotPw:{zh:'忘记密码?',en:'Forgot password?'},
tos:{zh:'继续即代表同意《服务条款》与《隐私政策》',en:'By continuing you agree to our Terms & Privacy Policy'},
authSidePitch:{zh:'一个账户,全平台同步。守护你的每一次连接。',en:'One account, every device. Protecting every connection.'},
/* redeem & buy */
redeemEntry:{zh:'兑换 & 购买',en:'Redeem & buy'}, redeemTitle:{zh:'兑换 & 购买',en:'Redeem & buy'},
redeemCodeTitle:{zh:'兑换激活码',en:'Redeem a code'}, redeemPh:{zh:'输入激活码',en:'Enter activation code'}, redeemBtn:{zh:'激活',en:'Redeem'},
redeemOk:{zh:'激活成功 · PRO 已开通',en:'Activated · PRO unlocked'},
buyTitle:{zh:'购买渠道',en:'Where to buy'},
buySub:{zh:'客户端内不支持直接支付。请通过以下渠道获取激活码:',en:'In-app payment is unavailable. Get an activation code via:'},
chStore:{zh:'自助发卡商店',en:'Self-serve store'}, chStoreSub:{zh:'支付宝 / 微信 · 自动发码',en:'Alipay / WeChat · instant code'},
chUsdtSub:{zh:'链上转账 · 最隐私 · 自动发码',en:'On-chain · most private · instant code'},
smartSelect:{zh:'智能选择',en:'Smart select'}, smartSub:{zh:'根据当前网络环境,自动选择最优节点',en:'Picks the best node for your network'},
recommended:{zh:'推荐',en:'Recommended'},
twoFA:{zh:'双重认证',en:'Two-factor auth'}, twoFASub:{zh:'PRO 专享 · 登录需身份验证器动态码',en:'PRO only · TOTP code at login'},
ucEntry:{zh:'Web 用户中心',en:'Web account center'}, ucEntrySub:{zh:'订阅导入 · 邀请返利',en:'Subscription import · referral'}, ucOpen:{zh:'打开',en:'Open'},
/* quota + free (口径见 CLAUDE.md §7,与移动端一致) */
quotaToday:{zh:'今日剩余',en:'Left today'}, minutes:{zh:'分钟',en:'min'},
quotaFree:{zh:'免费版 · 每日 10 分钟',en:'Free · 10 min/day'},
watchAd:{zh:'看广告开始使用',en:'Watch ad to start'},
adUnlocked:{zh:'已解锁 · 今日可用',en:'Unlocked for today'},
freePlanName:{zh:'免费版',en:'Free'},
freeDemo:{zh:'演示:免费版视角',en:'Demo: free-tier view'}, freeDemoSub:{zh:'切换连接页的额度展示与套餐横幅',en:'Toggles quota UI & plan banner'},
checkUpdate:{zh:'检查更新',en:'Check for updates'},
replayOnboarding:{zh:'查看首次引导',en:'View onboarding'}, replayOnboardingSub:{zh:'演示用 · 重看 3 屏引导',en:'Demo · replay the 3 intro screens'},
/* 2FA login step (与用户中心一致) */
twoFATitle:{zh:'双重认证',en:'Two-factor auth'},
twoFAHint:{zh:'你的账户已开启双重认证。请输入身份验证器 App 中的 6 位动态码。',en:'Two-factor auth is on for this account. Enter the 6-digit code from your authenticator app.'},
twoFAConfirm:{zh:'验证并登录',en:'Verify & log in'},
twoFABack:{zh:'返回上一步',en:'Back'},
chTgSub:{zh:'@PangolinVPN_bot',en:'@PangolinVPN_bot'}, chLineSub:{zh:'@pangolinvpn',en:'@pangolinvpn'},
chEmail:{zh:'邮箱客服',en:'Email support'}, chEmailSub:{zh:'buy@pangolin.vpn',en:'buy@pangolin.vpn'},
/* account management (integrated dashboard) */
navAccount:{zh:'账户',en:'Account'},
curPlan:{zh:'当前套餐',en:'Current plan'}, renew:{zh:'续费 / 升级',en:'Renew / Upgrade'},
myDevices:{zh:'我的设备',en:'My devices'}, devicesSub:{zh:'PRO 套餐最多 5 台设备同时在线',en:'Up to 5 devices on PRO'},
thisDevice:{zh:'当前设备',en:'This device'}, lastActive:{zh:'最近活跃',en:'Last active'}, remove:{zh:'移除',en:'Remove'},
choosePlan:{zh:'选择套餐',en:'Choose your plan'}, free:{zh:'免费版',en:'Free'}, proPlan:{zh:'专业版',en:'Pro'}, team:{zh:'团队版',en:'Team'},
perMonth:{zh:'/月',en:'/mo'}, current:{zh:'当前',en:'Current'}, upgrade:{zh:'立即升级',en:'Upgrade'}, choose:{zh:'选择',en:'Choose'}, mostPopular:{zh:'最受欢迎',en:'Popular'},
feFree:{zh:['仅 1 个基础节点','每日 10 分钟时长','使用前观看广告','注册享 7 天免费试用'],en:['1 basic node only','10 min per day','Watch an ad to start','7-day free trial on sign-up']},
fePro:{zh:['80+ 全球节点','无限流量 · 极速','5 台设备同时在线','流媒体优化'],en:['80+ locations','Unlimited · fast','5 devices','Streaming optimized']},
feTeam:{zh:['Pro 全部功能','10 个成员席位','集中计费与管理','优先客服'],en:['Everything in Pro','10 seats','Central billing','Priority support']},
/* account info */
accInfoTitle:{zh:'账户信息',en:'Account info'}, accEmail:{zh:'邮箱',en:'Email'}, accPassword:{zh:'密码',en:'Password'}, accChange:{zh:'修改',en:'Change'},
accUsage:{zh:'本月用量',en:'Used this month'}, accSignOut:{zh:'退出登录',en:'Sign out'},
backToAccount:{zh:'返回账户',en:'Back to account'},
/* demo replay */
replayAuth:{zh:'查看登录 / 注册流程',en:'View login / sign-up'}, replayAuthSub:{zh:'演示用 · 退出到登录页',en:'Demo · back to login'},
replayOnboarding:{zh:'查看首次引导',en:'View onboarding'}, replayOnboardingSub:{zh:'演示用 · 重看引导页',en:'Demo · replay intro'},
/* onboarding */
obSkip:{zh:'跳过',en:'Skip'}, obNext:{zh:'下一步',en:'Next'}, obAllow:{zh:'允许并继续',en:'Allow & continue'}, obStart:{zh:'开始使用',en:'Get started'},
ob1Title:{zh:'一键连接全球',en:'Connect worldwide'}, ob1Sub:{zh:'80+ 节点,智能选择最快线路,稳定不掉线。',en:'80+ locations, auto-fastest routing, rock-solid.'},
ob2Title:{zh:'授权网络配置',en:'Allow network setup'}, ob2Sub:{zh:'系统会请求添加一个网络配置,用于建立加密隧道。',en:'Your system will ask to add a network profile to build the encrypted tunnel.'},
ob3Title:{zh:'安全 · 无日志',en:'Private by design'}, ob3Sub:{zh:'端到端加密,我们不记录你的任何浏览数据。',en:'End-to-end encrypted. We keep zero browsing logs.'},
/* contact us */
navContact:{zh:'联系我们',en:'Contact us'},
contactIntro:{zh:'遇到问题?通过以下任一渠道联系我们,通常数分钟内回复。',en:'Need help? Reach us through any channel below — we usually reply within minutes.'},
contactTg:{zh:'Telegram 客服',en:'Telegram support'}, contactLine:{zh:'LINE 客服',en:'LINE support'},
contactEmail:{zh:'邮箱客服',en:'Email support'}, contactStore:{zh:'自助发卡商店',en:'Self-serve store'},
contactHoursTitle:{zh:'服务时间',en:'Support hours'}, contactHours:{zh:'每日 9:00 – 24:00 (GMT+8)',en:'Daily 9:00 – 24:00 (GMT+8)'},
contactFaqTitle:{zh:'常见问题',en:'FAQ'}, contactFaq:{zh:'连不上 / 兑换码无效 / 多设备登录,先查阅帮助中心。',en:'Connection issues, invalid codes, multi-device — check the Help Center first.'},
contactFaqBtn:{zh:'打开帮助中心',en:'Open Help Center'},
};
function dT(lang){ return k => { const v=DSTRINGS[k]; return v ? (v[lang]||k) : k; }; }
function dName(s,lang){ return lang==='zh'?s.name:s.en; }
function dSub(s,lang){ if(lang==='zh') return s.tag||s.en; return s.tag==='流媒体优化'?'Streaming':s.tag==='P2P'?'P2P':s.name; }
Object.assign(window, { DIcon, DMark, DCC, DSignal, DSTRINGS, dT, dName, dSub, DSERVERS: [
{ code:'HK', name:'香港 · 流媒体', en:'Hong Kong', ping:18, tag:'流媒体优化' },
{ code:'JP', name:'日本 东京', en:'Tokyo', ping:32, tag:'P2P' },
{ code:'TW', name:'台湾 台北', en:'Taipei', ping:28, tag:'' },
{ code:'SG', name:'新加坡', en:'Singapore', ping:54, tag:'P2P' },
{ code:'KR', name:'韩国 首尔', en:'Seoul', ping:41, tag:'' },
{ code:'US', name:'美国 洛杉矶', en:'Los Angeles', ping:146, tag:'流媒体优化' },
{ code:'DE', name:'德国 法兰克福', en:'Frankfurt', ping:198, tag:'' },
{ code:'UK', name:'英国 伦敦', en:'London', ping:210, tag:'' },
] });