/* @ds-bundle: {"format":3,"namespace":"VPNDesignSystem_4c9564","components":[],"sourceHashes":{"ui_kits/desktop/dapp.jsx":"0261ad8c8093","ui_kits/desktop/dflows.jsx":"b52d86fc92ea","ui_kits/desktop/dparts.jsx":"e7fec2d75fc0","ui_kits/desktop/macos-window.jsx":"83e5cb33277e","ui_kits/mobile/flows.jsx":"838173b11d20","ui_kits/mobile/ios-frame.jsx":"39f3a091d97d","ui_kits/mobile/parts.jsx":"44efd184bf6a","ui_kits/mobile/screens.jsx":"cde11b0b1ad6","ui_kits/tablet/tabapp.jsx":"86e2e0f22462","ui_kits/usercenter/ucapp.jsx":"abe00336c077","ui_kits/usercenter/ucparts.jsx":"ba322907d9b7","ui_kits/website/site.js":"47ee2f38bcef"},"inlinedExternals":[],"unexposedExports":[]} */

(() => {

const __ds_ns = (window.VPNDesignSystem_4c9564 = window.VPNDesignSystem_4c9564 || {});

const __ds_scope = {};

(__ds_ns.__errors = __ds_ns.__errors || []);

// ui_kits/desktop/dapp.jsx
try { (() => {
/* dapp.jsx — 穿山甲 VPN desktop · window + views (i18n) */
const {
  useState,
  useEffect,
  useRef
} = React;
function DToggle({
  on,
  onChange
}) {
  return /*#__PURE__*/React.createElement("div", {
    onClick: onChange,
    style: {
      width: 42,
      height: 25,
      borderRadius: 999,
      position: 'relative',
      cursor: 'pointer',
      flexShrink: 0,
      background: on ? 'var(--accent)' : 'var(--border-strong)',
      transition: 'background 220ms var(--ease-out)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'absolute',
      top: 3,
      left: on ? 20 : 3,
      width: 19,
      height: 19,
      borderRadius: '50%',
      background: '#fff',
      boxShadow: 'var(--shadow-sm)',
      transition: 'left 220ms var(--ease-out)'
    }
  }));
}
function DLangSwitch({
  lang,
  setLang
}) {
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      background: 'var(--bg-subtle)',
      borderRadius: 999,
      padding: 3,
      gap: 2
    }
  }, [['zh', '中文'], ['en', 'EN']].map(([v, l]) => /*#__PURE__*/React.createElement("button", {
    key: v,
    onClick: () => setLang(v),
    style: {
      border: 'none',
      cursor: 'pointer',
      borderRadius: 999,
      padding: '4px 12px',
      fontFamily: 'var(--font-sans)',
      fontSize: 12,
      fontWeight: 700,
      background: lang === v ? 'var(--accent)' : 'transparent',
      color: lang === v ? 'var(--fg-on-accent)' : 'var(--fg3)',
      transition: 'all 140ms var(--ease-out)'
    }
  }, l)));
}
function NavItem({
  icon,
  label,
  active,
  onClick
}) {
  return /*#__PURE__*/React.createElement("button", {
    onClick: onClick,
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 11,
      width: '100%',
      textAlign: 'left',
      border: 'none',
      cursor: 'pointer',
      background: active ? 'var(--accent-subtle)' : 'transparent',
      color: active ? 'var(--accent)' : 'var(--fg2)',
      padding: '9px 12px',
      borderRadius: 'var(--radius-md)',
      fontFamily: 'var(--font-sans)',
      fontSize: 13.5,
      fontWeight: active ? 600 : 500,
      transition: 'background-color 140ms var(--ease-out), color 140ms var(--ease-out)'
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: icon,
    size: 18,
    stroke: active ? 2.3 : 2,
    color: active ? 'var(--accent)' : 'var(--fg3)'
  }), label);
}
function DConnect({
  t,
  lang,
  status,
  onToggle,
  server,
  smart,
  free,
  mins,
  adDone,
  onAd,
  elapsed
}) {
  const map = {
    off: {
      fill: 'var(--sand-100)',
      fg: 'var(--clay-500)',
      icon: 'power',
      cap: t('capOff'),
      sub: t('subOff'),
      ring: 'track'
    },
    connecting: {
      fill: 'var(--accent)',
      fg: '#fff',
      icon: 'loader-circle',
      cap: t('capConnecting'),
      sub: t('subConnecting'),
      ring: 'spin'
    },
    on: {
      fill: 'var(--success)',
      fg: '#fff',
      icon: 'shield-check',
      cap: t('capOn'),
      sub: t('subOn'),
      ring: 'full'
    }
  }[status];
  const fmt = s => `${String(Math.floor(s / 3600)).padStart(2, '0')}:${String(Math.floor(s % 3600 / 60)).padStart(2, '0')}:${String(s % 60).padStart(2, '0')}`;
  const shadow = status === 'off' ? 'inset 0 0 0 1px var(--sand-200), var(--shadow-md)' : `0 0 0 8px ${status === 'on' ? 'var(--success-subtle)' : 'var(--accent-subtle)'}, var(--shadow-lg)`;
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      justifyContent: 'center',
      height: '100%',
      gap: 24,
      padding: '10px 40px'
    }
  }, /*#__PURE__*/React.createElement("button", {
    onClick: onToggle,
    style: {
      position: 'relative',
      width: 176,
      height: 176,
      borderRadius: '50%',
      border: 'none',
      cursor: 'pointer',
      background: map.fill,
      color: map.fg,
      boxShadow: shadow,
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      justifyContent: 'center',
      gap: 7,
      transition: 'box-shadow 300ms var(--ease-out), background-color 300ms var(--ease-out)'
    }
  }, /*#__PURE__*/React.createElement("svg", {
    viewBox: "0 0 176 176",
    style: {
      position: 'absolute',
      inset: 0,
      width: '100%',
      height: '100%',
      transformOrigin: 'center',
      animation: map.ring === 'spin' ? 'pg-spin 1.4s linear infinite' : 'none'
    }
  }, map.ring === 'track' && /*#__PURE__*/React.createElement("circle", {
    cx: "88",
    cy: "88",
    r: "81",
    fill: "none",
    stroke: "var(--sand-200)",
    strokeWidth: "3",
    strokeDasharray: "2 8",
    strokeLinecap: "round"
  }), map.ring === 'spin' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("circle", {
    cx: "88",
    cy: "88",
    r: "81",
    fill: "none",
    stroke: "rgba(255,255,255,.3)",
    strokeWidth: "4"
  }), /*#__PURE__*/React.createElement("circle", {
    cx: "88",
    cy: "88",
    r: "81",
    fill: "none",
    stroke: "#fff",
    strokeWidth: "4",
    strokeLinecap: "round",
    strokeDasharray: "130 380"
  })), map.ring === 'full' && /*#__PURE__*/React.createElement("circle", {
    cx: "88",
    cy: "88",
    r: "81",
    fill: "none",
    stroke: "rgba(255,255,255,.85)",
    strokeWidth: "4",
    strokeLinecap: "round"
  })), /*#__PURE__*/React.createElement(DIcon, {
    name: map.icon,
    size: 46,
    stroke: 1.7,
    style: status === 'connecting' ? {
      animation: 'pg-spin 1s linear infinite'
    } : {}
  }), status === 'off' && /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-sans)',
      fontWeight: 700,
      fontSize: 13
    }
  }, t('connectNow')), status === 'connecting' && /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontWeight: 700,
      fontSize: 13,
      letterSpacing: '0.08em'
    }
  }, "\xB7\xB7\xB7"), status === 'on' && /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontWeight: 600,
      fontSize: 15
    }
  }, fmt(elapsed))), /*#__PURE__*/React.createElement("div", {
    style: {
      textAlign: 'center'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 22,
      color: 'var(--fg1)'
    }
  }, map.cap), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13,
      color: 'var(--fg3)',
      marginTop: 4
    }
  }, map.sub), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'inline-flex',
      alignItems: 'center',
      gap: 7,
      marginTop: 10,
      background: 'var(--surface)',
      border: '1px solid var(--border)',
      borderRadius: 'var(--radius-full)',
      padding: '6px 14px',
      fontSize: 12.5,
      fontWeight: 600,
      color: 'var(--fg2)'
    }
  }, smart && /*#__PURE__*/React.createElement(DIcon, {
    name: "zap",
    size: 13,
    stroke: 2.4,
    color: "var(--accent)"
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      whiteSpace: 'nowrap'
    }
  }, smart ? `${t('smartSelect')} · ` : '', dName(server, lang), " \xB7 ", server.ping, "ms"))), free && /*#__PURE__*/React.createElement("div", {
    style: {
      width: 340,
      background: 'var(--surface)',
      borderRadius: 'var(--radius-lg)',
      padding: '12px 14px',
      boxShadow: 'var(--shadow-sm)',
      border: '1px solid var(--border)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 7,
      marginBottom: 8
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: "clock",
    size: 14,
    stroke: 2.2,
    color: "var(--accent)"
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 12,
      fontWeight: 600,
      color: 'var(--fg2)'
    }
  }, t('quotaToday')), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 13.5,
      fontWeight: 600,
      color: 'var(--fg1)',
      whiteSpace: 'nowrap'
    }
  }, mins, " ", t('minutes')), /*#__PURE__*/React.createElement("span", {
    style: {
      marginLeft: 'auto',
      fontSize: 10.5,
      fontWeight: 600,
      color: 'var(--fg3)',
      background: 'var(--bg-subtle)',
      padding: '3px 9px',
      borderRadius: 'var(--radius-full)',
      whiteSpace: 'nowrap'
    }
  }, t('quotaFree'))), /*#__PURE__*/React.createElement("div", {
    style: {
      height: 6,
      background: 'var(--bg-subtle)',
      borderRadius: 3,
      overflow: 'hidden',
      marginBottom: 10
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: `${Math.min(100, mins / 10 * 100)}%`,
      height: '100%',
      background: mins <= 3 ? 'var(--warning)' : 'var(--accent)',
      borderRadius: 3
    }
  })), adDone ? /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      gap: 7,
      color: 'var(--success)',
      fontWeight: 700,
      fontSize: 13,
      padding: '8px'
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: "check-circle",
    size: 15,
    stroke: 2.2,
    color: "var(--success)"
  }), t('adUnlocked')) : /*#__PURE__*/React.createElement("button", {
    onClick: onAd,
    style: {
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      gap: 7,
      width: '100%',
      border: '1.5px solid var(--accent-border)',
      background: 'var(--accent-subtle)',
      color: 'var(--accent)',
      fontFamily: 'var(--font-sans)',
      fontWeight: 700,
      fontSize: 13,
      padding: '8px',
      borderRadius: 'var(--radius-full)',
      cursor: 'pointer'
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: "play-circle",
    size: 15,
    stroke: 2.2
  }), t('watchAd'))), status === 'on' && /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 10
    }
  }, [['arrow-down', '86.4', 'Mb/s'], ['arrow-up', '12.1', 'Mb/s'], ['zap', String(server.ping), 'ms']].map(([ic, v, u]) => /*#__PURE__*/React.createElement("div", {
    key: ic,
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 7,
      background: 'var(--surface)',
      border: '1px solid var(--border)',
      borderRadius: 'var(--radius-md)',
      padding: '8px 14px',
      boxShadow: 'var(--shadow-sm)'
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: ic,
    size: 15,
    stroke: 2.2,
    color: "var(--accent)"
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 14,
      color: 'var(--fg1)'
    }
  }, v, /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 10,
      color: 'var(--fg3)'
    }
  }, " ", u))))));
}
function DServers({
  t,
  lang,
  current,
  onPick
}) {
  const [q, setQ] = useState('');
  const list = DSERVERS.filter(s => (s.name + s.en).toLowerCase().includes(q.toLowerCase()));
  const smartActive = current === 'AUTO';
  return /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '4px 28px 24px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 9,
      background: 'var(--bg-subtle)',
      borderRadius: 'var(--radius-md)',
      padding: '9px 13px',
      marginBottom: 16,
      maxWidth: 340
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: "search",
    size: 17,
    color: "var(--fg3)"
  }), /*#__PURE__*/React.createElement("input", {
    value: q,
    onChange: e => setQ(e.target.value),
    placeholder: t('search'),
    style: {
      border: 'none',
      background: 'transparent',
      outline: 'none',
      flex: 1,
      fontFamily: 'var(--font-sans)',
      fontSize: 13.5,
      color: 'var(--fg1)'
    }
  })), /*#__PURE__*/React.createElement("button", {
    onClick: () => onPick('AUTO'),
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 12,
      width: '100%',
      textAlign: 'left',
      cursor: 'pointer',
      background: 'var(--accent-subtle)',
      border: `1.5px solid ${smartActive ? 'var(--accent)' : 'var(--accent-border)'}`,
      borderRadius: 'var(--radius-xl)',
      padding: '14px',
      boxShadow: smartActive ? 'var(--shadow-md)' : 'var(--shadow-sm)',
      marginBottom: 10
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 38,
      height: 38,
      borderRadius: 'var(--radius-md)',
      background: 'linear-gradient(150deg,var(--clay-500),var(--clay-700))',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: "zap",
    size: 18,
    stroke: 2.2,
    color: "#fff"
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 8
    }
  }, /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-sans)',
      fontSize: 14.5,
      fontWeight: 700,
      color: 'var(--fg1)'
    }
  }, t('smartSelect')), /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 10,
      fontWeight: 700,
      color: '#fff',
      background: 'var(--accent)',
      padding: '2px 8px',
      borderRadius: 999,
      letterSpacing: '0.04em'
    }
  }, t('recommended'))), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11.5,
      color: 'var(--fg2)',
      marginTop: 3
    }
  }, t('smartSub'))), smartActive && /*#__PURE__*/React.createElement(DIcon, {
    name: "check",
    size: 18,
    color: "var(--accent)",
    stroke: 2.6
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'grid',
      gridTemplateColumns: '1fr 1fr',
      gap: 10
    }
  }, list.map(s => {
    const active = s.code === current;
    return /*#__PURE__*/React.createElement("button", {
      key: s.code,
      onClick: () => onPick(s.code),
      style: {
        display: 'flex',
        alignItems: 'center',
        gap: 12,
        textAlign: 'left',
        cursor: 'pointer',
        background: active ? 'var(--accent-subtle)' : 'var(--surface)',
        border: `1.5px solid ${active ? 'var(--accent-border)' : 'var(--border)'}`,
        borderRadius: 'var(--radius-lg)',
        padding: '12px 14px',
        boxShadow: 'var(--shadow-sm)'
      }
    }, /*#__PURE__*/React.createElement(DCC, {
      code: s.code,
      active: active
    }), /*#__PURE__*/React.createElement("div", {
      style: {
        flex: 1,
        minWidth: 0
      }
    }, /*#__PURE__*/React.createElement("div", {
      style: {
        fontFamily: 'var(--font-sans)',
        fontSize: 14,
        fontWeight: 600,
        color: 'var(--fg1)'
      }
    }, dName(s, lang)), /*#__PURE__*/React.createElement("div", {
      style: {
        fontSize: 11.5,
        color: 'var(--fg3)',
        whiteSpace: 'nowrap',
        overflow: 'hidden',
        textOverflow: 'ellipsis'
      }
    }, dSub(s, lang))), /*#__PURE__*/React.createElement("div", {
      style: {
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'flex-end',
        gap: 5
      }
    }, /*#__PURE__*/React.createElement("span", {
      style: {
        fontFamily: 'var(--font-mono)',
        fontSize: 11.5,
        color: 'var(--fg2)'
      }
    }, s.ping, "ms"), /*#__PURE__*/React.createElement(DSignal, {
      ping: s.ping
    })), active && /*#__PURE__*/React.createElement(DIcon, {
      name: "check",
      size: 17,
      color: "var(--accent)"
    }));
  })));
}
function DStats({
  t,
  lang
}) {
  const vals = [2.1, 3.4, 1.8, 4.6, 5.2, 6.1, 3.0];
  const labels = t('days');
  const max = 6.1;
  return /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '8px 32px 24px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 14,
      marginBottom: 22
    }
  }, [[t('trafficMonth'), '42.6 GB'], [t('avgPing'), '29 ms'], [t('durMonth'), '86.4 h']].map(([l, v]) => /*#__PURE__*/React.createElement("div", {
    key: l,
    style: {
      flex: 1,
      background: 'var(--surface)',
      border: '1px solid var(--border)',
      borderRadius: 'var(--radius-lg)',
      padding: '16px 18px',
      boxShadow: 'var(--shadow-sm)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      color: 'var(--fg3)',
      fontWeight: 600
    }
  }, l), /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 24,
      fontWeight: 500,
      color: 'var(--fg1)',
      marginTop: 6
    }
  }, v)))), /*#__PURE__*/React.createElement("div", {
    style: {
      background: 'var(--surface)',
      border: '1px solid var(--border)',
      borderRadius: 'var(--radius-lg)',
      padding: '18px 20px',
      boxShadow: 'var(--shadow-sm)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13,
      fontWeight: 600,
      color: 'var(--fg1)',
      marginBottom: 18
    }
  }, t('weekTraffic')), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'flex-end',
      gap: 18,
      height: 120
    }
  }, vals.map((v, i) => /*#__PURE__*/React.createElement("div", {
    key: i,
    style: {
      flex: 1,
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      gap: 8
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 10,
      color: 'var(--fg3)'
    }
  }, v), /*#__PURE__*/React.createElement("div", {
    style: {
      width: '100%',
      maxWidth: 34,
      height: `${v / max * 86}px`,
      background: 'var(--accent)',
      borderRadius: '6px 6px 0 0',
      opacity: 0.85
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11,
      color: 'var(--fg3)'
    }
  }, labels[i]))))));
}
function DSettings({
  t,
  lang,
  setLang,
  dark,
  setDark,
  free,
  setFree,
  onReplayAuth,
  onReplayOnboarding,
  onRedeem
}) {
  const [auto, setAuto] = useState(true);
  const [kill, setKill] = useState(true);
  const [boot, setBoot] = useState(true);
  const card = {
    background: 'var(--surface)',
    border: '1px solid var(--border)',
    borderRadius: 'var(--radius-lg)',
    boxShadow: 'var(--shadow-sm)',
    overflow: 'hidden',
    marginBottom: 16
  };
  const Row = ({
    title,
    sub,
    right,
    last,
    onClick
  }) => /*#__PURE__*/React.createElement("div", {
    onClick: onClick,
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 12,
      padding: '14px 18px',
      borderBottom: last ? 'none' : '1px solid var(--border)',
      cursor: onClick ? 'pointer' : 'default'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 14,
      fontWeight: 500,
      color: 'var(--fg1)'
    }
  }, title), sub && /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      color: 'var(--fg3)',
      marginTop: 2
    }
  }, sub)), right);
  return /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '8px 32px 24px',
      maxWidth: 560
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: card
  }, /*#__PURE__*/React.createElement(Row, {
    title: t('redeemEntry'),
    sub: t('proMember'),
    right: /*#__PURE__*/React.createElement(DIcon, {
      name: "chevron-right",
      size: 18,
      color: "var(--fg3)"
    }),
    last: true,
    onClick: onRedeem
  })), /*#__PURE__*/React.createElement("div", {
    style: card
  }, /*#__PURE__*/React.createElement(Row, {
    title: t('autostart'),
    sub: t('autostartSub'),
    right: /*#__PURE__*/React.createElement(DToggle, {
      on: boot,
      onChange: () => setBoot(!boot)
    })
  }), /*#__PURE__*/React.createElement(Row, {
    title: t('smartRoute'),
    sub: t('smartRouteSub'),
    right: /*#__PURE__*/React.createElement(DToggle, {
      on: auto,
      onChange: () => setAuto(!auto)
    })
  }), /*#__PURE__*/React.createElement(Row, {
    title: t('killSwitch'),
    sub: t('killSwitchSub'),
    right: /*#__PURE__*/React.createElement(DToggle, {
      on: kill,
      onChange: () => setKill(!kill)
    }),
    last: true
  })), /*#__PURE__*/React.createElement("div", {
    style: card
  }, /*#__PURE__*/React.createElement(Row, {
    title: t('language'),
    right: /*#__PURE__*/React.createElement(DLangSwitch, {
      lang: lang,
      setLang: setLang
    })
  }), /*#__PURE__*/React.createElement(Row, {
    title: t('darkAppearance'),
    sub: dark ? t('stateOn') : t('followLight'),
    right: /*#__PURE__*/React.createElement(DToggle, {
      on: dark,
      onChange: () => setDark(!dark)
    })
  }), /*#__PURE__*/React.createElement(Row, {
    title: t('protocol'),
    right: /*#__PURE__*/React.createElement("span", {
      style: {
        fontFamily: 'var(--font-mono)',
        fontSize: 13,
        color: 'var(--fg3)'
      }
    }, "WireGuard")
  }), /*#__PURE__*/React.createElement(Row, {
    title: t('checkUpdate'),
    right: /*#__PURE__*/React.createElement(DIcon, {
      name: "chevron-right",
      size: 18,
      color: "var(--fg3)"
    })
  }), /*#__PURE__*/React.createElement(Row, {
    title: t('version'),
    right: /*#__PURE__*/React.createElement("span", {
      style: {
        fontFamily: 'var(--font-mono)',
        fontSize: 13,
        color: 'var(--fg3)'
      }
    }, "v2.4.0 (macOS)"),
    last: true
  })), /*#__PURE__*/React.createElement("div", {
    style: card
  }, /*#__PURE__*/React.createElement(Row, {
    title: t('replayAuth'),
    sub: t('replayAuthSub'),
    right: /*#__PURE__*/React.createElement(DIcon, {
      name: "chevron-right",
      size: 18,
      color: "var(--fg3)"
    }),
    onClick: onReplayAuth
  }), /*#__PURE__*/React.createElement(Row, {
    title: t('replayOnboarding'),
    sub: t('replayOnboardingSub'),
    right: /*#__PURE__*/React.createElement(DIcon, {
      name: "chevron-right",
      size: 18,
      color: "var(--fg3)"
    }),
    onClick: onReplayOnboarding
  }), /*#__PURE__*/React.createElement(Row, {
    title: t('freeDemo'),
    sub: t('freeDemoSub'),
    right: /*#__PURE__*/React.createElement(DToggle, {
      on: free,
      onChange: () => setFree(!free)
    }),
    last: true
  })));
}
function DesktopApp() {
  const [stage, setStage] = useState('app'); // app | auth | onboarding — UI kit opens on the main app
  const [view, setView] = useState('connect');
  const [status, setStatus] = useState('off');
  const [code, setCode] = useState('AUTO'); // 'AUTO' = 智能选择(默认)
  const [dark, setDark] = useState(false);
  const [lang, setLang] = useState('zh');
  const [free, setFree] = useState(true); // 演示:免费版视角(与移动端一致)
  const [mins, setMins] = useState(6);
  const [adDone, setAdDone] = useState(false);
  const [elapsed, setElapsed] = useState(0);
  const timer = useRef(null);
  const t = dT(lang);
  const smart = code === 'AUTO';
  const server = smart ? DSERVERS.reduce((a, b) => a.ping < b.ping ? a : b) : DSERVERS.find(s => s.code === code);
  const titles = {
    connect: t('connect'),
    servers: t('servers'),
    stats: t('stats'),
    account: t('navAccount'),
    plans: t('choosePlan'),
    redeem: t('redeemTitle'),
    contact: t('navContact'),
    settings: t('settings')
  };
  function toggle() {
    if (status === 'off') {
      setStatus('connecting');
      setTimeout(() => {
        setStatus('on');
        setElapsed(0);
      }, 1500);
    } else setStatus('off');
  }
  function pick(c) {
    setCode(c);
    setView('connect');
    if (status === 'on') {
      setStatus('connecting');
      setTimeout(() => {
        setStatus('on');
        setElapsed(0);
      }, 1200);
    }
  }
  useEffect(() => {
    if (status === 'on') timer.current = setInterval(() => setElapsed(e => e + 1), 1000);
    return () => clearInterval(timer.current);
  }, [status]);
  if (stage === 'auth') return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      minHeight: '100vh',
      padding: 28,
      boxSizing: 'border-box'
    }
  }, /*#__PURE__*/React.createElement(DAuthFlow, {
    t: t,
    lang: lang,
    dark: dark,
    onDone: () => setStage('onboarding')
  }));
  if (stage === 'onboarding') return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      minHeight: '100vh',
      padding: 28,
      boxSizing: 'border-box'
    }
  }, /*#__PURE__*/React.createElement(DOnboarding, {
    t: t,
    lang: lang,
    dark: dark,
    onDone: () => setStage('app')
  }));
  let main;
  if (view === 'connect') main = /*#__PURE__*/React.createElement(DConnect, {
    t: t,
    lang: lang,
    status: status,
    onToggle: toggle,
    server: server,
    smart: smart,
    free: free,
    mins: mins,
    adDone: adDone,
    onAd: () => setAdDone(true),
    elapsed: elapsed
  });else if (view === 'servers') main = /*#__PURE__*/React.createElement(DServers, {
    t: t,
    lang: lang,
    current: code,
    onPick: pick
  });else if (view === 'stats') main = /*#__PURE__*/React.createElement(DStats, {
    t: t,
    lang: lang
  });else if (view === 'account') main = /*#__PURE__*/React.createElement(DAccountView, {
    t: t,
    lang: lang,
    free: free,
    onUpgrade: () => setView('plans'),
    onSignOut: () => setStage('auth')
  });else if (view === 'plans') main = /*#__PURE__*/React.createElement(DPlansView, {
    t: t,
    lang: lang,
    onChoose: () => setView('redeem')
  });else if (view === 'redeem') main = /*#__PURE__*/React.createElement(DRedeemView, {
    t: t,
    lang: lang
  });else if (view === 'contact') main = /*#__PURE__*/React.createElement(DContactView, {
    t: t,
    lang: lang
  });else main = /*#__PURE__*/React.createElement(DSettings, {
    t: t,
    lang: lang,
    setLang: setLang,
    dark: dark,
    setDark: setDark,
    free: free,
    setFree: setFree,
    onReplayAuth: () => setStage('auth'),
    onReplayOnboarding: () => setStage('onboarding'),
    onRedeem: () => setView('redeem')
  });
  return /*#__PURE__*/React.createElement("div", {
    "data-theme": dark ? 'dark' : 'light',
    style: {
      width: 920,
      height: 600,
      borderRadius: 16,
      overflow: 'hidden',
      display: 'flex',
      background: 'var(--bg)',
      boxShadow: '0 0 0 1px rgba(0,0,0,0.12), 0 28px 70px rgba(0,0,0,0.4)',
      fontFamily: 'var(--font-sans)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 204,
      flexShrink: 0,
      background: 'var(--bg-subtle)',
      borderRight: '1px solid var(--border)',
      display: 'flex',
      flexDirection: 'column',
      padding: '14px 12px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '2px 4px 16px'
    }
  }, /*#__PURE__*/React.createElement(MacTrafficLights, null)), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 9,
      padding: '0 6px 16px'
    }
  }, /*#__PURE__*/React.createElement(DMark, {
    size: 28
  }), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 16,
      color: 'var(--fg1)',
      lineHeight: 1
    }
  }, lang === 'zh' ? '穿山甲' : 'Pangolin'), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 9,
      fontWeight: 600,
      letterSpacing: '0.18em',
      color: 'var(--accent)',
      marginTop: 3
    }
  }, "PANGOLIN"))), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      gap: 3
    }
  }, /*#__PURE__*/React.createElement(NavItem, {
    icon: "power",
    label: t('navConnect'),
    active: view === 'connect',
    onClick: () => setView('connect')
  }), /*#__PURE__*/React.createElement(NavItem, {
    icon: "globe",
    label: t('navServers'),
    active: view === 'servers',
    onClick: () => setView('servers')
  }), /*#__PURE__*/React.createElement(NavItem, {
    icon: "chart-no-axes-column",
    label: t('navStats'),
    active: view === 'stats',
    onClick: () => setView('stats')
  }), /*#__PURE__*/React.createElement(NavItem, {
    icon: "user",
    label: t('navAccount'),
    active: view === 'account' || view === 'plans' || view === 'redeem',
    onClick: () => setView('account')
  }), /*#__PURE__*/React.createElement(NavItem, {
    icon: "message-circle",
    label: t('navContact'),
    active: view === 'contact',
    onClick: () => setView('contact')
  }), /*#__PURE__*/React.createElement(NavItem, {
    icon: "settings",
    label: t('navSettings'),
    active: view === 'settings',
    onClick: () => setView('settings')
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 10,
      background: 'var(--surface)',
      border: '1px solid var(--border)',
      borderRadius: 'var(--radius-md)',
      padding: '9px 11px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 30,
      height: 30,
      borderRadius: '50%',
      background: 'linear-gradient(150deg,var(--clay-500),var(--clay-700))',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: "crown",
    size: 15,
    color: "#fff"
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      minWidth: 0
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      fontWeight: 600,
      color: 'var(--fg1)',
      whiteSpace: 'nowrap',
      overflow: 'hidden',
      textOverflow: 'ellipsis'
    }
  }, free ? t('freePlanName') : t('proMember')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 10.5,
      color: 'var(--fg3)',
      whiteSpace: 'nowrap',
      overflow: 'hidden',
      textOverflow: 'ellipsis'
    }
  }, free ? t('quotaFree') : t('until'))))), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      display: 'flex',
      flexDirection: 'column',
      minWidth: 0
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      height: 52,
      flexShrink: 0,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-between',
      padding: '0 24px',
      borderBottom: '1px solid var(--border)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 10
    }
  }, (view === 'redeem' || view === 'plans') && /*#__PURE__*/React.createElement("button", {
    onClick: () => setView('account'),
    style: {
      border: 'none',
      background: 'transparent',
      cursor: 'pointer',
      padding: 4,
      display: 'flex'
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: "arrow-left",
    size: 20,
    color: "var(--fg1)"
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 17,
      color: 'var(--fg1)'
    }
  }, titles[view])), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 12
    }
  }, /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 12,
      fontWeight: 600,
      whiteSpace: 'nowrap',
      color: status === 'on' ? 'var(--success)' : 'var(--fg3)'
    }
  }, status === 'on' ? '● ' + t('connected') + ' ' + server.code : '○ ' + t('notConnected')), /*#__PURE__*/React.createElement("button", {
    onClick: () => setDark(!dark),
    style: {
      border: 'none',
      background: 'transparent',
      cursor: 'pointer',
      padding: 6,
      borderRadius: 'var(--radius-sm)',
      display: 'flex'
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: dark ? 'sun' : 'moon',
    size: 18,
    color: "var(--fg2)"
  })))), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      overflow: 'auto',
      minHeight: 0
    }
  }, main)));
}
Object.assign(window, {
  DesktopApp
});
})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/desktop/dapp.jsx", error: String((e && e.message) || e) }); }

// ui_kits/desktop/dflows.jsx
try { (() => {
/* dflows.jsx — 穿山甲 VPN desktop · auth + account management (integrated dashboard) + redeem */
const {
  useState: useStateD
} = React;
const dCard = {
  background: 'var(--surface)',
  border: '1px solid var(--border)',
  borderRadius: 'var(--radius-xl)',
  boxShadow: 'var(--shadow-sm)'
};
const dInput = {
  border: '1.5px solid var(--border-strong)',
  borderRadius: 'var(--radius-md)',
  padding: '11px 13px',
  fontFamily: 'var(--font-sans)',
  fontSize: 14,
  color: 'var(--fg1)',
  background: 'var(--bg)',
  outline: 'none',
  width: '100%',
  boxSizing: 'border-box'
};
function DField({
  label,
  children
}) {
  return /*#__PURE__*/React.createElement("label", {
    style: {
      display: 'block'
    }
  }, /*#__PURE__*/React.createElement("span", {
    style: {
      display: 'block',
      fontSize: 12.5,
      fontWeight: 600,
      color: 'var(--fg2)',
      marginBottom: 6
    }
  }, label), children);
}

/* ───────── AUTH — split panel, brand left / form right ───────── */
function DAuthFlow({
  t,
  lang,
  dark,
  onDone
}) {
  const [mode, setMode] = useStateD('login');
  const [step, setStep] = useStateD(0);
  const [email, setEmail] = useStateD('');
  const [code, setCode] = useStateD('');
  const [pw, setPw] = useStateD('');
  const [sent, setSent] = useStateD(false);
  const [totp, setTotp] = useStateD(false); // 2FA step after login (PRO)
  const [otp, setOtp] = useStateD('');
  const valid = /\S+@\S+\.\S+/.test(email);
  const tab = (id, label) => /*#__PURE__*/React.createElement("button", {
    onClick: () => {
      setMode(id);
      setStep(0);
      setSent(false);
    },
    style: {
      flex: 1,
      border: 'none',
      cursor: 'pointer',
      background: 'transparent',
      padding: '10px 0',
      fontFamily: 'var(--font-sans)',
      fontSize: 15,
      fontWeight: mode === id ? 700 : 500,
      color: mode === id ? 'var(--fg1)' : 'var(--fg3)',
      borderBottom: mode === id ? '2px solid var(--accent)' : '2px solid transparent'
    }
  }, label);
  const primary = (label, onClick, enabled) => /*#__PURE__*/React.createElement("button", {
    onClick: enabled ? onClick : undefined,
    disabled: !enabled,
    style: {
      width: '100%',
      border: 'none',
      borderRadius: 'var(--radius-full)',
      padding: '13px',
      fontFamily: 'var(--font-sans)',
      fontWeight: 700,
      fontSize: 15,
      cursor: enabled ? 'pointer' : 'not-allowed',
      background: 'var(--accent)',
      color: 'var(--fg-on-accent)',
      opacity: enabled ? 1 : 0.45,
      marginTop: 4
    }
  }, label);
  return /*#__PURE__*/React.createElement("div", {
    "data-theme": dark ? 'dark' : 'light',
    style: {
      width: 880,
      height: 560,
      borderRadius: 16,
      overflow: 'hidden',
      display: 'flex',
      boxShadow: '0 0 0 1px rgba(0,0,0,0.12), 0 28px 70px rgba(0,0,0,0.4)',
      fontFamily: 'var(--font-sans)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 340,
      flexShrink: 0,
      background: 'linear-gradient(165deg,var(--clay-500),var(--clay-800))',
      color: '#fff',
      padding: '48px 40px',
      display: 'flex',
      flexDirection: 'column'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 11
    }
  }, /*#__PURE__*/React.createElement(DMark, {
    size: 34,
    color: "#fff"
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 20
    }
  }, lang === 'zh' ? '穿山甲' : 'Pangolin')), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      display: 'flex',
      flexDirection: 'column',
      justifyContent: 'center'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 28,
      lineHeight: 1.3
    }
  }, t('authSidePitch'))), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      opacity: .8,
      letterSpacing: '0.04em'
    }
  }, t('authTagline'))), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      background: 'var(--bg)',
      padding: '44px 46px',
      display: 'flex',
      flexDirection: 'column'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      borderBottom: '1px solid var(--border)',
      marginBottom: 26
    }
  }, tab('login', t('tabLogin')), tab('register', t('tabRegister'))), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      display: 'flex',
      flexDirection: 'column',
      gap: 16
    }
  }, mode === 'login' && !totp && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(DField, {
    label: t('emailLabel')
  }, /*#__PURE__*/React.createElement("input", {
    style: dInput,
    value: email,
    onChange: e => setEmail(e.target.value),
    placeholder: t('emailPh')
  })), /*#__PURE__*/React.createElement(DField, {
    label: t('pwLabel')
  }, /*#__PURE__*/React.createElement("input", {
    style: dInput,
    type: "password",
    value: pw,
    onChange: e => setPw(e.target.value),
    placeholder: t('pwPh')
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      textAlign: 'right',
      marginTop: -6
    }
  }, /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 13,
      color: 'var(--accent)',
      fontWeight: 600,
      cursor: 'pointer'
    }
  }, t('forgotPw'))), primary(t('doLogin'), () => setTotp(true), valid && pw.length > 0)), mode === 'login' && totp && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 8
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: "shield-check",
    size: 18,
    color: "var(--accent)"
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 17,
      color: 'var(--fg1)'
    }
  }, t('twoFATitle')), /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 10,
      fontWeight: 700,
      color: 'var(--accent)',
      background: 'var(--accent-subtle)',
      border: '1px solid var(--accent-border)',
      padding: '2px 8px',
      borderRadius: 999
    }
  }, "PRO")), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12.5,
      color: 'var(--fg3)',
      lineHeight: 1.6
    }
  }, t('twoFAHint')), /*#__PURE__*/React.createElement("input", {
    value: otp,
    onChange: e => setOtp(e.target.value.replace(/\D/g, '').slice(0, 6)),
    placeholder: "\xB7\xB7\xB7\xB7\xB7\xB7",
    style: {
      ...dInput,
      fontFamily: 'var(--font-mono)',
      fontSize: 20,
      letterSpacing: '0.5em',
      textAlign: 'center'
    }
  }), primary(t('twoFAConfirm'), onDone, otp.length === 6), /*#__PURE__*/React.createElement("div", {
    onClick: () => setTotp(false),
    style: {
      textAlign: 'center',
      fontSize: 12.5,
      color: 'var(--fg3)',
      cursor: 'pointer'
    }
  }, t('twoFABack'))), mode === 'register' && step === 0 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(DField, {
    label: t('emailLabel')
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 8
    }
  }, /*#__PURE__*/React.createElement("input", {
    style: dInput,
    value: email,
    onChange: e => setEmail(e.target.value),
    placeholder: t('emailPh')
  }), /*#__PURE__*/React.createElement("button", {
    onClick: () => valid && setSent(true),
    style: {
      border: '1.5px solid var(--border-strong)',
      background: 'transparent',
      borderRadius: 'var(--radius-md)',
      padding: '0 16px',
      cursor: valid ? 'pointer' : 'default',
      color: valid ? 'var(--accent)' : 'var(--fg3)',
      fontWeight: 700,
      fontSize: 13,
      whiteSpace: 'nowrap',
      flexShrink: 0
    }
  }, sent ? t('resend') : t('sendCode')))), sent && /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      color: 'var(--success)',
      marginTop: -8,
      display: 'flex',
      alignItems: 'center',
      gap: 6
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: "check-circle",
    size: 14,
    color: "var(--success)"
  }), t('codeSentTo'), " ", email), /*#__PURE__*/React.createElement(DField, {
    label: t('codeLabel')
  }, /*#__PURE__*/React.createElement("input", {
    style: {
      ...dInput,
      fontFamily: 'var(--font-mono)',
      letterSpacing: '0.3em'
    },
    value: code,
    onChange: e => setCode(e.target.value.replace(/\D/g, '').slice(0, 6)),
    placeholder: "\xB7\xB7\xB7\xB7\xB7\xB7"
  })), primary(t('doNext'), () => setStep(1), sent && code.length === 6)), mode === 'register' && step === 1 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13,
      color: 'var(--fg2)',
      display: 'flex',
      alignItems: 'center',
      gap: 7
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: "check-circle",
    size: 15,
    color: "var(--success)"
  }), email), /*#__PURE__*/React.createElement(DField, {
    label: t('pwLabel')
  }, /*#__PURE__*/React.createElement("input", {
    style: dInput,
    type: "password",
    value: pw,
    onChange: e => setPw(e.target.value),
    placeholder: t('setPwPh')
  })), primary(t('doCreate'), onDone, pw.length >= 6))), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11,
      color: 'var(--fg3)',
      textAlign: 'center',
      lineHeight: 1.5,
      paddingTop: 18
    }
  }, t('tos'))));
}

/* ───────── ACCOUNT (integrated: plan + account info + devices) ───────── */
function DAccountView({
  t,
  lang,
  free,
  onUpgrade,
  onSignOut
}) {
  const [twoFA, setTwoFA] = useStateD(true);
  const [devices, setDevices] = useStateD([{
    id: 1,
    icon: 'laptop',
    name: 'MacBook Pro',
    os: 'macOS 26',
    active: t('thisDevice'),
    me: true
  }, {
    id: 2,
    icon: 'smartphone',
    name: 'iPhone 17',
    os: 'iOS 26',
    active: '2 min',
    me: false
  }, {
    id: 3,
    icon: 'monitor-smartphone',
    name: 'iPad Air',
    os: 'iPadOS 26',
    active: lang === 'zh' ? '3 小时前' : '3h ago',
    me: false
  }]);
  const infoRow = (label, value, action, last) => /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 12,
      padding: '14px 18px',
      borderBottom: last ? 'none' : '1px solid var(--border)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 96,
      fontSize: 13,
      fontWeight: 600,
      color: 'var(--fg2)'
    }
  }, label), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      fontSize: 14,
      color: 'var(--fg1)'
    }
  }, value), action);
  const smallBtn = {
    border: '1.5px solid var(--border-strong)',
    background: 'transparent',
    color: 'var(--fg2)',
    fontSize: 13,
    fontWeight: 600,
    padding: '7px 14px',
    borderRadius: 'var(--radius-full)',
    cursor: 'pointer'
  };
  return /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '8px 32px 28px',
      display: 'flex',
      flexDirection: 'column',
      gap: 22,
      maxWidth: 760
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      ...dCard,
      background: 'linear-gradient(150deg,var(--clay-600),var(--clay-800))',
      border: 'none',
      color: '#fff',
      padding: '20px 24px',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-between'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 15
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 48,
      height: 48,
      borderRadius: '50%',
      background: 'rgba(255,255,255,.18)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center'
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: "crown",
    size: 24,
    color: "#fff"
  })), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12.5,
      opacity: .8
    }
  }, t('curPlan')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontSize: 20,
      fontWeight: 700,
      marginTop: 2
    }
  }, free ? t('freePlanName') : t('proMember')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11.5,
      opacity: .8,
      marginTop: 3,
      fontFamily: 'var(--font-mono)',
      whiteSpace: 'nowrap'
    }
  }, free ? t('quotaFree') : `${t('expires')} 2026-12-31 · ${t('accUsage')} 42.6 GB`))), /*#__PURE__*/React.createElement("button", {
    onClick: onUpgrade,
    style: {
      border: 'none',
      background: '#fff',
      color: 'var(--clay-700)',
      fontWeight: 700,
      fontSize: 14,
      padding: '11px 20px',
      borderRadius: 'var(--radius-full)',
      cursor: 'pointer',
      display: 'inline-flex',
      alignItems: 'center',
      gap: 8
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: "ticket",
    size: 16,
    color: "var(--clay-700)"
  }), t('renew'))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontSize: 17,
      fontWeight: 700,
      color: 'var(--fg1)',
      marginBottom: 14
    }
  }, t('accInfoTitle')), /*#__PURE__*/React.createElement("div", {
    style: {
      ...dCard,
      overflow: 'hidden'
    }
  }, infoRow(t('accEmail'), 'me@pangolin.vpn', /*#__PURE__*/React.createElement("button", {
    style: smallBtn
  }, t('accChange'))), infoRow(t('accPassword'), '••••••••••', /*#__PURE__*/React.createElement("button", {
    style: smallBtn
  }, t('accChange'))), infoRow(t('twoFA'), t('twoFASub'), /*#__PURE__*/React.createElement(DToggle, {
    on: twoFA,
    onChange: () => setTwoFA(!twoFA)
  })), infoRow(t('ucEntry'), t('ucEntrySub'), /*#__PURE__*/React.createElement("button", {
    onClick: () => window.open('../usercenter/index.html', '_blank'),
    style: {
      ...smallBtn,
      display: 'inline-flex',
      alignItems: 'center',
      gap: 6
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: "external-link",
    size: 14,
    color: "var(--fg2)"
  }), t('ucOpen'))), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 12,
      padding: '14px 18px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 96,
      fontSize: 13,
      fontWeight: 600,
      color: 'var(--danger)'
    }
  }, t('accSignOut')), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }), /*#__PURE__*/React.createElement("button", {
    onClick: onSignOut,
    style: {
      ...smallBtn,
      color: 'var(--danger)',
      borderColor: 'var(--danger-subtle)',
      background: 'var(--danger-subtle)',
      display: 'inline-flex',
      alignItems: 'center',
      gap: 7
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: "log-out",
    size: 15,
    color: "var(--danger)"
  }), t('accSignOut'))))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontSize: 17,
      fontWeight: 700,
      color: 'var(--fg1)'
    }
  }, t('myDevices')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12.5,
      color: 'var(--fg3)',
      margin: '3px 0 14px'
    }
  }, t('devicesSub')), /*#__PURE__*/React.createElement("div", {
    style: {
      ...dCard,
      overflow: 'hidden'
    }
  }, devices.map((d, i) => /*#__PURE__*/React.createElement("div", {
    key: d.id,
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 14,
      padding: '14px 18px',
      borderBottom: i < devices.length - 1 ? '1px solid var(--border)' : 'none'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 40,
      height: 40,
      borderRadius: 'var(--radius-md)',
      background: 'var(--accent-subtle)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: d.icon,
    size: 20,
    color: "var(--accent)"
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 14.5,
      fontWeight: 600,
      color: 'var(--fg1)',
      display: 'flex',
      alignItems: 'center',
      gap: 8
    }
  }, d.name, d.me && /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 11,
      fontWeight: 600,
      color: 'var(--success)',
      background: 'var(--success-subtle)',
      padding: '2px 8px',
      borderRadius: 999
    }
  }, d.active)), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      color: 'var(--fg3)',
      marginTop: 2
    }
  }, d.os, !d.me && ` · ${t('lastActive')} ${d.active}`)), !d.me && /*#__PURE__*/React.createElement("button", {
    onClick: () => setDevices(devices.filter(x => x.id !== d.id)),
    style: {
      border: '1.5px solid var(--border-strong)',
      background: 'transparent',
      color: 'var(--fg2)',
      fontSize: 13,
      fontWeight: 600,
      padding: '7px 14px',
      borderRadius: 'var(--radius-full)',
      cursor: 'pointer'
    }
  }, t('remove')))))));
}

/* ───────── PLANS (shown on renew / upgrade) ───────── */
function DPlansView({
  t,
  lang,
  onChoose
}) {
  const plans = [{
    id: 'free',
    name: t('free'),
    price: '¥0',
    feats: t('feFree'),
    cta: t('current'),
    variant: 'cur'
  }, {
    id: 'pro',
    name: t('proPlan'),
    price: '¥25',
    feats: t('fePro'),
    cta: t('upgrade'),
    variant: 'pro'
  }, {
    id: 'team',
    name: t('team'),
    price: '¥99',
    feats: t('feTeam'),
    cta: t('choose'),
    variant: 'plain'
  }];
  return /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '8px 32px 28px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'grid',
      gridTemplateColumns: '1fr 1fr 1fr',
      gap: 16,
      alignItems: 'start',
      maxWidth: 760
    }
  }, plans.map(p => {
    const isPro = p.variant === 'pro';
    return /*#__PURE__*/React.createElement("div", {
      key: p.id,
      style: {
        ...dCard,
        position: 'relative',
        padding: '22px 20px',
        ...(isPro ? {
          background: 'linear-gradient(160deg,var(--clay-600),var(--clay-800))',
          border: 'none',
          color: '#fff',
          boxShadow: 'var(--shadow-md)'
        } : {})
      }
    }, isPro && /*#__PURE__*/React.createElement("div", {
      style: {
        position: 'absolute',
        top: -10,
        left: '50%',
        transform: 'translateX(-50%)',
        background: '#fff',
        color: 'var(--clay-700)',
        fontSize: 11,
        fontWeight: 700,
        padding: '3px 11px',
        borderRadius: 999,
        boxShadow: 'var(--shadow-sm)'
      }
    }, t('mostPopular')), /*#__PURE__*/React.createElement("div", {
      style: {
        fontSize: 13.5,
        fontWeight: 600,
        color: isPro ? '#fff' : 'var(--fg2)',
        opacity: isPro ? .85 : 1
      }
    }, p.name), /*#__PURE__*/React.createElement("div", {
      style: {
        fontFamily: 'var(--font-display)',
        fontSize: 30,
        fontWeight: 700,
        marginTop: 6,
        color: isPro ? '#fff' : 'var(--fg1)'
      }
    }, p.price, /*#__PURE__*/React.createElement("span", {
      style: {
        fontSize: 13,
        fontWeight: 500,
        opacity: .7
      }
    }, t('perMonth'))), /*#__PURE__*/React.createElement("div", {
      style: {
        display: 'flex',
        flexDirection: 'column',
        gap: 9,
        margin: '16px 0 18px'
      }
    }, p.feats.map((f, i) => /*#__PURE__*/React.createElement("div", {
      key: i,
      style: {
        display: 'flex',
        alignItems: 'center',
        gap: 9,
        fontSize: 13,
        color: isPro ? 'rgba(255,255,255,.92)' : 'var(--fg2)'
      }
    }, /*#__PURE__*/React.createElement(DIcon, {
      name: "check",
      size: 15,
      color: isPro ? '#fff' : 'var(--success)',
      stroke: 2.4
    }), f))), /*#__PURE__*/React.createElement("button", {
      onClick: p.variant !== 'cur' ? onChoose : undefined,
      style: {
        width: '100%',
        border: p.variant === 'cur' ? '1.5px solid var(--border-strong)' : 'none',
        cursor: p.variant === 'cur' ? 'default' : 'pointer',
        borderRadius: 'var(--radius-full)',
        padding: '11px',
        fontWeight: 600,
        fontSize: 14,
        background: isPro ? '#fff' : p.variant === 'cur' ? 'transparent' : 'var(--accent)',
        color: isPro ? 'var(--clay-700)' : p.variant === 'cur' ? 'var(--fg2)' : '#fff'
      }
    }, p.cta));
  })));
}

/* ───────── REDEEM & BUY ───────── */
function DRedeemView({
  t,
  lang
}) {
  const [code, setCode] = useStateD('');
  const [ok, setOk] = useStateD(false);
  const channels = [{
    icon: 'shopping-bag',
    name: t('chStore'),
    sub: t('chStoreSub'),
    accent: true
  }, {
    icon: 'credit-card',
    name: 'USDT (TRC20)',
    sub: t('chUsdtSub'),
    mono: false
  }, {
    icon: 'send',
    name: 'Telegram',
    sub: t('chTgSub'),
    mono: true
  }, {
    icon: 'message-circle',
    name: 'LINE',
    sub: t('chLineSub'),
    mono: true
  }, {
    icon: 'mail',
    name: t('chEmail'),
    sub: t('chEmailSub'),
    mono: true
  }];
  return /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '8px 32px 28px',
      maxWidth: 680
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      ...dCard,
      padding: '20px 22px',
      marginBottom: 24
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 14.5,
      fontWeight: 700,
      color: 'var(--fg1)',
      marginBottom: 12
    }
  }, t('redeemCodeTitle')), ok ? /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 9,
      color: 'var(--success)',
      fontWeight: 600,
      fontSize: 15,
      padding: '6px 0'
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: "check-circle",
    size: 20,
    color: "var(--success)"
  }), t('redeemOk')) : /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 10
    }
  }, /*#__PURE__*/React.createElement("input", {
    value: code,
    onChange: e => setCode(e.target.value.toUpperCase()),
    placeholder: t('redeemPh'),
    style: {
      ...dInput,
      fontFamily: 'var(--font-mono)',
      letterSpacing: '0.08em'
    }
  }), /*#__PURE__*/React.createElement("button", {
    onClick: () => code.length >= 4 && setOk(true),
    style: {
      border: 'none',
      borderRadius: 'var(--radius-md)',
      padding: '0 22px',
      background: 'var(--accent)',
      color: '#fff',
      fontWeight: 700,
      fontSize: 14,
      cursor: 'pointer',
      flexShrink: 0
    }
  }, t('redeemBtn')))), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 14.5,
      fontWeight: 700,
      color: 'var(--fg1)',
      marginBottom: 6
    }
  }, t('buyTitle')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12.5,
      color: 'var(--fg3)',
      lineHeight: 1.5,
      marginBottom: 14
    }
  }, t('buySub')), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'grid',
      gridTemplateColumns: '1fr 1fr',
      gap: 12
    }
  }, channels.map(c => /*#__PURE__*/React.createElement("button", {
    key: c.name,
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 13,
      textAlign: 'left',
      cursor: 'pointer',
      background: c.accent ? 'var(--accent-subtle)' : 'var(--surface)',
      border: `1px solid ${c.accent ? 'var(--accent-border)' : 'var(--border)'}`,
      borderRadius: 'var(--radius-lg)',
      padding: '14px 16px',
      boxShadow: 'var(--shadow-sm)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 40,
      height: 40,
      borderRadius: 'var(--radius-md)',
      background: c.accent ? 'var(--accent)' : 'var(--bg-subtle)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: c.icon,
    size: 20,
    color: c.accent ? '#fff' : 'var(--accent)'
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      minWidth: 0
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 14.5,
      fontWeight: 600,
      color: 'var(--fg1)'
    }
  }, c.name), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      color: 'var(--fg3)',
      fontFamily: c.mono ? 'var(--font-mono)' : 'var(--font-sans)',
      whiteSpace: 'nowrap',
      overflow: 'hidden',
      textOverflow: 'ellipsis'
    }
  }, c.sub)), /*#__PURE__*/React.createElement(DIcon, {
    name: "external-link",
    size: 16,
    color: "var(--fg3)"
  })))));
}

/* ───────── ONBOARDING — window card, 3 screens ───────── */
function DOnboarding({
  t,
  lang,
  dark,
  onDone
}) {
  const [i, setI] = useStateD(0);
  const steps = [{
    icon: 'globe',
    title: t('ob1Title'),
    sub: t('ob1Sub'),
    cta: t('obNext')
  }, {
    icon: 'lock',
    title: t('ob2Title'),
    sub: t('ob2Sub'),
    cta: t('obAllow')
  }, {
    icon: 'shield-check',
    title: t('ob3Title'),
    sub: t('ob3Sub'),
    cta: t('obStart')
  }];
  const s = steps[i];
  const last = i === steps.length - 1;
  return /*#__PURE__*/React.createElement("div", {
    "data-theme": dark ? 'dark' : 'light',
    style: {
      width: 560,
      height: 520,
      borderRadius: 16,
      overflow: 'hidden',
      display: 'flex',
      flexDirection: 'column',
      background: 'var(--bg)',
      boxShadow: '0 0 0 1px rgba(0,0,0,0.12), 0 28px 70px rgba(0,0,0,0.4)',
      fontFamily: 'var(--font-sans)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-between',
      padding: '18px 22px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 9
    }
  }, /*#__PURE__*/React.createElement(DMark, {
    size: 24
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 15,
      color: 'var(--fg1)'
    }
  }, lang === 'zh' ? '穿山甲' : 'Pangolin')), !last && /*#__PURE__*/React.createElement("button", {
    onClick: onDone,
    style: {
      border: 'none',
      background: 'transparent',
      cursor: 'pointer',
      fontSize: 13,
      fontWeight: 600,
      color: 'var(--fg3)'
    }
  }, t('obSkip'))), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      justifyContent: 'center',
      textAlign: 'center',
      padding: '0 56px',
      gap: 22
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 108,
      height: 108,
      borderRadius: '50%',
      background: 'var(--accent-subtle)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center'
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: s.icon,
    size: 52,
    stroke: 1.6,
    color: "var(--accent)"
  })), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontSize: 26,
      fontWeight: 700,
      color: 'var(--fg1)'
    }
  }, s.title), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 15,
      color: 'var(--fg2)',
      lineHeight: 1.6,
      marginTop: 10,
      maxWidth: 380
    }
  }, s.sub))), /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '0 40px 36px',
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      gap: 20
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 8
    }
  }, steps.map((_, k) => /*#__PURE__*/React.createElement("div", {
    key: k,
    style: {
      width: k === i ? 22 : 8,
      height: 8,
      borderRadius: 999,
      background: k === i ? 'var(--accent)' : 'var(--border-strong)',
      transition: 'all 220ms var(--ease-out)'
    }
  }))), /*#__PURE__*/React.createElement("button", {
    onClick: () => last ? onDone() : setI(i + 1),
    style: {
      width: '100%',
      maxWidth: 360,
      border: 'none',
      borderRadius: 'var(--radius-full)',
      padding: '13px',
      fontFamily: 'var(--font-sans)',
      fontWeight: 700,
      fontSize: 15,
      cursor: 'pointer',
      background: 'var(--accent)',
      color: 'var(--fg-on-accent)'
    }
  }, s.cta)));
}

/* ───────── CONTACT US ───────── */
function DContactView({
  t,
  lang
}) {
  const channels = [{
    icon: 'send',
    name: t('contactTg'),
    sub: '@PangolinVPN_bot',
    accent: true
  }, {
    icon: 'message-circle',
    name: t('contactLine'),
    sub: '@pangolinvpn'
  }, {
    icon: 'mail',
    name: t('contactEmail'),
    sub: 'support@pangolin.vpn'
  }, {
    icon: 'shopping-bag',
    name: t('contactStore'),
    sub: 'shop.pangolin.vpn'
  }];
  return /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '8px 32px 28px',
      maxWidth: 680
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13.5,
      color: 'var(--fg2)',
      lineHeight: 1.6,
      marginBottom: 18
    }
  }, t('contactIntro')), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'grid',
      gridTemplateColumns: '1fr 1fr',
      gap: 12,
      marginBottom: 22
    }
  }, channels.map(c => /*#__PURE__*/React.createElement("button", {
    key: c.name,
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 13,
      textAlign: 'left',
      cursor: 'pointer',
      background: c.accent ? 'var(--accent-subtle)' : 'var(--surface)',
      border: `1px solid ${c.accent ? 'var(--accent-border)' : 'var(--border)'}`,
      borderRadius: 'var(--radius-lg)',
      padding: '14px 16px',
      boxShadow: 'var(--shadow-sm)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 40,
      height: 40,
      borderRadius: 'var(--radius-md)',
      background: c.accent ? 'var(--accent)' : 'var(--bg-subtle)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(DIcon, {
    name: c.icon,
    size: 20,
    color: c.accent ? '#fff' : 'var(--accent)'
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      minWidth: 0
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 14.5,
      fontWeight: 600,
      color: 'var(--fg1)'
    }
  }, c.name), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      color: 'var(--fg3)',
      fontFamily: 'var(--font-mono)',
      whiteSpace: 'nowrap',
      overflow: 'hidden',
      textOverflow: 'ellipsis'
    }
  }, c.sub)), /*#__PURE__*/React.createElement(DIcon, {
    name: "external-link",
    size: 16,
    color: "var(--fg3)"
  })))), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 14
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      ...dCard,
      flex: 1,
      padding: '16px 18px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12.5,
      fontWeight: 600,
      color: 'var(--fg3)'
    }
  }, t('contactHoursTitle')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 15,
      fontWeight: 600,
      color: 'var(--fg1)',
      marginTop: 6,
      fontFamily: 'var(--font-mono)'
    }
  }, t('contactHours'))), /*#__PURE__*/React.createElement("div", {
    style: {
      ...dCard,
      flex: 2,
      padding: '16px 18px',
      display: 'flex',
      alignItems: 'center',
      gap: 14
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12.5,
      fontWeight: 600,
      color: 'var(--fg3)'
    }
  }, t('contactFaqTitle')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13,
      color: 'var(--fg2)',
      marginTop: 5,
      lineHeight: 1.5
    }
  }, t('contactFaq'))), /*#__PURE__*/React.createElement("button", {
    style: {
      border: '1.5px solid var(--border-strong)',
      background: 'transparent',
      color: 'var(--fg1)',
      fontSize: 13,
      fontWeight: 600,
      padding: '9px 15px',
      borderRadius: 'var(--radius-full)',
      cursor: 'pointer',
      whiteSpace: 'nowrap',
      flexShrink: 0
    }
  }, t('contactFaqBtn')))));
}
Object.assign(window, {
  DAuthFlow,
  DOnboarding,
  DAccountView,
  DPlansView,
  DRedeemView,
  DContactView
});
})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/desktop/dflows.jsx", error: String((e && e.message) || e) }); }

// ui_kits/desktop/dparts.jsx
try { (() => {
/* dparts.jsx — 穿山甲 VPN desktop · atoms (inline Lucide paths) */
const DLUCIDE = {
  power: '<path d="M12 2v10"/><path d="M18.36 6.64a9 9 0 1 1-12.73 0"/>',
  'shield-check': '<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/>',
  globe: '<circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/>',
  'loader-circle': '<path d="M21 12a9 9 0 1 1-6.219-8.56"/>',
  'chart-no-axes-column': '<line x1="18" x2="18" y1="20" y2="10"/><line x1="12" x2="12" y1="20" y2="4"/><line x1="6" x2="6" y1="20" y2="14"/>',
  settings: '<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/>',
  check: '<path d="M20 6 9 17l-5-5"/>',
  zap: '<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>',
  'arrow-down': '<path d="M12 5v14"/><path d="m19 12-7 7-7-7"/>',
  'arrow-up': '<path d="M12 19V5"/><path d="m5 12 7-7 7 7"/>',
  search: '<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>',
  moon: '<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>',
  sun: '<circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/>',
  crown: '<path d="M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z"/><path d="M5 21h14"/>',
  mail: '<rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>',
  lock: '<rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>',
  'check-circle': '<path d="M21.801 10A10 10 0 1 1 17 3.335"/><path d="m9 11 3 3L22 4"/>',
  'arrow-left': '<path d="m12 19-7-7 7-7"/><path d="M19 12H5"/>',
  'chevron-right': '<path d="m9 18 6-6-6-6"/>',
  send: '<path d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"/><path d="m21.854 2.147-10.94 10.939"/>',
  'message-circle': '<path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/>',
  'external-link': '<path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>',
  'shopping-bag': '<path d="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z"/><path d="M3 6h18"/><path d="M16 10a4 4 0 0 1-8 0"/>',
  laptop: '<path d="M18 5a2 2 0 0 1 2 2v8.526a2 2 0 0 0 .212.894l1.575 3.15A.5.5 0 0 1 21.342 21H2.658a.5.5 0 0 1-.445-.724l1.575-3.15A2 2 0 0 0 4 16.526V7a2 2 0 0 1 2-2z"/><path d="M20.054 15.987H3.946"/>',
  smartphone: '<rect width="14" height="20" x="5" y="2" rx="2" ry="2"/><path d="M12 18h.01"/>',
  'monitor-smartphone': '<path d="M18 8V5a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h8"/><path d="M10 19v-3.96 3.15"/><path d="M7 19h5"/><rect width="6" height="10" x="16" y="12" rx="2"/>',
  'log-out': '<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/>',
  ticket: '<path d="M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z"/><path d="M13 5v2"/><path d="M13 17v2"/><path d="M13 11v2"/>',
  clock: '<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>',
  'play-circle': '<circle cx="12" cy="12" r="10"/><polygon points="10 8 16 12 10 16 10 8"/>',
  compass: '<path d="m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"/><circle cx="12" cy="12" r="10"/>',
  'refresh-cw': '<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M3 21v-5h5"/>',
  'credit-card': '<rect width="20" height="14" x="2" y="5" rx="2"/><line x1="2" x2="22" y1="10" y2="10"/>',
  user: '<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>'
};
function DIcon({
  name,
  size = 20,
  stroke = 2,
  color = 'currentColor',
  style = {}
}) {
  return /*#__PURE__*/React.createElement("svg", {
    width: size,
    height: size,
    viewBox: "0 0 24 24",
    fill: "none",
    stroke: color,
    strokeWidth: stroke,
    strokeLinecap: "round",
    strokeLinejoin: "round",
    style: {
      display: 'block',
      flexShrink: 0,
      ...style
    },
    dangerouslySetInnerHTML: {
      __html: DLUCIDE[name] || ''
    }
  });
}
function DMark({
  size = 28,
  color = 'var(--accent)'
}) {
  return /*#__PURE__*/React.createElement("svg", {
    width: size,
    height: size,
    viewBox: "0 0 96 96",
    fill: "none",
    style: {
      display: 'block'
    }
  }, /*#__PURE__*/React.createElement("g", {
    transform: "translate(96,0) scale(-1,1)"
  }, /*#__PURE__*/React.createElement("path", {
    d: "M16 59 Q17 51 26 50 Q34 31 45 30 Q55 30 62 37 Q69 41 75 45 Q85 49 89 44 Q92 50 84 52 Q75 53 67 53 Q66 62 60 62 L56 62 Q54 55 49 55 Q47 62 37 62 L33 62 Q31 56 26 56 Q20 59 16 59 Z",
    fill: color
  }), /*#__PURE__*/React.createElement("g", {
    stroke: "#fff",
    strokeWidth: "2.4",
    strokeLinecap: "round",
    strokeLinejoin: "round",
    fill: "none",
    opacity: "0.5"
  }, /*#__PURE__*/React.createElement("path", {
    d: "M26 50 Q34 43 42 50"
  }), /*#__PURE__*/React.createElement("path", {
    d: "M36 48 Q44 41 52 48"
  }), /*#__PURE__*/React.createElement("path", {
    d: "M46 48 Q54 41 62 49"
  })), /*#__PURE__*/React.createElement("circle", {
    cx: "23",
    cy: "55",
    r: "2.2",
    fill: "#fff",
    opacity: "0.85"
  })));
}
function DCC({
  code,
  active,
  size = 34
}) {
  return /*#__PURE__*/React.createElement("div", {
    style: {
      width: size,
      height: size,
      borderRadius: 'var(--radius-md)',
      flexShrink: 0,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      fontFamily: 'var(--font-mono)',
      fontSize: size * 0.31,
      fontWeight: 600,
      background: active ? 'var(--accent)' : 'var(--bg-subtle)',
      color: active ? '#fff' : 'var(--fg2)'
    }
  }, code);
}
function DSignal({
  ping
}) {
  const lvl = ping < 40 ? 3 : ping < 90 ? 2 : 1;
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 2,
      alignItems: 'flex-end',
      height: 13
    }
  }, [4, 8, 13].map((h, i) => /*#__PURE__*/React.createElement("div", {
    key: i,
    style: {
      width: 3,
      height: h,
      borderRadius: 1,
      background: i < lvl ? 'var(--success)' : 'var(--border-strong)'
    }
  })));
}
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: ''
  }]
});
})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/desktop/dparts.jsx", error: String((e && e.message) || e) }); }

// ui_kits/desktop/macos-window.jsx
try { (() => {
/* BEGIN USAGE */
// MacOS.jsx — Simplified macOS Tahoe (Liquid Glass) window
// Based on the macOS Tahoe UI Kit. No image assets, no dependencies.
// Exports (to window): MacWindow, MacSidebar, MacSidebarItem, MacSidebarHeader, MacToolbar, MacGlass, MacTrafficLights
//
// Usage — wrap your app content in <MacWindow> to get the window chrome
// (traffic lights + titlebar). Props: width, height, title, sidebar (pass a
// <MacSidebar> element); compose MacToolbar/MacGlass inside as needed:
//
//   <MacWindow width={980} height={620} title="Documents"
//              sidebar={<MacSidebar>…</MacSidebar>}>
//     ...your app content...
//   </MacWindow>
/* END USAGE */

const MAC_FONT = '-apple-system, BlinkMacSystemFont, "SF Pro", "Helvetica Neue", sans-serif';

// ─────────────────────────────────────────────────────────────
// Liquid glass primitive — blur + white tint + inset highlight
// ─────────────────────────────────────────────────────────────
function MacGlass({
  children,
  radius = 296,
  dark = false,
  style = {}
}) {
  return /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'relative',
      borderRadius: radius,
      ...style
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'absolute',
      inset: 0,
      borderRadius: radius,
      background: dark ? 'rgba(255,255,255,0.08)' : 'rgba(255,255,255,0.35)',
      backdropFilter: 'blur(40px) saturate(180%)',
      WebkitBackdropFilter: 'blur(40px) saturate(180%)',
      border: dark ? '0.5px solid rgba(255,255,255,0.12)' : '0.5px solid rgba(255,255,255,0.6)',
      boxShadow: dark ? '0 8px 40px rgba(0,0,0,0.2)' : '0 8px 40px rgba(0,0,0,0.08), inset 0 1px 0 rgba(255,255,255,0.4)'
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'relative',
      zIndex: 1
    }
  }, children));
}

// ─────────────────────────────────────────────────────────────
// Traffic lights (14px, Tahoe colors)
// ─────────────────────────────────────────────────────────────
function MacTrafficLights({
  style = {}
}) {
  const dot = bg => /*#__PURE__*/React.createElement("div", {
    style: {
      width: 14,
      height: 14,
      borderRadius: '50%',
      background: bg,
      border: '0.5px solid rgba(0,0,0,0.1)'
    }
  });
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 9,
      alignItems: 'center',
      padding: 1,
      ...style
    }
  }, dot('#ff736a'), dot('#febc2e'), dot('#19c332'));
}

// ─────────────────────────────────────────────────────────────
// Toolbar — title + single glass pill icon
// ─────────────────────────────────────────────────────────────
function MacToolbar({
  title = 'Folder'
}) {
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 8,
      alignItems: 'center',
      padding: 8,
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: MAC_FONT,
      fontSize: 15,
      fontWeight: 700,
      color: 'rgba(0,0,0,0.85)',
      whiteSpace: 'nowrap',
      paddingLeft: 8
    }
  }, title), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }), /*#__PURE__*/React.createElement(MacGlass, null, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 36,
      height: 36,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 14,
      height: 14,
      borderRadius: '50%',
      background: '#4c4c4c',
      opacity: 0.4
    }
  }))), /*#__PURE__*/React.createElement(MacGlass, null, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 140,
      height: 36,
      display: 'flex',
      alignItems: 'center',
      gap: 6,
      padding: '0 12px'
    }
  }, /*#__PURE__*/React.createElement("svg", {
    width: "13",
    height: "13",
    viewBox: "0 0 13 13",
    fill: "none"
  }, /*#__PURE__*/React.createElement("circle", {
    cx: "5.5",
    cy: "5.5",
    r: "4",
    stroke: "#727272",
    strokeWidth: "1.5"
  }), /*#__PURE__*/React.createElement("path", {
    d: "M8.5 8.5l3 3",
    stroke: "#727272",
    strokeWidth: "1.5",
    strokeLinecap: "round"
  })), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: MAC_FONT,
      fontSize: 13,
      fontWeight: 500,
      color: '#727272'
    }
  }, "Search"))));
}

// ─────────────────────────────────────────────────────────────
// Sidebar — frosted glass panel floating inside the window
// ─────────────────────────────────────────────────────────────
function MacSidebarItem({
  label,
  selected = false
}) {
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 6,
      height: 24,
      padding: '4px 10px 4px 6px',
      margin: '0 10px',
      borderRadius: 8,
      position: 'relative',
      fontFamily: MAC_FONT,
      fontSize: 11,
      fontWeight: 500
    }
  }, selected && /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'absolute',
      inset: 0,
      borderRadius: 8,
      background: 'rgba(0,0,0,0.11)',
      mixBlendMode: 'multiply'
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      width: 14,
      height: 14,
      borderRadius: '50%',
      background: selected ? '#007aff' : 'rgba(0,0,0,0.4)',
      opacity: selected ? 1 : 0.5,
      flexShrink: 0,
      position: 'relative'
    }
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      color: 'rgba(0,0,0,0.85)',
      position: 'relative'
    }
  }, label));
}
function MacSidebar({
  children
}) {
  return /*#__PURE__*/React.createElement("div", {
    style: {
      width: 220,
      height: '100%',
      padding: 8,
      flexShrink: 0,
      position: 'relative',
      display: 'flex',
      flexDirection: 'column'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'absolute',
      inset: 8,
      borderRadius: 18,
      background: 'rgba(210,225,245,0.45)',
      backdropFilter: 'blur(50px) saturate(200%)',
      WebkitBackdropFilter: 'blur(50px) saturate(200%)',
      border: '0.5px solid rgba(255,255,255,0.5)',
      boxShadow: '0 8px 40px rgba(0,0,0,0.10), inset 0 1px 0 rgba(255,255,255,0.35)'
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'relative',
      zIndex: 1,
      padding: '10px 0',
      display: 'flex',
      flexDirection: 'column',
      gap: 2
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      height: 32,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-between',
      padding: '0 10px',
      marginBottom: 4
    }
  }, /*#__PURE__*/React.createElement(MacTrafficLights, null)), children));
}
function MacSidebarHeader({
  title
}) {
  return /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '14px 18px 5px',
      fontFamily: MAC_FONT,
      fontSize: 11,
      fontWeight: 700,
      color: 'rgba(0,0,0,0.5)'
    }
  }, title);
}

// ─────────────────────────────────────────────────────────────
// Window — r:26, big shadow, sidebar + toolbar + content
// ─────────────────────────────────────────────────────────────
function MacWindow({
  width = 900,
  height = 600,
  title = 'Folder',
  sidebar,
  children
}) {
  return /*#__PURE__*/React.createElement("div", {
    style: {
      width,
      height,
      borderRadius: 26,
      overflow: 'hidden',
      background: '#fff',
      boxShadow: '0 0 0 1px rgba(0,0,0,0.23), 0 16px 48px rgba(0,0,0,0.35)',
      display: 'flex',
      position: 'relative',
      fontFamily: MAC_FONT
    }
  }, /*#__PURE__*/React.createElement(MacSidebar, null, sidebar), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      display: 'flex',
      flexDirection: 'column'
    }
  }, /*#__PURE__*/React.createElement(MacToolbar, {
    title: title
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      overflow: 'auto',
      padding: '4px 8px'
    }
  }, children)));
}
Object.assign(window, {
  MacWindow,
  MacSidebar,
  MacSidebarItem,
  MacSidebarHeader,
  MacToolbar,
  MacGlass,
  MacTrafficLights
});
})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/desktop/macos-window.jsx", error: String((e && e.message) || e) }); }

// ui_kits/mobile/flows.jsx
try { (() => {
/* flows.jsx — 穿山甲 VPN mobile · auth, onboarding, redeem/buy */
const {
  useState: useStateF
} = React;

/* shared field */
function Field({
  icon,
  label,
  children
}) {
  return /*#__PURE__*/React.createElement("label", {
    style: {
      display: 'block'
    }
  }, /*#__PURE__*/React.createElement("span", {
    style: {
      display: 'block',
      fontSize: 12,
      fontWeight: 600,
      color: 'var(--fg2)',
      marginBottom: 7
    }
  }, label), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 10,
      background: 'var(--surface)',
      border: '1.5px solid var(--border-strong)',
      borderRadius: 'var(--radius-md)',
      padding: '12px 14px'
    }
  }, icon && /*#__PURE__*/React.createElement(Icon, {
    name: icon,
    size: 18,
    color: "var(--fg3)"
  }), children));
}
const inputStyle = {
  border: 'none',
  background: 'transparent',
  outline: 'none',
  flex: 1,
  fontFamily: 'var(--font-sans)',
  fontSize: 15,
  color: 'var(--fg1)',
  minWidth: 0
};

/* ───────── AUTH (login + email-code register) ───────── */
function AuthFlow({
  t,
  lang,
  onDone
}) {
  const [mode, setMode] = useStateF('login'); // login | register
  const [step, setStep] = useStateF(0); // register: 0 email+code, 1 set password
  const [email, setEmail] = useStateF('');
  const [code, setCode] = useStateF('');
  const [pw, setPw] = useStateF('');
  const [sent, setSent] = useStateF(false);
  const [totp, setTotp] = useStateF(false); // 2FA step after login (PRO)
  const [otp, setOtp] = useStateF('');
  const valid = /\S+@\S+\.\S+/.test(email);
  const tab = (id, label) => /*#__PURE__*/React.createElement("button", {
    onClick: () => {
      setMode(id);
      setStep(0);
      setSent(false);
    },
    style: {
      flex: 1,
      border: 'none',
      cursor: 'pointer',
      background: 'transparent',
      padding: '10px 0',
      fontFamily: 'var(--font-sans)',
      fontSize: 15,
      fontWeight: mode === id ? 700 : 500,
      color: mode === id ? 'var(--fg1)' : 'var(--fg3)',
      borderBottom: mode === id ? '2px solid var(--accent)' : '2px solid transparent'
    }
  }, label);
  const primaryBtn = (label, onClick, enabled) => /*#__PURE__*/React.createElement("button", {
    onClick: enabled ? onClick : undefined,
    disabled: !enabled,
    style: {
      width: '100%',
      border: 'none',
      borderRadius: 'var(--radius-full)',
      padding: '14px',
      fontFamily: 'var(--font-sans)',
      fontWeight: 700,
      fontSize: 15,
      cursor: enabled ? 'pointer' : 'not-allowed',
      background: 'var(--accent)',
      color: 'var(--fg-on-accent)',
      opacity: enabled ? 1 : 0.45,
      marginTop: 4
    }
  }, label);
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      height: '100%',
      padding: '0 28px',
      background: 'var(--bg)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      gap: 12,
      paddingTop: 18,
      paddingBottom: 28
    }
  }, /*#__PURE__*/React.createElement(Mark, {
    size: 56
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      textAlign: 'center'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 24,
      color: 'var(--fg1)'
    }
  }, t('brand')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13,
      color: 'var(--accent)',
      fontWeight: 600,
      letterSpacing: '0.04em',
      marginTop: 4
    }
  }, t('authTagline')))), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      borderBottom: '1px solid var(--border)',
      marginBottom: 22
    }
  }, tab('login', t('tabLogin')), tab('register', t('tabRegister'))), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      gap: 16,
      flex: 1
    }
  }, mode === 'login' && !totp && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Field, {
    icon: "mail",
    label: t('emailLabel')
  }, /*#__PURE__*/React.createElement("input", {
    style: inputStyle,
    value: email,
    onChange: e => setEmail(e.target.value),
    placeholder: t('emailPh')
  })), /*#__PURE__*/React.createElement(Field, {
    icon: "lock",
    label: t('pwLabel')
  }, /*#__PURE__*/React.createElement("input", {
    style: inputStyle,
    type: "password",
    value: pw,
    onChange: e => setPw(e.target.value),
    placeholder: t('pwPh')
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      textAlign: 'right',
      marginTop: -6
    }
  }, /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 13,
      color: 'var(--accent)',
      fontWeight: 600
    }
  }, t('forgotPw'))), primaryBtn(t('doLogin'), () => setTotp(true), valid && pw.length > 0)), mode === 'login' && totp && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 8
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "shield-check",
    size: 19,
    color: "var(--accent)"
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 18,
      color: 'var(--fg1)'
    }
  }, t('twoFATitle')), /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 10,
      fontWeight: 700,
      color: 'var(--accent)',
      background: 'var(--accent-subtle)',
      border: '1px solid var(--accent-border)',
      padding: '2px 8px',
      borderRadius: 999
    }
  }, "PRO")), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12.5,
      color: 'var(--fg3)',
      lineHeight: 1.6,
      marginTop: -6
    }
  }, t('twoFAHint')), /*#__PURE__*/React.createElement(Field, {
    icon: "shield-check",
    label: t('twoFATitle')
  }, /*#__PURE__*/React.createElement("input", {
    style: {
      ...inputStyle,
      fontFamily: 'var(--font-mono)',
      fontSize: 20,
      letterSpacing: '0.5em',
      textAlign: 'center'
    },
    value: otp,
    onChange: e => setOtp(e.target.value.replace(/\D/g, '').slice(0, 6)),
    placeholder: "\xB7\xB7\xB7\xB7\xB7\xB7"
  })), primaryBtn(t('twoFAConfirm'), onDone, otp.length === 6), /*#__PURE__*/React.createElement("div", {
    onClick: () => setTotp(false),
    style: {
      textAlign: 'center',
      fontSize: 12.5,
      color: 'var(--fg3)',
      cursor: 'pointer'
    }
  }, t('twoFABack'))), mode === 'register' && step === 0 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Field, {
    icon: "mail",
    label: t('emailLabel')
  }, /*#__PURE__*/React.createElement("input", {
    style: inputStyle,
    value: email,
    onChange: e => setEmail(e.target.value),
    placeholder: t('emailPh')
  }), /*#__PURE__*/React.createElement("button", {
    onClick: () => valid && setSent(true),
    style: {
      border: 'none',
      background: 'transparent',
      cursor: valid ? 'pointer' : 'default',
      color: valid ? 'var(--accent)' : 'var(--fg3)',
      fontWeight: 700,
      fontSize: 13,
      whiteSpace: 'nowrap',
      flexShrink: 0
    }
  }, sent ? t('resend') : t('sendCode'))), sent && /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      color: 'var(--success)',
      marginTop: -8,
      display: 'flex',
      alignItems: 'center',
      gap: 6
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "check-circle",
    size: 14,
    color: "var(--success)"
  }), t('codeSentTo'), " ", email), /*#__PURE__*/React.createElement(Field, {
    icon: "shield-check",
    label: t('codeLabel')
  }, /*#__PURE__*/React.createElement("input", {
    style: {
      ...inputStyle,
      fontFamily: 'var(--font-mono)',
      letterSpacing: '0.3em'
    },
    value: code,
    onChange: e => setCode(e.target.value.replace(/\D/g, '').slice(0, 6)),
    placeholder: "\xB7\xB7\xB7\xB7\xB7\xB7"
  })), primaryBtn(t('doNext'), () => setStep(1), sent && code.length === 6)), mode === 'register' && step === 1 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13,
      color: 'var(--fg2)',
      display: 'flex',
      alignItems: 'center',
      gap: 7,
      marginBottom: -4
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "check-circle",
    size: 15,
    color: "var(--success)"
  }), email), /*#__PURE__*/React.createElement(Field, {
    icon: "lock",
    label: t('pwLabel')
  }, /*#__PURE__*/React.createElement("input", {
    style: inputStyle,
    type: "password",
    value: pw,
    onChange: e => setPw(e.target.value),
    placeholder: t('setPwPh')
  })), primaryBtn(t('doCreate'), onDone, pw.length >= 6))), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11,
      color: 'var(--fg3)',
      textAlign: 'center',
      lineHeight: 1.5,
      padding: '18px 8px 24px'
    }
  }, t('tos')));
}

/* ───────── ONBOARDING (3 screens) ───────── */
function Onboarding({
  t,
  lang,
  onDone
}) {
  const [i, setI] = useStateF(0);
  const slides = [{
    icon: 'globe',
    tint: 'var(--accent)',
    bg: 'var(--accent-subtle)',
    title: t('ob1Title'),
    sub: t('ob1Sub'),
    cta: t('obNext')
  }, {
    icon: 'shield',
    tint: 'var(--accent)',
    bg: 'var(--accent-subtle)',
    title: t('ob2Title'),
    sub: t('ob2Sub'),
    cta: t('obAllow')
  }, {
    icon: 'shield-check',
    tint: 'var(--success)',
    bg: 'var(--success-subtle)',
    title: t('ob3Title'),
    sub: t('ob3Sub'),
    cta: t('obStart')
  }];
  const s = slides[i];
  const next = () => i < 2 ? setI(i + 1) : onDone();
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      height: '100%',
      padding: '0 28px',
      background: 'var(--bg)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      justifyContent: 'flex-end',
      paddingTop: 10
    }
  }, /*#__PURE__*/React.createElement("button", {
    onClick: onDone,
    style: {
      border: 'none',
      background: 'transparent',
      cursor: 'pointer',
      color: 'var(--fg3)',
      fontSize: 14,
      fontWeight: 600,
      padding: 8
    }
  }, t('obSkip'))), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      justifyContent: 'center',
      gap: 28,
      textAlign: 'center'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 120,
      height: 120,
      borderRadius: '50%',
      background: s.bg,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center'
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: s.icon,
    size: 52,
    stroke: 1.6,
    color: s.tint
  })), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 26,
      color: 'var(--fg1)'
    }
  }, s.title), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 15,
      color: 'var(--fg2)',
      lineHeight: 1.6,
      marginTop: 12,
      maxWidth: 280
    }
  }, s.sub))), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      justifyContent: 'center',
      gap: 8,
      marginBottom: 22
    }
  }, slides.map((_, k) => /*#__PURE__*/React.createElement("div", {
    key: k,
    style: {
      width: k === i ? 22 : 7,
      height: 7,
      borderRadius: 999,
      background: k === i ? 'var(--accent)' : 'var(--border-strong)',
      transition: 'all 220ms var(--ease-out)'
    }
  }))), /*#__PURE__*/React.createElement("button", {
    onClick: next,
    style: {
      width: '100%',
      border: 'none',
      borderRadius: 'var(--radius-full)',
      padding: '15px',
      fontFamily: 'var(--font-sans)',
      fontWeight: 700,
      fontSize: 15,
      cursor: 'pointer',
      background: 'var(--accent)',
      color: 'var(--fg-on-accent)',
      marginBottom: 26
    }
  }, s.cta));
}

/* ───────── REDEEM & BUY ───────── */
function RedeemScreen({
  t,
  lang,
  onBack
}) {
  const [code, setCode] = useStateF('');
  const [ok, setOk] = useStateF(false);
  const channels = [{
    icon: 'shopping-bag',
    name: t('chStore'),
    sub: t('chStoreSub'),
    accent: true
  }, {
    icon: 'credit-card',
    name: 'USDT (TRC20)',
    sub: t('chUsdtSub')
  }, {
    icon: 'send',
    name: 'Telegram',
    sub: t('chTgSub')
  }, {
    icon: 'message-circle',
    name: 'LINE',
    sub: t('chLineSub')
  }, {
    icon: 'mail',
    name: t('chEmail'),
    sub: t('chEmailSub')
  }];
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      height: '100%'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 8,
      padding: '6px 16px 14px'
    }
  }, /*#__PURE__*/React.createElement("button", {
    onClick: onBack,
    style: {
      border: 'none',
      background: 'transparent',
      cursor: 'pointer',
      padding: 6,
      display: 'flex'
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "arrow-left",
    size: 22,
    color: "var(--fg1)"
  })), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 18,
      color: 'var(--fg1)',
      whiteSpace: 'nowrap'
    }
  }, t('redeemTitle'))), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      overflow: 'auto',
      padding: '0 20px 20px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      background: 'var(--surface)',
      border: '1px solid var(--border)',
      borderRadius: 'var(--radius-lg)',
      boxShadow: 'var(--shadow-sm)',
      padding: 18,
      marginBottom: 22
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 14,
      fontWeight: 700,
      color: 'var(--fg1)',
      marginBottom: 12
    }
  }, t('redeemCodeTitle')), ok ? /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 9,
      color: 'var(--success)',
      fontWeight: 600,
      fontSize: 15,
      padding: '6px 0'
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "check-circle",
    size: 20,
    color: "var(--success)"
  }), t('redeemOk')) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 10
    }
  }, /*#__PURE__*/React.createElement("input", {
    value: code,
    onChange: e => setCode(e.target.value.toUpperCase()),
    placeholder: t('redeemPh'),
    style: {
      flex: 1,
      minWidth: 0,
      border: '1.5px solid var(--border-strong)',
      borderRadius: 'var(--radius-md)',
      padding: '12px 14px',
      fontFamily: 'var(--font-mono)',
      fontSize: 14,
      letterSpacing: '0.08em',
      color: 'var(--fg1)',
      background: 'var(--bg)',
      outline: 'none'
    }
  }), /*#__PURE__*/React.createElement("button", {
    onClick: () => code.length >= 4 && setOk(true),
    style: {
      border: 'none',
      borderRadius: 'var(--radius-md)',
      padding: '0 20px',
      background: 'var(--accent)',
      color: '#fff',
      fontWeight: 700,
      fontSize: 14,
      cursor: 'pointer',
      flexShrink: 0
    }
  }, t('redeemBtn'))))), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 14,
      fontWeight: 700,
      color: 'var(--fg1)',
      marginBottom: 6
    }
  }, t('buyTitle')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12.5,
      color: 'var(--fg3)',
      lineHeight: 1.5,
      marginBottom: 14
    }
  }, t('buySub')), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      gap: 10
    }
  }, channels.map(c => /*#__PURE__*/React.createElement("button", {
    key: c.name,
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 13,
      width: '100%',
      textAlign: 'left',
      cursor: 'pointer',
      background: c.accent ? 'var(--accent-subtle)' : 'var(--surface)',
      border: `1px solid ${c.accent ? 'var(--accent-border)' : 'var(--border)'}`,
      borderRadius: 'var(--radius-lg)',
      padding: '14px 16px',
      boxShadow: 'var(--shadow-sm)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 40,
      height: 40,
      borderRadius: 'var(--radius-md)',
      background: c.accent ? 'var(--accent)' : 'var(--bg-subtle)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: c.icon,
    size: 20,
    color: c.accent ? '#fff' : 'var(--accent)'
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 15,
      fontWeight: 600,
      color: 'var(--fg1)'
    }
  }, c.name), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12.5,
      color: 'var(--fg3)',
      fontFamily: c.icon === 'send' || c.icon === 'mail' || c.icon === 'message-circle' ? 'var(--font-mono)' : 'var(--font-sans)'
    }
  }, c.sub)), /*#__PURE__*/React.createElement(Icon, {
    name: "external-link",
    size: 17,
    color: "var(--fg3)"
  }))))));
}

/* ───────── PLANS (shown on upgrade) ───────── */
function PlansScreen({
  t,
  lang,
  onBack,
  onChoose
}) {
  const plans = [{
    id: 'free',
    name: t('free'),
    price: '¥0',
    feats: t('feFree'),
    cta: t('current'),
    variant: 'cur'
  }, {
    id: 'pro',
    name: t('proPlan'),
    price: '¥25',
    feats: t('fePro'),
    cta: t('upgrade'),
    variant: 'pro'
  }, {
    id: 'team',
    name: t('team'),
    price: '¥99',
    feats: t('feTeam'),
    cta: t('choose'),
    variant: 'plain'
  }];
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      height: '100%'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 8,
      padding: '6px 16px 14px'
    }
  }, /*#__PURE__*/React.createElement("button", {
    onClick: onBack,
    style: {
      border: 'none',
      background: 'transparent',
      cursor: 'pointer',
      padding: 6,
      display: 'flex'
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "arrow-left",
    size: 22,
    color: "var(--fg1)"
  })), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 18,
      color: 'var(--fg1)',
      whiteSpace: 'nowrap'
    }
  }, t('choosePlan'))), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      overflow: 'auto',
      padding: '4px 20px 20px',
      display: 'flex',
      flexDirection: 'column',
      gap: 14
    }
  }, plans.map(p => {
    const isPro = p.variant === 'pro';
    return /*#__PURE__*/React.createElement("div", {
      key: p.id,
      style: {
        position: 'relative',
        borderRadius: 'var(--radius-xl)',
        padding: '18px 20px',
        ...(isPro ? {
          background: 'linear-gradient(155deg,var(--clay-600),var(--clay-800))',
          color: '#fff',
          boxShadow: 'var(--shadow-md)'
        } : {
          background: 'var(--surface)',
          border: '1px solid var(--border)',
          boxShadow: 'var(--shadow-sm)'
        })
      }
    }, /*#__PURE__*/React.createElement("div", {
      style: {
        display: 'flex',
        alignItems: 'baseline',
        justifyContent: 'space-between'
      }
    }, /*#__PURE__*/React.createElement("div", {
      style: {
        fontSize: 14,
        fontWeight: 600,
        color: isPro ? '#fff' : 'var(--fg2)',
        opacity: isPro ? 0.9 : 1
      }
    }, p.name, isPro && /*#__PURE__*/React.createElement("span", {
      style: {
        marginLeft: 8,
        fontSize: 10.5,
        fontWeight: 700,
        background: '#fff',
        color: 'var(--clay-700)',
        padding: '2px 8px',
        borderRadius: 999
      }
    }, t('mostPopular'))), /*#__PURE__*/React.createElement("div", {
      style: {
        fontFamily: 'var(--font-display)',
        fontSize: 26,
        fontWeight: 700,
        color: isPro ? '#fff' : 'var(--fg1)'
      }
    }, p.price, /*#__PURE__*/React.createElement("span", {
      style: {
        fontSize: 12,
        fontWeight: 500,
        opacity: 0.7
      }
    }, t('perMonth')))), /*#__PURE__*/React.createElement("div", {
      style: {
        display: 'flex',
        flexWrap: 'wrap',
        gap: '7px 16px',
        margin: '14px 0 16px'
      }
    }, p.feats.map((f, i) => /*#__PURE__*/React.createElement("div", {
      key: i,
      style: {
        display: 'flex',
        alignItems: 'center',
        gap: 7,
        fontSize: 12.5,
        color: isPro ? 'rgba(255,255,255,.92)' : 'var(--fg2)'
      }
    }, /*#__PURE__*/React.createElement(Icon, {
      name: "check",
      size: 14,
      color: isPro ? '#fff' : 'var(--success)',
      stroke: 2.4
    }), f))), /*#__PURE__*/React.createElement("button", {
      onClick: p.variant !== 'cur' ? onChoose : undefined,
      style: {
        width: '100%',
        border: p.variant === 'cur' ? '1.5px solid var(--border-strong)' : 'none',
        cursor: p.variant === 'cur' ? 'default' : 'pointer',
        borderRadius: 'var(--radius-full)',
        padding: '12px',
        fontWeight: 700,
        fontSize: 14,
        background: isPro ? '#fff' : p.variant === 'cur' ? 'transparent' : 'var(--accent)',
        color: isPro ? 'var(--clay-700)' : p.variant === 'cur' ? 'var(--fg2)' : '#fff'
      }
    }, p.cta));
  })));
}

/* ───────── CONTACT US ───────── */
function ContactScreen({
  t,
  lang,
  onBack
}) {
  const channels = [{
    icon: 'send',
    name: 'Telegram',
    sub: '@PangolinVPN_bot',
    accent: true
  }, {
    icon: 'message-circle',
    name: 'LINE',
    sub: '@pangolinvpn'
  }, {
    icon: 'mail',
    name: t('contactEmail'),
    sub: 'support@pangolin.vpn'
  }, {
    icon: 'shopping-bag',
    name: t('contactStore'),
    sub: 'shop.pangolin.vpn'
  }];
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      height: '100%'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 8,
      padding: '6px 16px 14px'
    }
  }, /*#__PURE__*/React.createElement("button", {
    onClick: onBack,
    style: {
      border: 'none',
      background: 'transparent',
      cursor: 'pointer',
      padding: 6,
      display: 'flex'
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "arrow-left",
    size: 22,
    color: "var(--fg1)"
  })), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 18,
      color: 'var(--fg1)',
      whiteSpace: 'nowrap'
    }
  }, t('contactTitle'))), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      overflow: 'auto',
      padding: '0 20px 20px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13,
      color: 'var(--fg2)',
      lineHeight: 1.6,
      marginBottom: 16
    }
  }, t('contactIntro')), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      gap: 10,
      marginBottom: 18
    }
  }, channels.map(c => /*#__PURE__*/React.createElement("button", {
    key: c.name,
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 13,
      width: '100%',
      textAlign: 'left',
      cursor: 'pointer',
      background: c.accent ? 'var(--accent-subtle)' : 'var(--surface)',
      border: `1px solid ${c.accent ? 'var(--accent-border)' : 'var(--border)'}`,
      borderRadius: 'var(--radius-lg)',
      padding: '14px 16px',
      boxShadow: 'var(--shadow-sm)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 40,
      height: 40,
      borderRadius: 'var(--radius-md)',
      background: c.accent ? 'var(--accent)' : 'var(--bg-subtle)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: c.icon,
    size: 20,
    color: c.accent ? '#fff' : 'var(--accent)'
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      minWidth: 0
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 15,
      fontWeight: 600,
      color: 'var(--fg1)'
    }
  }, c.name), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12.5,
      color: 'var(--fg3)',
      fontFamily: 'var(--font-mono)'
    }
  }, c.sub)), /*#__PURE__*/React.createElement(Icon, {
    name: "external-link",
    size: 17,
    color: "var(--fg3)"
  })))), /*#__PURE__*/React.createElement("div", {
    style: {
      background: 'var(--surface)',
      border: '1px solid var(--border)',
      borderRadius: 'var(--radius-lg)',
      boxShadow: 'var(--shadow-sm)',
      padding: '14px 16px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      fontWeight: 600,
      color: 'var(--fg3)'
    }
  }, t('contactHoursTitle')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 14,
      fontWeight: 600,
      color: 'var(--fg1)',
      marginTop: 5,
      fontFamily: 'var(--font-mono)'
    }
  }, t('contactHours')))));
}
Object.assign(window, {
  AuthFlow,
  Onboarding,
  RedeemScreen,
  PlansScreen,
  ContactScreen
});
})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/mobile/flows.jsx", error: String((e && e.message) || e) }); }

// ui_kits/mobile/ios-frame.jsx
try { (() => {
/* BEGIN USAGE */
// iOS.jsx — Simplified iOS 26 (Liquid Glass) device frame
// Based on the iOS 26 UI Kit + Figma status bar spec. No assets, no deps.
// Exports (to window): IOSDevice, IOSStatusBar, IOSNavBar, IOSGlassPill, IOSList, IOSListRow, IOSKeyboard
//
// Usage — wrap your screen content in <IOSDevice> to get the bezel, status bar
// and home indicator (props: title, dark, keyboard):
//
//   <IOSDevice title="Settings">
//     ...your screen content...
//   </IOSDevice>
//   <IOSDevice dark title="Search" keyboard>…</IOSDevice>
/* END USAGE */

// ─────────────────────────────────────────────────────────────
// Status bar
// ─────────────────────────────────────────────────────────────
function IOSStatusBar({
  dark = false,
  time = '9:41'
}) {
  const c = dark ? '#fff' : '#000';
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 154,
      alignItems: 'center',
      justifyContent: 'center',
      padding: '21px 24px 19px',
      boxSizing: 'border-box',
      position: 'relative',
      zIndex: 20,
      width: '100%'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      height: 22,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      paddingTop: 1.5
    }
  }, /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: '-apple-system, "SF Pro", system-ui',
      fontWeight: 590,
      fontSize: 17,
      lineHeight: '22px',
      color: c
    }
  }, time)), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      height: 22,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      gap: 7,
      paddingTop: 1,
      paddingRight: 1
    }
  }, /*#__PURE__*/React.createElement("svg", {
    width: "19",
    height: "12",
    viewBox: "0 0 19 12"
  }, /*#__PURE__*/React.createElement("rect", {
    x: "0",
    y: "7.5",
    width: "3.2",
    height: "4.5",
    rx: "0.7",
    fill: c
  }), /*#__PURE__*/React.createElement("rect", {
    x: "4.8",
    y: "5",
    width: "3.2",
    height: "7",
    rx: "0.7",
    fill: c
  }), /*#__PURE__*/React.createElement("rect", {
    x: "9.6",
    y: "2.5",
    width: "3.2",
    height: "9.5",
    rx: "0.7",
    fill: c
  }), /*#__PURE__*/React.createElement("rect", {
    x: "14.4",
    y: "0",
    width: "3.2",
    height: "12",
    rx: "0.7",
    fill: c
  })), /*#__PURE__*/React.createElement("svg", {
    width: "17",
    height: "12",
    viewBox: "0 0 17 12"
  }, /*#__PURE__*/React.createElement("path", {
    d: "M8.5 3.2C10.8 3.2 12.9 4.1 14.4 5.6L15.5 4.5C13.7 2.7 11.2 1.5 8.5 1.5C5.8 1.5 3.3 2.7 1.5 4.5L2.6 5.6C4.1 4.1 6.2 3.2 8.5 3.2Z",
    fill: c
  }), /*#__PURE__*/React.createElement("path", {
    d: "M8.5 6.8C9.9 6.8 11.1 7.3 12 8.2L13.1 7.1C11.8 5.9 10.2 5.1 8.5 5.1C6.8 5.1 5.2 5.9 3.9 7.1L5 8.2C5.9 7.3 7.1 6.8 8.5 6.8Z",
    fill: c
  }), /*#__PURE__*/React.createElement("circle", {
    cx: "8.5",
    cy: "10.5",
    r: "1.5",
    fill: c
  })), /*#__PURE__*/React.createElement("svg", {
    width: "27",
    height: "13",
    viewBox: "0 0 27 13"
  }, /*#__PURE__*/React.createElement("rect", {
    x: "0.5",
    y: "0.5",
    width: "23",
    height: "12",
    rx: "3.5",
    stroke: c,
    strokeOpacity: "0.35",
    fill: "none"
  }), /*#__PURE__*/React.createElement("rect", {
    x: "2",
    y: "2",
    width: "20",
    height: "9",
    rx: "2",
    fill: c
  }), /*#__PURE__*/React.createElement("path", {
    d: "M25 4.5V8.5C25.8 8.2 26.5 7.2 26.5 6.5C26.5 5.8 25.8 4.8 25 4.5Z",
    fill: c,
    fillOpacity: "0.4"
  }))));
}

// ─────────────────────────────────────────────────────────────
// Liquid glass pill — blur + tint + shine
// ─────────────────────────────────────────────────────────────
function IOSGlassPill({
  children,
  dark = false,
  style = {}
}) {
  return /*#__PURE__*/React.createElement("div", {
    style: {
      height: 44,
      minWidth: 44,
      borderRadius: 9999,
      position: 'relative',
      overflow: 'hidden',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      boxShadow: dark ? '0 2px 6px rgba(0,0,0,0.35), 0 6px 16px rgba(0,0,0,0.2)' : '0 1px 3px rgba(0,0,0,0.07), 0 3px 10px rgba(0,0,0,0.06)',
      ...style
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'absolute',
      inset: 0,
      borderRadius: 9999,
      backdropFilter: 'blur(12px) saturate(180%)',
      WebkitBackdropFilter: 'blur(12px) saturate(180%)',
      background: dark ? 'rgba(120,120,128,0.28)' : 'rgba(255,255,255,0.5)'
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'absolute',
      inset: 0,
      borderRadius: 9999,
      boxShadow: dark ? 'inset 1.5px 1.5px 1px rgba(255,255,255,0.15), inset -1px -1px 1px rgba(255,255,255,0.08)' : 'inset 1.5px 1.5px 1px rgba(255,255,255,0.7), inset -1px -1px 1px rgba(255,255,255,0.4)',
      border: dark ? '0.5px solid rgba(255,255,255,0.15)' : '0.5px solid rgba(0,0,0,0.06)'
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'relative',
      zIndex: 1,
      display: 'flex',
      alignItems: 'center',
      padding: '0 4px'
    }
  }, children));
}

// ─────────────────────────────────────────────────────────────
// Navigation bar — glass pills + large title
// ─────────────────────────────────────────────────────────────
function IOSNavBar({
  title = 'Title',
  dark = false,
  trailingIcon = true
}) {
  const muted = dark ? 'rgba(255,255,255,0.6)' : '#404040';
  const text = dark ? '#fff' : '#000';
  const pillIcon = content => /*#__PURE__*/React.createElement(IOSGlassPill, {
    dark: dark
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 36,
      height: 36,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center'
    }
  }, content));
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      gap: 10,
      paddingTop: 62,
      paddingBottom: 10,
      position: 'relative',
      zIndex: 5
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-between',
      padding: '0 16px'
    }
  }, pillIcon(/*#__PURE__*/React.createElement("svg", {
    width: "12",
    height: "20",
    viewBox: "0 0 12 20",
    fill: "none",
    style: {
      marginLeft: -1
    }
  }, /*#__PURE__*/React.createElement("path", {
    d: "M10 2L2 10l8 8",
    stroke: muted,
    strokeWidth: "2.5",
    strokeLinecap: "round",
    strokeLinejoin: "round"
  }))), trailingIcon && pillIcon(/*#__PURE__*/React.createElement("svg", {
    width: "22",
    height: "6",
    viewBox: "0 0 22 6"
  }, /*#__PURE__*/React.createElement("circle", {
    cx: "3",
    cy: "3",
    r: "2.5",
    fill: muted
  }), /*#__PURE__*/React.createElement("circle", {
    cx: "11",
    cy: "3",
    r: "2.5",
    fill: muted
  }), /*#__PURE__*/React.createElement("circle", {
    cx: "19",
    cy: "3",
    r: "2.5",
    fill: muted
  })))), /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '0 16px',
      fontFamily: '-apple-system, system-ui',
      fontSize: 34,
      fontWeight: 700,
      lineHeight: '41px',
      color: text,
      letterSpacing: 0.4
    }
  }, title));
}

// ─────────────────────────────────────────────────────────────
// Grouped list (inset card, r:26) + row (52px)
// ─────────────────────────────────────────────────────────────
function IOSListRow({
  title,
  detail,
  icon,
  chevron = true,
  isLast = false,
  dark = false
}) {
  const text = dark ? '#fff' : '#000';
  const sec = dark ? 'rgba(235,235,245,0.6)' : 'rgba(60,60,67,0.6)';
  const ter = dark ? 'rgba(235,235,245,0.3)' : 'rgba(60,60,67,0.3)';
  const sep = dark ? 'rgba(84,84,88,0.65)' : 'rgba(60,60,67,0.12)';
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      minHeight: 52,
      padding: '0 16px',
      position: 'relative',
      fontFamily: '-apple-system, system-ui',
      fontSize: 17,
      letterSpacing: -0.43
    }
  }, icon && /*#__PURE__*/React.createElement("div", {
    style: {
      width: 30,
      height: 30,
      borderRadius: 7,
      background: icon,
      marginRight: 12,
      flexShrink: 0
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      color: text
    }
  }, title), detail && /*#__PURE__*/React.createElement("span", {
    style: {
      color: sec,
      marginRight: 6
    }
  }, detail), chevron && /*#__PURE__*/React.createElement("svg", {
    width: "8",
    height: "14",
    viewBox: "0 0 8 14",
    style: {
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement("path", {
    d: "M1 1l6 6-6 6",
    stroke: ter,
    strokeWidth: "2",
    fill: "none",
    strokeLinecap: "round",
    strokeLinejoin: "round"
  })), !isLast && /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'absolute',
      bottom: 0,
      right: 0,
      left: icon ? 58 : 16,
      height: 0.5,
      background: sep
    }
  }));
}
function IOSList({
  header,
  children,
  dark = false
}) {
  const hc = dark ? 'rgba(235,235,245,0.6)' : 'rgba(60,60,67,0.6)';
  const bg = dark ? '#1C1C1E' : '#fff';
  return /*#__PURE__*/React.createElement("div", null, header && /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: '-apple-system, system-ui',
      fontSize: 13,
      color: hc,
      textTransform: 'uppercase',
      padding: '8px 36px 6px',
      letterSpacing: -0.08
    }
  }, header), /*#__PURE__*/React.createElement("div", {
    style: {
      background: bg,
      borderRadius: 26,
      margin: '0 16px',
      overflow: 'hidden'
    }
  }, children));
}

// ─────────────────────────────────────────────────────────────
// Device frame
// ─────────────────────────────────────────────────────────────
function IOSDevice({
  children,
  width = 402,
  height = 874,
  dark = false,
  title,
  keyboard = false
}) {
  return /*#__PURE__*/React.createElement("div", {
    style: {
      width,
      height,
      borderRadius: 48,
      overflow: 'hidden',
      position: 'relative',
      background: dark ? '#000' : '#F2F2F7',
      boxShadow: '0 40px 80px rgba(0,0,0,0.18), 0 0 0 1px rgba(0,0,0,0.12)',
      fontFamily: '-apple-system, system-ui, sans-serif',
      WebkitFontSmoothing: 'antialiased'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'absolute',
      top: 11,
      left: '50%',
      transform: 'translateX(-50%)',
      width: 126,
      height: 37,
      borderRadius: 24,
      background: '#000',
      zIndex: 50
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'absolute',
      top: 0,
      left: 0,
      right: 0,
      zIndex: 10
    }
  }, /*#__PURE__*/React.createElement(IOSStatusBar, {
    dark: dark
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      height: '100%',
      display: 'flex',
      flexDirection: 'column'
    }
  }, title !== undefined && /*#__PURE__*/React.createElement(IOSNavBar, {
    title: title,
    dark: dark
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      overflow: 'auto'
    }
  }, children), keyboard && /*#__PURE__*/React.createElement(IOSKeyboard, {
    dark: dark
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'absolute',
      bottom: 0,
      left: 0,
      right: 0,
      zIndex: 60,
      height: 34,
      display: 'flex',
      justifyContent: 'center',
      alignItems: 'flex-end',
      paddingBottom: 8,
      pointerEvents: 'none'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 139,
      height: 5,
      borderRadius: 100,
      background: dark ? 'rgba(255,255,255,0.7)' : 'rgba(0,0,0,0.25)'
    }
  })));
}

// ─────────────────────────────────────────────────────────────
// Keyboard — iOS 26 liquid glass
// ─────────────────────────────────────────────────────────────
function IOSKeyboard({
  dark = false
}) {
  const glyph = dark ? 'rgba(255,255,255,0.7)' : '#595959';
  const sugg = dark ? 'rgba(255,255,255,0.6)' : '#333';
  const keyBg = dark ? 'rgba(255,255,255,0.22)' : 'rgba(255,255,255,0.85)';

  // special-key icons
  const icons = {
    shift: /*#__PURE__*/React.createElement("svg", {
      width: "19",
      height: "17",
      viewBox: "0 0 19 17"
    }, /*#__PURE__*/React.createElement("path", {
      d: "M9.5 1L1 9.5h4.5V16h8V9.5H18L9.5 1z",
      fill: glyph
    })),
    del: /*#__PURE__*/React.createElement("svg", {
      width: "23",
      height: "17",
      viewBox: "0 0 23 17"
    }, /*#__PURE__*/React.createElement("path", {
      d: "M7 1h13a2 2 0 012 2v11a2 2 0 01-2 2H7l-6-7.5L7 1z",
      fill: "none",
      stroke: glyph,
      strokeWidth: "1.6",
      strokeLinejoin: "round"
    }), /*#__PURE__*/React.createElement("path", {
      d: "M10 5l7 7M17 5l-7 7",
      stroke: glyph,
      strokeWidth: "1.6",
      strokeLinecap: "round"
    })),
    ret: /*#__PURE__*/React.createElement("svg", {
      width: "20",
      height: "14",
      viewBox: "0 0 20 14"
    }, /*#__PURE__*/React.createElement("path", {
      d: "M18 1v6H4m0 0l4-4M4 7l4 4",
      fill: "none",
      stroke: "#fff",
      strokeWidth: "1.8",
      strokeLinecap: "round",
      strokeLinejoin: "round"
    }))
  };
  const key = (content, {
    w,
    flex,
    ret,
    fs = 25,
    k
  } = {}) => /*#__PURE__*/React.createElement("div", {
    key: k,
    style: {
      height: 42,
      borderRadius: 8.5,
      flex: flex ? 1 : undefined,
      width: w,
      minWidth: 0,
      background: ret ? '#08f' : keyBg,
      boxShadow: '0 1px 0 rgba(0,0,0,0.075)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      fontFamily: '-apple-system, "SF Compact", system-ui',
      fontSize: fs,
      fontWeight: 458,
      color: ret ? '#fff' : glyph
    }
  }, content);
  const row = (keys, pad = 0) => /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 6.5,
      justifyContent: 'center',
      padding: `0 ${pad}px`
    }
  }, keys.map(l => key(l, {
    flex: true,
    k: l
  })));
  return /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'relative',
      zIndex: 15,
      borderRadius: 27,
      overflow: 'hidden',
      padding: '11px 0 2px',
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      boxShadow: dark ? '0 -2px 20px rgba(0,0,0,0.09)' : '0 -1px 6px rgba(0,0,0,0.018), 0 -3px 20px rgba(0,0,0,0.012)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'absolute',
      inset: 0,
      borderRadius: 27,
      backdropFilter: 'blur(12px) saturate(180%)',
      WebkitBackdropFilter: 'blur(12px) saturate(180%)',
      background: dark ? 'rgba(120,120,128,0.14)' : 'rgba(255,255,255,0.25)'
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'absolute',
      inset: 0,
      borderRadius: 27,
      boxShadow: dark ? 'inset 1.5px 1.5px 1px rgba(255,255,255,0.15)' : 'inset 1.5px 1.5px 1px rgba(255,255,255,0.7), inset -1px -1px 1px rgba(255,255,255,0.4)',
      border: dark ? '0.5px solid rgba(255,255,255,0.15)' : '0.5px solid rgba(0,0,0,0.06)',
      pointerEvents: 'none'
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 20,
      alignItems: 'center',
      padding: '8px 22px 13px',
      width: '100%',
      boxSizing: 'border-box',
      position: 'relative'
    }
  }, ['"The"', 'the', 'to'].map((w, i) => /*#__PURE__*/React.createElement(React.Fragment, {
    key: i
  }, i > 0 && /*#__PURE__*/React.createElement("div", {
    style: {
      width: 1,
      height: 25,
      background: '#ccc',
      opacity: 0.3
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      textAlign: 'center',
      fontFamily: '-apple-system, system-ui',
      fontSize: 17,
      color: sugg,
      letterSpacing: -0.43,
      lineHeight: '22px'
    }
  }, w)))), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      gap: 13,
      padding: '0 6.5px',
      width: '100%',
      boxSizing: 'border-box',
      position: 'relative'
    }
  }, row(['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p']), row(['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'], 20), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 14.25,
      alignItems: 'center'
    }
  }, key(icons.shift, {
    w: 45,
    k: 'shift'
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 6.5,
      flex: 1
    }
  }, ['z', 'x', 'c', 'v', 'b', 'n', 'm'].map(l => key(l, {
    flex: true,
    k: l
  }))), key(icons.del, {
    w: 45,
    k: 'del'
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 6,
      alignItems: 'center'
    }
  }, key('ABC', {
    w: 92.25,
    fs: 18,
    k: 'abc'
  }), key('', {
    flex: true,
    k: 'space'
  }), key(icons.ret, {
    w: 92.25,
    ret: true,
    k: 'ret'
  }))), /*#__PURE__*/React.createElement("div", {
    style: {
      height: 56,
      width: '100%',
      position: 'relative'
    }
  }));
}
Object.assign(window, {
  IOSDevice,
  IOSStatusBar,
  IOSNavBar,
  IOSGlassPill,
  IOSList,
  IOSListRow,
  IOSKeyboard
});
})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/mobile/ios-frame.jsx", error: String((e && e.message) || e) }); }

// ui_kits/mobile/parts.jsx
try { (() => {
/* parts.jsx — 穿山甲 VPN mobile · shared atoms
   Icon uses inline Lucide path data (lucide.dev) for reliability in React. */

const LUCIDE = {
  power: '<path d="M12 2v10"/><path d="M18.36 6.64a9 9 0 1 1-12.73 0"/>',
  'shield-check': '<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/>',
  globe: '<circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/>',
  settings: '<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/>',
  'chevron-right': '<path d="m9 18 6-6-6-6"/>',
  'chevron-down': '<path d="m6 9 6 6 6-6"/>',
  check: '<path d="M20 6 9 17l-5-5"/>',
  zap: '<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>',
  'loader-circle': '<path d="M21 12a9 9 0 1 1-6.219-8.56"/>',
  user: '<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',
  x: '<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',
  crown: '<path d="M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z"/><path d="M5 21h14"/>',
  'map-pin': '<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/>',
  'arrow-down': '<path d="M12 5v14"/><path d="m19 12-7 7-7-7"/>',
  'arrow-up': '<path d="M12 19V5"/><path d="m5 12 7-7 7 7"/>',
  search: '<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>',
  moon: '<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>',
  sun: '<circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/>',
  shield: '<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/>',
  'refresh-cw': '<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M3 21v-5h5"/>',
  chart: '<line x1="18" x2="18" y1="20" y2="10"/><line x1="12" x2="12" y1="20" y2="4"/><line x1="6" x2="6" y1="20" y2="14"/>',
  wifi: '<path d="M12 20h.01"/><path d="M2 8.82a15 15 0 0 1 20 0"/><path d="M5 12.859a10 10 0 0 1 14 0"/><path d="M8.5 16.429a5 5 0 0 1 7 0"/>',
  mail: '<rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>',
  lock: '<rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>',
  'arrow-left': '<path d="m12 19-7-7 7-7"/><path d="M19 12H5"/>',
  'shopping-bag': '<path d="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z"/><path d="M3 6h18"/><path d="M16 10a4 4 0 0 1-8 0"/>',
  send: '<path d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"/><path d="m21.854 2.147-10.94 10.939"/>',
  'message-circle': '<path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/>',
  'external-link': '<path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>',
  'check-circle': '<path d="M21.801 10A10 10 0 1 1 17 3.335"/><path d="m9 11 3 3L22 4"/>',
  'log-out': '<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/>',
  compass: '<path d="m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"/><circle cx="12" cy="12" r="10"/>',
  laptop: '<path d="M18 5a2 2 0 0 1 2 2v8.526a2 2 0 0 0 .212.894l1.575 3.15A.5.5 0 0 1 21.342 21H2.658a.5.5 0 0 1-.445-.724l1.575-3.15A2 2 0 0 0 4 16.526V7a2 2 0 0 1 2-2z"/><path d="M20.054 15.987H3.946"/>',
  smartphone: '<rect width="14" height="20" x="5" y="2" rx="2" ry="2"/><path d="M12 18h.01"/>',
  'monitor-smartphone': '<path d="M18 8V5a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h8"/><path d="M10 19v-3.96 3.15"/><path d="M7 19h5"/><rect width="6" height="10" x="16" y="12" rx="2"/>',
  ticket: '<path d="M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z"/><path d="M13 5v2"/><path d="M13 17v2"/><path d="M13 11v2"/>',
  clock: '<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>',
  'credit-card': '<rect width="20" height="14" x="2" y="5" rx="2"/><line x1="2" x2="22" y1="10" y2="10"/>',
  'play-circle': '<circle cx="12" cy="12" r="10"/><polygon points="10 8 16 12 10 16 10 8"/>'
};
function Icon({
  name,
  size = 24,
  stroke = 2,
  color = 'currentColor',
  style = {}
}) {
  return /*#__PURE__*/React.createElement("svg", {
    width: size,
    height: size,
    viewBox: "0 0 24 24",
    fill: "none",
    stroke: color,
    strokeWidth: stroke,
    strokeLinecap: "round",
    strokeLinejoin: "round",
    style: {
      display: 'block',
      flexShrink: 0,
      ...style
    },
    dangerouslySetInnerHTML: {
      __html: LUCIDE[name] || ''
    }
  });
}

/* Brand mark — walking pangolin (matches app icon), facing right */
function Mark({
  size = 40,
  color = 'var(--accent)'
}) {
  return /*#__PURE__*/React.createElement("svg", {
    width: size,
    height: size,
    viewBox: "0 0 96 96",
    fill: "none",
    style: {
      display: 'block'
    }
  }, /*#__PURE__*/React.createElement("g", {
    transform: "translate(96,0) scale(-1,1)"
  }, /*#__PURE__*/React.createElement("path", {
    d: "M16 59 Q17 51 26 50 Q34 31 45 30 Q55 30 62 37 Q69 41 75 45 Q85 49 89 44 Q92 50 84 52 Q75 53 67 53 Q66 62 60 62 L56 62 Q54 55 49 55 Q47 62 37 62 L33 62 Q31 56 26 56 Q20 59 16 59 Z",
    fill: color
  }), /*#__PURE__*/React.createElement("g", {
    stroke: "#fff",
    strokeWidth: "2.4",
    strokeLinecap: "round",
    strokeLinejoin: "round",
    fill: "none",
    opacity: "0.5"
  }, /*#__PURE__*/React.createElement("path", {
    d: "M26 50 Q34 43 42 50"
  }), /*#__PURE__*/React.createElement("path", {
    d: "M36 48 Q44 41 52 48"
  }), /*#__PURE__*/React.createElement("path", {
    d: "M46 48 Q54 41 62 49"
  })), /*#__PURE__*/React.createElement("circle", {
    cx: "23",
    cy: "55",
    r: "2.2",
    fill: "#fff",
    opacity: "0.85"
  })));
}

/* Country code tile */
function CC({
  code,
  active
}) {
  return /*#__PURE__*/React.createElement("div", {
    style: {
      width: 38,
      height: 38,
      borderRadius: 'var(--radius-md)',
      flexShrink: 0,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      fontFamily: 'var(--font-mono)',
      fontSize: 12,
      fontWeight: 600,
      background: active ? 'var(--accent)' : 'var(--bg-subtle)',
      color: active ? '#fff' : 'var(--fg2)'
    }
  }, code);
}

/* Signal bars from ping */
function Signal({
  ping
}) {
  const lvl = ping < 40 ? 3 : ping < 90 ? 2 : 1;
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 2,
      alignItems: 'flex-end',
      height: 14
    }
  }, [5, 9, 14].map((h, i) => /*#__PURE__*/React.createElement("div", {
    key: i,
    style: {
      width: 3,
      height: h,
      borderRadius: 1,
      background: i < lvl ? 'var(--success)' : 'var(--border-strong)'
    }
  })));
}

/* Pill button */
function Pill({
  children,
  variant = 'primary',
  onClick,
  style = {},
  disabled
}) {
  const v = {
    primary: {
      background: 'var(--accent)',
      color: 'var(--fg-on-accent)'
    },
    secondary: {
      background: 'var(--surface)',
      color: 'var(--fg1)',
      border: '1.5px solid var(--border-strong)'
    },
    ghost: {
      background: 'transparent',
      color: 'var(--accent)'
    },
    danger: {
      background: 'var(--danger-subtle)',
      color: 'var(--danger)'
    }
  }[variant];
  return /*#__PURE__*/React.createElement("button", {
    onClick: onClick,
    disabled: disabled,
    style: {
      display: 'inline-flex',
      alignItems: 'center',
      justifyContent: 'center',
      gap: 8,
      fontFamily: 'var(--font-sans)',
      fontWeight: 600,
      fontSize: 15,
      border: 'none',
      borderRadius: 'var(--radius-full)',
      padding: '13px 22px',
      cursor: disabled ? 'not-allowed' : 'pointer',
      transition: 'all 140ms var(--ease-out)',
      opacity: disabled ? 0.5 : 1,
      ...v,
      ...style
    }
  }, children);
}

/* ───────── i18n ─────────
   Real product shows ONE language at a time (toggle in settings).
   Bilingual specimens only live in the design-system preview cards. */
const STRINGS = {
  brand: {
    zh: '穿山甲',
    en: 'Pangolin'
  },
  online: {
    zh: '● 在线',
    en: '● Online'
  },
  offline: {
    zh: '○ 离线',
    en: '○ Offline'
  },
  capOff: {
    zh: '未连接 · 轻点连接',
    en: 'Tap to connect'
  },
  capConnecting: {
    zh: '连接中…',
    en: 'Connecting…'
  },
  capOn: {
    zh: '已连接 · 网络已加密',
    en: 'Connected · Encrypted'
  },
  centerOff: {
    zh: 'TAP',
    en: 'TAP'
  },
  download: {
    zh: '下载',
    en: 'Down'
  },
  upload: {
    zh: '上传',
    en: 'Up'
  },
  latency: {
    zh: '延迟',
    en: 'Ping'
  },
  chooseNode: {
    zh: '选择节点',
    en: 'Choose server'
  },
  search: {
    zh: '搜索国家 / 城市',
    en: 'Search country / city'
  },
  tabConnect: {
    zh: '连接',
    en: 'Connect'
  },
  tabServers: {
    zh: '节点',
    en: 'Servers'
  },
  tabStats: {
    zh: '统计',
    en: 'Stats'
  },
  tabMe: {
    zh: '我的',
    en: 'Account'
  },
  connectNow: {
    zh: '点击连接',
    en: 'CONNECT'
  },
  secure: {
    zh: '已加密',
    en: 'SECURE'
  },
  statsTitle: {
    zh: '使用统计',
    en: 'Statistics'
  },
  trafficMonth: {
    zh: '本月流量',
    en: 'Traffic'
  },
  avgPing: {
    zh: '平均延迟',
    en: 'Avg ping'
  },
  durMonth: {
    zh: '本月时长',
    en: 'Time'
  },
  weekTraffic: {
    zh: '本周流量 (GB)',
    en: 'This week (GB)'
  },
  days7: {
    zh: ['一', '二', '三', '四', '五', '六', '日'],
    en: ['M', 'T', 'W', 'T', 'F', 'S', 'S']
  },
  proMember: {
    zh: 'PRO 会员',
    en: 'PRO member'
  },
  expires: {
    zh: '有效期至',
    en: 'Expires'
  },
  usage: {
    zh: '本月用量',
    en: 'Used this month'
  },
  smartRoute: {
    zh: '智能分流',
    en: 'Smart routing'
  },
  smartRouteSub: {
    zh: '海外应用加速,本地直连',
    en: 'Accelerate overseas apps, keep local direct'
  },
  killSwitch: {
    zh: 'Kill Switch',
    en: 'Kill Switch'
  },
  killSwitchSub: {
    zh: '断线时阻断网络,防止泄露',
    en: 'Block traffic if the VPN drops'
  },
  darkAppearance: {
    zh: '深色外观',
    en: 'Dark appearance'
  },
  stateOn: {
    zh: '已开启',
    en: 'On'
  },
  followLight: {
    zh: '跟随浅色',
    en: 'Off'
  },
  protocol: {
    zh: '协议',
    en: 'Protocol'
  },
  checkUpdate: {
    zh: '检查更新',
    en: 'Check for updates'
  },
  language: {
    zh: '语言',
    en: 'Language'
  },
  /* 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'
  },
  stepEmail: {
    zh: '验证邮箱',
    en: 'Verify email'
  },
  stepPw: {
    zh: '设置密码',
    en: 'Set password'
  },
  /* 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: 'iOS 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.'
  },
  /* 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: 'Activate'
  },
  redeemOk: {
    zh: '激活成功 · PRO 已开通',
    en: 'Activated · PRO unlocked'
  },
  buyTitle: {
    zh: '购买渠道',
    en: 'Where to buy'
  },
  buySub: {
    zh: 'App 内不支持直接支付。请通过以下渠道获取激活码:',
    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'
  },
  chTgSub: {
    zh: '@PangolinVPN_bot',
    en: '@PangolinVPN_bot'
  },
  chLineSub: {
    zh: '@pangolinvpn',
    en: '@pangolinvpn'
  },
  chEmail: {
    zh: '邮箱',
    en: 'Email'
  },
  chEmailSub: {
    zh: 'buy@pangolin.vpn',
    en: 'buy@pangolin.vpn'
  },
  back: {
    zh: '返回',
    en: 'Back'
  },
  replayAuth: {
    zh: '查看登录 / 注册流程',
    en: 'View login / sign-up'
  },
  twoFA: {
    zh: '双重认证',
    en: 'Two-factor auth'
  },
  twoFASub: {
    zh: 'PRO 专享 · 登录需身份验证器动态码',
    en: 'PRO only · TOTP code at login'
  },
  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'
  },
  ucEntry: {
    zh: 'Web 用户中心',
    en: 'Web account center'
  },
  ucEntrySub: {
    zh: '订阅导入 · 邀请返利',
    en: 'Subscription import · referral'
  },
  replayAuthSub: {
    zh: '演示用 · 退出到登录页',
    en: 'Demo · back to login'
  },
  replayOnboarding: {
    zh: '查看首次引导',
    en: 'View onboarding'
  },
  replayOnboardingSub: {
    zh: '演示用 · 重看 3 屏引导',
    en: 'Demo · replay the 3 intro screens'
  },
  /* account management (integrated) */
  meTitle: {
    zh: '我的',
    en: 'Account'
  },
  curPlan: {
    zh: '当前套餐',
    en: 'Current plan'
  },
  expires: {
    zh: '有效期至',
    en: 'Expires'
  },
  upgradeBtn: {
    zh: '续费 / 升级',
    en: 'Renew / Upgrade'
  },
  accInfoTitle: {
    zh: '账户信息',
    en: 'Account info'
  },
  accEmail: {
    zh: '邮箱',
    en: 'Email'
  },
  accPassword: {
    zh: '密码',
    en: 'Password'
  },
  accChange: {
    zh: '修改',
    en: 'Change'
  },
  accSignOut: {
    zh: '退出登录',
    en: 'Sign out'
  },
  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 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']
  },
  /* contact */
  contactEntry: {
    zh: '联系我们',
    en: 'Contact us'
  },
  contactTitle: {
    zh: '联系我们',
    en: 'Contact us'
  },
  contactIntro: {
    zh: '遇到问题?通过以下任一渠道联系我们,通常数分钟内回复。',
    en: 'Need help? Reach us via any channel below — usually replies in minutes.'
  },
  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)'
  },
  devicesCount: {
    zh: '台设备',
    en: 'devices'
  },
  /* smart select + quota (口径见 CLAUDE.md §7) */
  smartSelect: {
    zh: '智能选择',
    en: 'Smart select'
  },
  smartSub: {
    zh: '根据当前网络环境,自动选择最优节点',
    en: 'Picks the best node for your network'
  },
  recommended: {
    zh: '推荐',
    en: 'Recommended'
  },
  quotaToday: {
    zh: '今日剩余',
    en: 'Left today'
  },
  minutes: {
    zh: '分钟',
    en: 'min'
  },
  quotaFree: {
    zh: '免费版 · 每日 10 分钟',
    en: 'Free · 10 min/day'
  },
  quotaTrial: {
    zh: '体验期 · 7 天免费使用',
    en: 'Trial · 7 days free'
  },
  watchAd: {
    zh: '看广告开始使用',
    en: 'Watch ad to start'
  },
  adUnlocked: {
    zh: '已解锁 · 今日可用',
    en: 'Unlocked for today'
  },
  freePlanName: {
    zh: '免费版',
    en: 'Free'
  },
  upgradeNow: {
    zh: '升级 PRO',
    en: 'Go PRO'
  },
  freeDemo: {
    zh: '演示:免费版视角',
    en: 'Demo: free-tier view'
  },
  freeDemoSub: {
    zh: '切换连接页的额度展示与套餐横幅',
    en: 'Toggles quota UI & plan banner'
  }
};
function makeT(lang) {
  return k => STRINGS[k] && STRINGS[k][lang] || k;
}
/* localized server label */
function srvName(s, lang) {
  return lang === 'zh' ? s.name : s.en;
}
function srvSub(s, lang) {
  const tag = s.tags && s.tags[0];
  if (lang === 'zh') return tag ? tag : s.en;
  return tag === '流媒体优化' ? 'Streaming' : tag === 'P2P' ? 'P2P' : s.name;
}
Object.assign(window, {
  Icon,
  Mark,
  CC,
  Signal,
  Pill,
  STRINGS,
  makeT,
  srvName,
  srvSub,
  SERVERS: [{
    code: 'HK',
    name: '香港 · 流媒体',
    en: 'Hong Kong',
    ping: 18,
    tags: ['流媒体优化']
  }, {
    code: 'JP',
    name: '日本 东京',
    en: 'Tokyo',
    ping: 32,
    tags: ['P2P']
  }, {
    code: 'SG',
    name: '新加坡',
    en: 'Singapore',
    ping: 54,
    tags: ['P2P']
  }, {
    code: 'TW',
    name: '台湾 台北',
    en: 'Taipei',
    ping: 28,
    tags: []
  }, {
    code: 'US',
    name: '美国 洛杉矶',
    en: 'Los Angeles',
    ping: 146,
    tags: ['流媒体优化']
  }, {
    code: 'DE',
    name: '德国 法兰克福',
    en: 'Frankfurt',
    ping: 198,
    tags: []
  }, {
    code: 'UK',
    name: '英国 伦敦',
    en: 'London',
    ping: 210,
    tags: []
  }, {
    code: 'KR',
    name: '韩国 首尔',
    en: 'Seoul',
    ping: 41,
    tags: []
  }]
});
})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/mobile/parts.jsx", error: String((e && e.message) || e) }); }

// ui_kits/mobile/screens.jsx
try { (() => {
/* screens.jsx — 穿山甲 VPN mobile · screens + bottom tab (i18n) */

const {
  useState,
  useEffect,
  useRef
} = React;

/* ───────── Top brand bar ───────── */
function TopBar({
  t,
  lang,
  right
}) {
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-between',
      padding: '6px 20px 14px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 9
    }
  }, /*#__PURE__*/React.createElement(Mark, {
    size: 28
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 18,
      color: 'var(--fg1)',
      letterSpacing: '-0.01em'
    }
  }, t('brand'))), right);
}

/* ───────── CONNECT screen ───────── */
function ConnectScreen({
  t,
  lang,
  status,
  onToggle,
  server,
  smart,
  free,
  mins,
  adDone,
  onAd,
  goServers,
  elapsed
}) {
  const map = {
    off: {
      fill: 'var(--sand-100)',
      fg: 'var(--clay-500)',
      icon: 'power',
      cap: t('capOff'),
      ring: 'track'
    },
    connecting: {
      fill: 'var(--accent)',
      fg: '#fff',
      icon: 'loader-circle',
      cap: t('capConnecting'),
      ring: 'spin'
    },
    on: {
      fill: 'var(--success)',
      fg: '#fff',
      icon: 'shield-check',
      cap: t('capOn'),
      ring: 'full'
    }
  }[status];
  const fmt = s => `${String(Math.floor(s / 3600)).padStart(2, '0')}:${String(Math.floor(s % 3600 / 60)).padStart(2, '0')}:${String(s % 60).padStart(2, '0')}`;
  const shadow = status === 'off' ? 'inset 0 0 0 1px var(--sand-200), var(--shadow-md)' : `0 0 0 9px ${status === 'on' ? 'var(--success-subtle)' : 'var(--accent-subtle)'}, var(--shadow-lg)`;
  // in-circle center block
  const center = status === 'off' ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-sans)',
      fontWeight: 700,
      fontSize: 14
    }
  }, t('connectNow'))) : status === 'connecting' ? /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontWeight: 700,
      fontSize: 14,
      letterSpacing: '0.08em'
    }
  }, "\xB7\xB7\xB7") : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontWeight: 600,
      fontSize: 18
    }
  }, fmt(elapsed)), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-sans)',
      fontWeight: 700,
      fontSize: 10,
      letterSpacing: '0.1em',
      opacity: .9
    }
  }, t('secure')));
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      height: '100%'
    }
  }, /*#__PURE__*/React.createElement(TopBar, {
    t: t,
    lang: lang,
    right: /*#__PURE__*/React.createElement("span", {
      style: {
        fontFamily: 'var(--font-mono)',
        fontSize: 12,
        whiteSpace: 'nowrap',
        color: status === 'on' ? 'var(--success)' : 'var(--fg3)',
        fontWeight: 600
      }
    }, status === 'on' ? t('online') : t('offline'))
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      justifyContent: 'center',
      gap: 26,
      padding: '0 24px'
    }
  }, /*#__PURE__*/React.createElement("button", {
    onClick: onToggle,
    style: {
      position: 'relative',
      width: 208,
      height: 208,
      borderRadius: '50%',
      border: 'none',
      cursor: 'pointer',
      background: map.fill,
      color: map.fg,
      boxShadow: shadow,
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      justifyContent: 'center',
      gap: 6,
      transition: 'box-shadow 300ms var(--ease-out), background-color 300ms var(--ease-out)'
    }
  }, /*#__PURE__*/React.createElement("svg", {
    viewBox: "0 0 208 208",
    style: {
      position: 'absolute',
      inset: 0,
      width: '100%',
      height: '100%',
      transformOrigin: 'center',
      animation: map.ring === 'spin' ? 'pg-spin 1.4s linear infinite' : 'none'
    }
  }, map.ring === 'track' && /*#__PURE__*/React.createElement("circle", {
    cx: "104",
    cy: "104",
    r: "96",
    fill: "none",
    stroke: "var(--sand-200)",
    strokeWidth: "3",
    strokeDasharray: "2 8",
    strokeLinecap: "round"
  }), map.ring === 'spin' && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("circle", {
    cx: "104",
    cy: "104",
    r: "96",
    fill: "none",
    stroke: "rgba(255,255,255,.3)",
    strokeWidth: "4"
  }), /*#__PURE__*/React.createElement("circle", {
    cx: "104",
    cy: "104",
    r: "96",
    fill: "none",
    stroke: "#fff",
    strokeWidth: "4",
    strokeLinecap: "round",
    strokeDasharray: "150 453"
  })), map.ring === 'full' && /*#__PURE__*/React.createElement("circle", {
    cx: "104",
    cy: "104",
    r: "96",
    fill: "none",
    stroke: "rgba(255,255,255,.85)",
    strokeWidth: "4",
    strokeLinecap: "round"
  })), /*#__PURE__*/React.createElement(Icon, {
    name: map.icon,
    size: 50,
    stroke: 1.7,
    style: status === 'connecting' ? {
      animation: 'pg-spin 1s linear infinite'
    } : {}
  }), center), /*#__PURE__*/React.createElement("div", {
    style: {
      textAlign: 'center'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-sans)',
      fontSize: 15,
      fontWeight: 600,
      color: 'var(--fg2)',
      whiteSpace: 'nowrap'
    }
  }, map.cap))), /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '0 20px 18px',
      display: 'flex',
      flexDirection: 'column',
      gap: 12
    }
  }, free && /*#__PURE__*/React.createElement("div", {
    style: {
      background: 'var(--surface)',
      borderRadius: 'var(--radius-lg)',
      padding: '12px 14px',
      boxShadow: 'var(--shadow-sm)',
      border: '1px solid var(--border)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 7,
      marginBottom: 8
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "clock",
    size: 15,
    stroke: 2.2,
    color: "var(--accent)"
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 12,
      fontWeight: 600,
      color: 'var(--fg2)'
    }
  }, t('quotaToday')), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 14,
      fontWeight: 600,
      color: 'var(--fg1)',
      whiteSpace: 'nowrap'
    }
  }, mins, " ", t('minutes')), /*#__PURE__*/React.createElement("span", {
    style: {
      marginLeft: 'auto',
      fontSize: 10.5,
      fontWeight: 600,
      color: 'var(--fg3)',
      background: 'var(--bg-subtle)',
      padding: '3px 9px',
      borderRadius: 'var(--radius-full)',
      whiteSpace: 'nowrap'
    }
  }, t('quotaFree'))), /*#__PURE__*/React.createElement("div", {
    style: {
      height: 6,
      background: 'var(--bg-subtle)',
      borderRadius: 3,
      overflow: 'hidden',
      marginBottom: 10
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: `${Math.min(100, mins / 10 * 100)}%`,
      height: '100%',
      background: mins <= 3 ? 'var(--warning)' : 'var(--accent)',
      borderRadius: 3,
      transition: 'width 300ms var(--ease-out)'
    }
  })), adDone ? /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      gap: 7,
      color: 'var(--success)',
      fontWeight: 700,
      fontSize: 13,
      padding: '9px'
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "check-circle",
    size: 16,
    stroke: 2.2,
    color: "var(--success)"
  }), t('adUnlocked')) : /*#__PURE__*/React.createElement("button", {
    onClick: onAd,
    style: {
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      gap: 7,
      width: '100%',
      border: '1.5px solid var(--accent-border)',
      background: 'var(--accent-subtle)',
      color: 'var(--accent)',
      fontFamily: 'var(--font-sans)',
      fontWeight: 700,
      fontSize: 13,
      padding: '9px',
      borderRadius: 'var(--radius-full)',
      cursor: 'pointer'
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "play-circle",
    size: 16,
    stroke: 2.2
  }), t('watchAd'))), status === 'on' && /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 12
    }
  }, [['arrow-down', t('download'), '86.4', 'Mb/s'], ['arrow-up', t('upload'), '12.1', 'Mb/s'], ['zap', t('latency'), String(server.ping), 'ms']].map(([ic, l, v, u]) => /*#__PURE__*/React.createElement("div", {
    key: l,
    style: {
      flex: 1,
      background: 'var(--surface)',
      borderRadius: 'var(--radius-lg)',
      padding: '12px 14px',
      boxShadow: 'var(--shadow-sm)',
      border: '1px solid var(--border)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 5,
      color: 'var(--fg3)',
      fontSize: 11,
      fontWeight: 600,
      marginBottom: 4
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: ic,
    size: 13,
    stroke: 2.2,
    color: "var(--accent)"
  }), l), /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 17,
      fontWeight: 500,
      color: 'var(--fg1)'
    }
  }, v, /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 11,
      color: 'var(--fg3)'
    }
  }, " ", u))))), /*#__PURE__*/React.createElement("button", {
    onClick: goServers,
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 12,
      width: '100%',
      textAlign: 'left',
      background: 'var(--surface)',
      border: '1px solid var(--border)',
      borderRadius: 'var(--radius-lg)',
      padding: '12px 14px',
      cursor: 'pointer',
      boxShadow: 'var(--shadow-sm)'
    }
  }, /*#__PURE__*/React.createElement(CC, {
    code: server.code,
    active: true
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-sans)',
      fontSize: 15,
      fontWeight: 600,
      color: 'var(--fg1)',
      display: 'flex',
      alignItems: 'center',
      gap: 7
    }
  }, smart ? t('smartSelect') : srvName(server, lang), smart && /*#__PURE__*/React.createElement(Icon, {
    name: "zap",
    size: 13,
    stroke: 2.4,
    color: "var(--accent)"
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      color: 'var(--fg3)'
    }
  }, smart ? `${srvName(server, lang)} · ${server.ping}ms` : `${srvSub(server, lang)} · ${server.ping}ms`)), /*#__PURE__*/React.createElement(Icon, {
    name: "chevron-right",
    size: 20,
    color: "var(--fg3)"
  }))));
}

/* ───────── SERVERS screen ───────── */
function ServersScreen({
  t,
  lang,
  current,
  onPick,
  q,
  setQ
}) {
  const list = SERVERS.filter(s => (s.name + s.en).toLowerCase().includes(q.toLowerCase()));
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      height: '100%'
    }
  }, /*#__PURE__*/React.createElement(TopBar, {
    t: t,
    lang: lang
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '0 20px 12px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontSize: 24,
      fontWeight: 700,
      color: 'var(--fg1)',
      marginBottom: 12
    }
  }, t('chooseNode')), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 10,
      background: 'var(--bg-subtle)',
      borderRadius: 'var(--radius-md)',
      padding: '10px 14px'
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "search",
    size: 18,
    color: "var(--fg3)"
  }), /*#__PURE__*/React.createElement("input", {
    value: q,
    onChange: e => setQ(e.target.value),
    placeholder: t('search'),
    style: {
      border: 'none',
      background: 'transparent',
      outline: 'none',
      flex: 1,
      fontFamily: 'var(--font-sans)',
      fontSize: 15,
      color: 'var(--fg1)'
    }
  }))), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      overflow: 'auto',
      padding: '0 20px 20px'
    }
  }, /*#__PURE__*/React.createElement("button", {
    onClick: () => onPick('AUTO'),
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 13,
      width: '100%',
      textAlign: 'left',
      padding: '15px 14px',
      border: `1.5px solid ${current === 'AUTO' ? 'var(--accent)' : 'var(--accent-border)'}`,
      cursor: 'pointer',
      background: 'var(--accent-subtle)',
      borderRadius: 'var(--radius-xl)',
      boxShadow: current === 'AUTO' ? 'var(--shadow-md)' : 'var(--shadow-sm)',
      marginBottom: 12
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 42,
      height: 42,
      borderRadius: 'var(--radius-md)',
      background: 'linear-gradient(150deg,var(--clay-500),var(--clay-700))',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "zap",
    size: 21,
    stroke: 2.2,
    color: "#fff"
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 8
    }
  }, /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-sans)',
      fontSize: 15.5,
      fontWeight: 700,
      color: 'var(--fg1)'
    }
  }, t('smartSelect')), /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 10,
      fontWeight: 700,
      color: '#fff',
      background: 'var(--accent)',
      padding: '2px 8px',
      borderRadius: 999,
      letterSpacing: '0.04em'
    }
  }, t('recommended'))), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      color: 'var(--fg2)',
      marginTop: 3,
      lineHeight: 1.5
    }
  }, t('smartSub'))), current === 'AUTO' && /*#__PURE__*/React.createElement(Icon, {
    name: "check",
    size: 19,
    color: "var(--accent)",
    stroke: 2.6
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      background: 'var(--surface)',
      borderRadius: 'var(--radius-lg)',
      boxShadow: 'var(--shadow-sm)',
      overflow: 'hidden',
      border: '1px solid var(--border)'
    }
  }, list.map((s, i) => {
    const active = s.code === current;
    return /*#__PURE__*/React.createElement("button", {
      key: s.code,
      onClick: () => onPick(s.code),
      style: {
        display: 'flex',
        alignItems: 'center',
        gap: 13,
        width: '100%',
        textAlign: 'left',
        padding: '12px 14px',
        border: 'none',
        cursor: 'pointer',
        borderBottom: i < list.length - 1 ? '1px solid var(--border)' : 'none',
        background: active ? 'var(--accent-subtle)' : 'transparent'
      }
    }, /*#__PURE__*/React.createElement(CC, {
      code: s.code,
      active: active
    }), /*#__PURE__*/React.createElement("div", {
      style: {
        flex: 1
      }
    }, /*#__PURE__*/React.createElement("div", {
      style: {
        fontFamily: 'var(--font-sans)',
        fontSize: 15,
        fontWeight: 600,
        color: 'var(--fg1)'
      }
    }, srvName(s, lang)), /*#__PURE__*/React.createElement("div", {
      style: {
        fontSize: 12,
        color: 'var(--fg3)'
      }
    }, srvSub(s, lang))), /*#__PURE__*/React.createElement("span", {
      style: {
        fontFamily: 'var(--font-mono)',
        fontSize: 12,
        color: 'var(--fg2)'
      }
    }, s.ping, "ms"), /*#__PURE__*/React.createElement(Signal, {
      ping: s.ping
    }), active && /*#__PURE__*/React.createElement(Icon, {
      name: "check",
      size: 18,
      color: "var(--accent)"
    }));
  }))));
}

/* ───────── SETTINGS screen ───────── */
function Toggle({
  on,
  onChange
}) {
  return /*#__PURE__*/React.createElement("div", {
    onClick: onChange,
    style: {
      width: 46,
      height: 28,
      borderRadius: 999,
      position: 'relative',
      cursor: 'pointer',
      flexShrink: 0,
      background: on ? 'var(--accent)' : 'var(--border-strong)',
      transition: 'background 220ms var(--ease-out)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'absolute',
      top: 3,
      left: on ? 21 : 3,
      width: 22,
      height: 22,
      borderRadius: '50%',
      background: '#fff',
      boxShadow: 'var(--shadow-sm)',
      transition: 'left 220ms var(--ease-out)'
    }
  }));
}
/* segmented language switch 中 / EN */
function LangSwitch({
  lang,
  setLang
}) {
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      background: 'var(--bg-subtle)',
      borderRadius: 'var(--radius-full)',
      padding: 3,
      gap: 2
    }
  }, [['zh', '中文'], ['en', 'EN']].map(([v, l]) => /*#__PURE__*/React.createElement("button", {
    key: v,
    onClick: () => setLang(v),
    style: {
      border: 'none',
      cursor: 'pointer',
      borderRadius: 'var(--radius-full)',
      padding: '5px 13px',
      fontFamily: 'var(--font-sans)',
      fontSize: 12.5,
      fontWeight: 700,
      background: lang === v ? 'var(--accent)' : 'transparent',
      color: lang === v ? 'var(--fg-on-accent)' : 'var(--fg3)',
      transition: 'all 140ms var(--ease-out)'
    }
  }, l)));
}
function Row({
  icon,
  title,
  sub,
  right,
  last,
  onClick
}) {
  return /*#__PURE__*/React.createElement("div", {
    onClick: onClick,
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 13,
      padding: '13px 16px',
      borderBottom: last ? 'none' : '1px solid var(--border)',
      cursor: onClick ? 'pointer' : 'default'
    }
  }, icon && /*#__PURE__*/React.createElement("div", {
    style: {
      width: 32,
      height: 32,
      borderRadius: 'var(--radius-sm)',
      background: 'var(--accent-subtle)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: icon,
    size: 17,
    color: "var(--accent)",
    stroke: 2.2
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-sans)',
      fontSize: 15,
      fontWeight: 500,
      color: 'var(--fg1)'
    }
  }, title), sub && /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      color: 'var(--fg3)'
    }
  }, sub)), right);
}
function SettingsScreen({
  t,
  lang,
  setLang,
  dark,
  setDark,
  free,
  setFree,
  onRedeem,
  onUpgrade,
  onContact,
  onSignOut,
  onReplayAuth,
  onReplayOnboarding
}) {
  const [autostart, setAuto] = useState(true);
  const [kill, setKill] = useState(true);
  const [twoFA, setTwoFA] = useState(true);
  const [devices, setDevices] = useState([{
    id: 1,
    icon: 'laptop',
    name: 'MacBook Pro',
    os: 'macOS 26',
    active: t('thisDevice'),
    me: true
  }, {
    id: 2,
    icon: 'smartphone',
    name: 'iPhone 17',
    os: 'iOS 26',
    active: '2 min',
    me: false
  }, {
    id: 3,
    icon: 'monitor-smartphone',
    name: 'iPad Air',
    os: 'iPadOS 26',
    active: lang === 'zh' ? '3 小时前' : '3h ago',
    me: false
  }]);
  const card = {
    background: 'var(--surface)',
    borderRadius: 'var(--radius-lg)',
    boxShadow: 'var(--shadow-sm)',
    border: '1px solid var(--border)',
    overflow: 'hidden',
    marginBottom: 18
  };
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      height: '100%'
    }
  }, /*#__PURE__*/React.createElement(TopBar, {
    t: t,
    lang: lang
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      overflow: 'auto',
      padding: '0 20px 20px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontSize: 24,
      fontWeight: 700,
      color: 'var(--fg1)',
      marginBottom: 14
    }
  }, t('meTitle')), /*#__PURE__*/React.createElement("div", {
    style: {
      background: 'linear-gradient(155deg,var(--clay-600),var(--clay-800))',
      borderRadius: 'var(--radius-xl)',
      padding: 18,
      color: '#fff',
      marginBottom: 18,
      boxShadow: 'var(--shadow-md)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 11
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 44,
      height: 44,
      borderRadius: '50%',
      background: 'rgba(255,255,255,0.18)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center'
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "crown",
    size: 22,
    color: "#fff"
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontWeight: 700,
      fontSize: 16
    }
  }, "me@pangolin.vpn"), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'inline-flex',
      alignItems: 'center',
      gap: 4,
      fontSize: 11,
      fontWeight: 600,
      background: 'rgba(255,255,255,0.2)',
      padding: '2px 8px',
      borderRadius: 999,
      marginTop: 4
    }
  }, free ? t('freePlanName') : t('proMember')))), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      justifyContent: 'space-between',
      alignItems: 'flex-end',
      marginTop: 16,
      paddingTop: 14,
      borderTop: '1px solid rgba(255,255,255,0.18)',
      fontSize: 12
    }
  }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
    style: {
      opacity: 0.7
    }
  }, free ? t('quotaToday') : t('expires')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontWeight: 600,
      marginTop: 2,
      fontFamily: 'var(--font-mono)',
      whiteSpace: 'nowrap'
    }
  }, free ? t('quotaFree') : '2026-12-31 · 42.6 GB')), /*#__PURE__*/React.createElement("button", {
    onClick: onUpgrade,
    style: {
      border: 'none',
      background: '#fff',
      color: 'var(--clay-700)',
      fontWeight: 700,
      fontSize: 13,
      padding: '9px 16px',
      borderRadius: 'var(--radius-full)',
      cursor: 'pointer',
      display: 'inline-flex',
      alignItems: 'center',
      gap: 6
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "ticket",
    size: 15,
    color: "var(--clay-700)"
  }), t('upgradeBtn')))), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13,
      fontWeight: 700,
      color: 'var(--fg2)',
      margin: '4px 4px 10px'
    }
  }, t('accInfoTitle')), /*#__PURE__*/React.createElement("div", {
    style: card
  }, /*#__PURE__*/React.createElement(Row, {
    icon: "mail",
    title: t('accEmail'),
    sub: "me@pangolin.vpn",
    right: /*#__PURE__*/React.createElement("span", {
      style: {
        fontSize: 13,
        color: 'var(--accent)',
        fontWeight: 600
      }
    }, t('accChange'))
  }), /*#__PURE__*/React.createElement(Row, {
    icon: "lock",
    title: t('accPassword'),
    sub: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
    right: /*#__PURE__*/React.createElement("span", {
      style: {
        fontSize: 13,
        color: 'var(--accent)',
        fontWeight: 600
      }
    }, t('accChange'))
  }), /*#__PURE__*/React.createElement(Row, {
    icon: "shield",
    title: t('twoFA'),
    sub: t('twoFASub'),
    right: /*#__PURE__*/React.createElement(Toggle, {
      on: twoFA,
      onChange: () => setTwoFA(!twoFA)
    }),
    last: true
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13,
      fontWeight: 700,
      color: 'var(--fg2)',
      margin: '4px 4px 4px'
    }
  }, t('myDevices')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11.5,
      color: 'var(--fg3)',
      margin: '0 4px 10px'
    }
  }, t('devicesSub')), /*#__PURE__*/React.createElement("div", {
    style: card
  }, devices.map((d, i) => /*#__PURE__*/React.createElement("div", {
    key: d.id,
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 12,
      padding: '12px 16px',
      borderBottom: i < devices.length - 1 ? '1px solid var(--border)' : 'none'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 34,
      height: 34,
      borderRadius: 'var(--radius-md)',
      background: 'var(--accent-subtle)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: d.icon,
    size: 18,
    color: "var(--accent)"
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      minWidth: 0
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 14,
      fontWeight: 600,
      color: 'var(--fg1)',
      display: 'flex',
      alignItems: 'center',
      gap: 7
    }
  }, d.name, d.me && /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 10.5,
      fontWeight: 600,
      color: 'var(--success)',
      background: 'var(--success-subtle)',
      padding: '1px 7px',
      borderRadius: 999
    }
  }, d.active)), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11.5,
      color: 'var(--fg3)',
      marginTop: 1
    }
  }, d.os, !d.me && ` · ${d.active}`)), !d.me && /*#__PURE__*/React.createElement("button", {
    onClick: () => setDevices(devices.filter(x => x.id !== d.id)),
    style: {
      border: '1.5px solid var(--border-strong)',
      background: 'transparent',
      color: 'var(--fg2)',
      fontSize: 12.5,
      fontWeight: 600,
      padding: '6px 12px',
      borderRadius: 'var(--radius-full)',
      cursor: 'pointer'
    }
  }, t('remove'))))), /*#__PURE__*/React.createElement("div", {
    style: card
  }, /*#__PURE__*/React.createElement(Row, {
    icon: "shopping-bag",
    title: t('redeemEntry'),
    right: /*#__PURE__*/React.createElement(Icon, {
      name: "chevron-right",
      size: 18,
      color: "var(--fg3)"
    }),
    onClick: onRedeem
  }), /*#__PURE__*/React.createElement(Row, {
    icon: "external-link",
    title: t('ucEntry'),
    sub: t('ucEntrySub'),
    right: /*#__PURE__*/React.createElement(Icon, {
      name: "chevron-right",
      size: 18,
      color: "var(--fg3)"
    }),
    onClick: () => window.open('../usercenter/index.html', '_blank')
  }), /*#__PURE__*/React.createElement(Row, {
    icon: "message-circle",
    title: t('contactEntry'),
    right: /*#__PURE__*/React.createElement(Icon, {
      name: "chevron-right",
      size: 18,
      color: "var(--fg3)"
    }),
    last: true,
    onClick: onContact
  })), /*#__PURE__*/React.createElement("div", {
    style: card
  }, /*#__PURE__*/React.createElement(Row, {
    icon: "zap",
    title: t('smartRoute'),
    sub: t('smartRouteSub'),
    right: /*#__PURE__*/React.createElement(Toggle, {
      on: autostart,
      onChange: () => setAuto(!autostart)
    })
  }), /*#__PURE__*/React.createElement(Row, {
    icon: "shield",
    title: t('killSwitch'),
    sub: t('killSwitchSub'),
    right: /*#__PURE__*/React.createElement(Toggle, {
      on: kill,
      onChange: () => setKill(!kill)
    }),
    last: true
  })), /*#__PURE__*/React.createElement("div", {
    style: card
  }, /*#__PURE__*/React.createElement(Row, {
    icon: "globe",
    title: t('language'),
    right: /*#__PURE__*/React.createElement(LangSwitch, {
      lang: lang,
      setLang: setLang
    })
  }), /*#__PURE__*/React.createElement(Row, {
    icon: dark ? 'moon' : 'sun',
    title: t('darkAppearance'),
    sub: dark ? t('stateOn') : t('followLight'),
    right: /*#__PURE__*/React.createElement(Toggle, {
      on: dark,
      onChange: () => setDark(!dark)
    })
  }), /*#__PURE__*/React.createElement(Row, {
    icon: "shield",
    title: t('protocol'),
    right: /*#__PURE__*/React.createElement("span", {
      style: {
        fontFamily: 'var(--font-mono)',
        fontSize: 13,
        color: 'var(--fg3)'
      }
    }, "WireGuard")
  }), /*#__PURE__*/React.createElement(Row, {
    icon: "refresh-cw",
    title: t('checkUpdate'),
    right: /*#__PURE__*/React.createElement(Icon, {
      name: "chevron-right",
      size: 18,
      color: "var(--fg3)"
    }),
    last: true
  })), /*#__PURE__*/React.createElement("div", {
    style: card
  }, /*#__PURE__*/React.createElement(Row, {
    icon: "log-out",
    title: t('replayAuth'),
    sub: t('replayAuthSub'),
    right: /*#__PURE__*/React.createElement(Icon, {
      name: "chevron-right",
      size: 18,
      color: "var(--fg3)"
    }),
    onClick: onReplayAuth
  }), /*#__PURE__*/React.createElement(Row, {
    icon: "compass",
    title: t('replayOnboarding'),
    sub: t('replayOnboardingSub'),
    right: /*#__PURE__*/React.createElement(Icon, {
      name: "chevron-right",
      size: 18,
      color: "var(--fg3)"
    }),
    onClick: onReplayOnboarding
  }), /*#__PURE__*/React.createElement(Row, {
    icon: "clock",
    title: t('freeDemo'),
    sub: t('freeDemoSub'),
    right: /*#__PURE__*/React.createElement(Toggle, {
      on: free,
      onChange: () => setFree(!free)
    }),
    last: true
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      textAlign: 'center',
      fontSize: 12,
      color: 'var(--fg3)',
      fontFamily: 'var(--font-mono)'
    }
  }, "\u7A7F\u5C71\u7532 \xB7 v2.4.0")));
}

/* ───────── STATS screen ───────── */
function StatsScreen({
  t,
  lang
}) {
  const vals = [2.1, 3.4, 1.8, 4.6, 5.2, 6.1, 3.0];
  const max = 6.1;
  const labels = t('days7');
  const card = {
    background: 'var(--surface)',
    border: '1px solid var(--border)',
    borderRadius: 'var(--radius-lg)',
    boxShadow: 'var(--shadow-sm)'
  };
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      height: '100%'
    }
  }, /*#__PURE__*/React.createElement(TopBar, {
    t: t,
    lang: lang
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      overflow: 'auto',
      padding: '0 20px 20px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontSize: 24,
      fontWeight: 700,
      color: 'var(--fg1)',
      marginBottom: 16
    }
  }, t('statsTitle')), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 12,
      marginBottom: 16
    }
  }, [[t('trafficMonth'), '42.6', 'GB'], [t('avgPing'), '29', 'ms'], [t('durMonth'), '86.4', 'h']].map(([l, v, u]) => /*#__PURE__*/React.createElement("div", {
    key: l,
    style: {
      ...card,
      flex: 1,
      padding: '14px 14px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11,
      color: 'var(--fg3)',
      fontWeight: 600
    }
  }, l), /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 20,
      fontWeight: 500,
      color: 'var(--fg1)',
      marginTop: 6
    }
  }, v, /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 11,
      color: 'var(--fg3)'
    }
  }, " ", u))))), /*#__PURE__*/React.createElement("div", {
    style: {
      ...card,
      padding: '18px 18px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13,
      fontWeight: 600,
      color: 'var(--fg1)',
      marginBottom: 18
    }
  }, t('weekTraffic')), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'flex-end',
      gap: 12,
      height: 120
    }
  }, vals.map((v, i) => /*#__PURE__*/React.createElement("div", {
    key: i,
    style: {
      flex: 1,
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      gap: 7
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 10,
      color: 'var(--fg3)'
    }
  }, v), /*#__PURE__*/React.createElement("div", {
    style: {
      width: '100%',
      maxWidth: 30,
      height: `${v / max * 84}px`,
      background: 'var(--accent)',
      borderRadius: '6px 6px 0 0',
      opacity: 0.85
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11,
      color: 'var(--fg3)'
    }
  }, labels[i])))))));
}

/* ───────── Bottom tab ───────── */
function BottomTab({
  t,
  tab,
  setTab
}) {
  const items = [['connect', 'power', t('tabConnect')], ['servers', 'globe', t('tabServers')], ['stats', 'chart', t('tabStats')], ['me', 'user', t('tabMe')]];
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      borderTop: '1px solid var(--border)',
      background: 'var(--surface)',
      paddingBottom: 22
    }
  }, items.map(([id, ic, label]) => {
    const a = tab === id;
    return /*#__PURE__*/React.createElement("button", {
      key: id,
      onClick: () => setTab(id),
      style: {
        flex: 1,
        border: 'none',
        background: 'transparent',
        cursor: 'pointer',
        padding: '10px 0 4px',
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        gap: 4
      }
    }, /*#__PURE__*/React.createElement(Icon, {
      name: ic,
      size: 22,
      stroke: a ? 2.4 : 2,
      color: a ? 'var(--accent)' : 'var(--fg3)'
    }), /*#__PURE__*/React.createElement("span", {
      style: {
        fontFamily: 'var(--font-sans)',
        fontSize: 11,
        fontWeight: a ? 700 : 500,
        color: a ? 'var(--accent)' : 'var(--fg3)'
      }
    }, label));
  }));
}
Object.assign(window, {
  ConnectScreen,
  ServersScreen,
  StatsScreen,
  SettingsScreen,
  BottomTab,
  LangSwitch
});
})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/mobile/screens.jsx", error: String((e && e.message) || e) }); }

// ui_kits/tablet/tabapp.jsx
try { (() => {
/* tabapp.jsx — 穿山甲 iPad 客户端 · 分栏布局
   复用 ../mobile/parts.jsx 的 Icon/Mark/CC/Signal/SERVERS/makeT/srvName/srvSub。
   仅 iPad 专属字串定义在本文件 TSTR。 */

const {
  useState,
  useEffect,
  useRef
} = React;

/* iPad 专属字串(双语单显) */
const TSTR = {
  navConnect: {
    zh: '连接',
    en: 'Connect'
  },
  navNodes: {
    zh: '节点',
    en: 'Nodes'
  },
  navStats: {
    zh: '统计',
    en: 'Stats'
  },
  navAccount: {
    zh: '账户',
    en: 'Account'
  },
  capOff: {
    zh: '未连接 · 轻点连接',
    en: 'Not connected · tap to start'
  },
  capConnecting: {
    zh: '连接中 Connecting…',
    en: 'Connecting…'
  },
  capOn: {
    zh: '已连接 · 网络已加密',
    en: 'Connected · traffic encrypted'
  },
  download: {
    zh: '下载',
    en: 'Down'
  },
  upload: {
    zh: '上传',
    en: 'Up'
  },
  latency: {
    zh: '延迟',
    en: 'Ping'
  },
  curNode: {
    zh: '当前节点',
    en: 'Current node'
  },
  searchPh: {
    zh: '搜索国家 / 城市',
    en: 'Search country / city'
  },
  statTraffic: {
    zh: '本月流量',
    en: 'Data this month'
  },
  statPing: {
    zh: '平均延迟',
    en: 'Avg latency'
  },
  statTime: {
    zh: '本月时长',
    en: 'Time this month'
  },
  weekTraffic: {
    zh: '本周流量 (GB)',
    en: 'This week (GB)'
  },
  days: {
    zh: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
    en: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },
  acctEmail: {
    zh: '邮箱',
    en: 'Email'
  },
  language: {
    zh: '语言',
    en: 'Language'
  },
  darkMode: {
    zh: '深色外观',
    en: 'Dark appearance'
  },
  smartRoute: {
    zh: '智能分流',
    en: 'Smart routing'
  },
  smartRouteSub: {
    zh: '海外应用走加速,国内直连',
    en: 'Accelerate abroad, direct at home'
  },
  killSwitch: {
    zh: 'Kill Switch',
    en: 'Kill Switch'
  },
  killSub: {
    zh: '断线时阻断网络,防止泄露',
    en: 'Block traffic if the link drops'
  },
  freeBanner: {
    zh: '免费版',
    en: 'Free plan'
  },
  trialNote: {
    zh: '升级 PRO:不限时长 · 80+ 加速线路 · 5 台设备',
    en: 'Go PRO: unlimited time · 80+ routes · 5 devices'
  },
  version: {
    zh: '穿山甲 · iPadOS · v2.4.0',
    en: 'Pangolin · iPadOS · v2.4.0'
  }
};
function makeTT(lang) {
  return k => (TSTR[k] && TSTR[k][lang]) !== undefined ? TSTR[k][lang] : k;
}
function fmtHMS(s) {
  return `${String(Math.floor(s / 3600)).padStart(2, '0')}:${String(Math.floor(s % 3600 / 60)).padStart(2, '0')}:${String(s % 60).padStart(2, '0')}`;
}

/* ── 左侧栏 ── */
function TabRail({
  tt,
  view,
  setView,
  free,
  t
}) {
  const items = [['connect', 'power', 'navConnect'], ['nodes', 'globe', 'navNodes'], ['stats', 'chart', 'navStats'], ['account', 'user', 'navAccount']];
  return /*#__PURE__*/React.createElement("div", {
    style: {
      width: 232,
      flexShrink: 0,
      background: 'var(--bg-subtle)',
      borderRight: '1px solid var(--border)',
      display: 'flex',
      flexDirection: 'column',
      padding: '18px 14px 16px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 10,
      padding: '0 8px 20px'
    }
  }, /*#__PURE__*/React.createElement(Mark, {
    size: 30
  }), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 17,
      color: 'var(--fg1)',
      lineHeight: 1
    }
  }, "\u7A7F\u5C71\u7532"), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 9,
      fontWeight: 600,
      letterSpacing: '0.2em',
      color: 'var(--accent)',
      marginTop: 3
    }
  }, "PANGOLIN"))), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      gap: 4
    }
  }, items.map(([id, ic, lk]) => {
    const a = view === id;
    return /*#__PURE__*/React.createElement("button", {
      key: id,
      onClick: () => setView(id),
      style: {
        display: 'flex',
        alignItems: 'center',
        gap: 12,
        width: '100%',
        textAlign: 'left',
        border: 'none',
        cursor: 'pointer',
        background: a ? 'var(--accent-subtle)' : 'transparent',
        color: a ? 'var(--accent)' : 'var(--fg2)',
        padding: '13px 14px',
        borderRadius: 'var(--radius-md)',
        fontFamily: 'var(--font-sans)',
        fontSize: 15,
        fontWeight: a ? 700 : 500,
        transition: 'background-color 140ms var(--ease-out), color 140ms var(--ease-out)',
        minHeight: 48
      }
    }, /*#__PURE__*/React.createElement(Icon, {
      name: ic,
      size: 20,
      stroke: a ? 2.4 : 2,
      color: a ? 'var(--accent)' : 'var(--fg3)'
    }), tt(lk));
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      background: free ? 'var(--surface)' : 'linear-gradient(150deg,var(--clay-600),var(--clay-800))',
      border: free ? '1px solid var(--border)' : 'none',
      borderRadius: 'var(--radius-lg)',
      padding: '12px 13px',
      color: free ? 'var(--fg1)' : '#fff'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 9
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 32,
      height: 32,
      borderRadius: '50%',
      background: free ? 'var(--bg-subtle)' : 'rgba(255,255,255,0.18)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: free ? 'user' : 'crown',
    size: 16,
    color: free ? 'var(--fg2)' : '#fff'
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      minWidth: 0
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12.5,
      fontWeight: 700,
      whiteSpace: 'nowrap'
    }
  }, free ? tt('freeBanner') : t('proMember')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 10.5,
      opacity: 0.65,
      whiteSpace: 'nowrap'
    }
  }, "me@pangolin.vpn")))));
}

/* ── 连接视图:左大按钮 + 右信息列 ── */
function TabConnect({
  t,
  tt,
  lang,
  status,
  onToggle,
  server,
  smart,
  free,
  mins,
  adDone,
  onAd,
  elapsed,
  goNodes
}) {
  const map = {
    off: {
      ring: 'var(--border)',
      fill: 'var(--surface)',
      fg: 'var(--fg2)',
      icon: 'power',
      label: 'TAP',
      cap: tt('capOff')
    },
    connecting: {
      ring: 'var(--accent-subtle)',
      fill: 'var(--accent)',
      fg: '#fff',
      icon: 'loader-circle',
      label: '···',
      cap: tt('capConnecting')
    },
    on: {
      ring: 'var(--success-subtle)',
      fill: 'var(--success)',
      fg: '#fff',
      icon: 'shield-check',
      label: 'SAFE',
      cap: tt('capOn')
    }
  }[status];
  const card = {
    background: 'var(--surface)',
    border: '1px solid var(--border)',
    borderRadius: 'var(--radius-lg)',
    boxShadow: 'var(--shadow-sm)'
  };
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      height: '100%',
      alignItems: 'stretch'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1.25,
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      justifyContent: 'center',
      gap: 26
    }
  }, /*#__PURE__*/React.createElement("button", {
    onClick: onToggle,
    style: {
      width: 216,
      height: 216,
      borderRadius: '50%',
      border: 'none',
      cursor: 'pointer',
      background: map.fill,
      color: map.fg,
      boxShadow: `0 0 0 11px ${map.ring}, var(--shadow-lg)`,
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      justifyContent: 'center',
      gap: 12,
      transition: 'box-shadow 300ms var(--ease-out), background-color 300ms var(--ease-out)'
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: map.icon,
    size: 60,
    stroke: 1.6,
    style: status === 'connecting' ? {
      animation: 'pg-spin 1s linear infinite'
    } : {}
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontWeight: 700,
      fontSize: 14,
      letterSpacing: '0.08em'
    }
  }, map.label)), /*#__PURE__*/React.createElement("div", {
    style: {
      textAlign: 'center'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-sans)',
      fontSize: 16,
      fontWeight: 600,
      color: 'var(--fg2)',
      whiteSpace: 'nowrap'
    }
  }, map.cap), status === 'on' && /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 28,
      fontWeight: 500,
      color: 'var(--fg1)',
      marginTop: 8,
      letterSpacing: '-0.01em'
    }
  }, fmtHMS(elapsed)))), /*#__PURE__*/React.createElement("div", {
    style: {
      width: 332,
      flexShrink: 0,
      display: 'flex',
      flexDirection: 'column',
      gap: 14,
      justifyContent: 'center',
      paddingRight: 28
    }
  }, free && /*#__PURE__*/React.createElement("div", {
    style: {
      ...card,
      padding: '14px 16px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 8,
      marginBottom: 9
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "clock",
    size: 15,
    stroke: 2.2,
    color: "var(--accent)"
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 12.5,
      fontWeight: 600,
      color: 'var(--fg2)'
    }
  }, t('quotaToday')), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 14,
      fontWeight: 600,
      color: 'var(--fg1)',
      whiteSpace: 'nowrap'
    }
  }, mins, " ", t('minutes')), /*#__PURE__*/React.createElement("span", {
    style: {
      marginLeft: 'auto',
      fontSize: 10.5,
      fontWeight: 600,
      color: 'var(--fg3)',
      background: 'var(--bg-subtle)',
      padding: '3px 9px',
      borderRadius: 'var(--radius-full)',
      whiteSpace: 'nowrap'
    }
  }, t('quotaFree'))), /*#__PURE__*/React.createElement("div", {
    style: {
      height: 6,
      background: 'var(--bg-subtle)',
      borderRadius: 3,
      overflow: 'hidden',
      marginBottom: 11
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: `${Math.min(100, mins / 10 * 100)}%`,
      height: '100%',
      background: mins <= 3 ? 'var(--warning)' : 'var(--accent)',
      borderRadius: 3
    }
  })), adDone ? /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      gap: 7,
      color: 'var(--success)',
      fontWeight: 700,
      fontSize: 13,
      padding: '8px'
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "check-circle",
    size: 16,
    stroke: 2.2,
    color: "var(--success)"
  }), t('adUnlocked')) : /*#__PURE__*/React.createElement("button", {
    onClick: onAd,
    style: {
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      gap: 7,
      width: '100%',
      border: '1.5px solid var(--accent-border)',
      background: 'var(--accent-subtle)',
      color: 'var(--accent)',
      fontFamily: 'var(--font-sans)',
      fontWeight: 700,
      fontSize: 13.5,
      padding: '10px',
      borderRadius: 'var(--radius-full)',
      cursor: 'pointer',
      minHeight: 44
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "play-circle",
    size: 16,
    stroke: 2.2
  }), t('watchAd'))), /*#__PURE__*/React.createElement("button", {
    onClick: goNodes,
    style: {
      ...card,
      display: 'flex',
      alignItems: 'center',
      gap: 13,
      textAlign: 'left',
      padding: '13px 15px',
      cursor: 'pointer',
      minHeight: 48
    }
  }, /*#__PURE__*/React.createElement(CC, {
    code: server.code,
    active: true
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11,
      fontWeight: 600,
      color: 'var(--fg3)',
      marginBottom: 2
    }
  }, tt('curNode')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-sans)',
      fontSize: 15,
      fontWeight: 600,
      color: 'var(--fg1)',
      display: 'flex',
      alignItems: 'center',
      gap: 7
    }
  }, smart ? t('smartSelect') : srvName(server, lang), smart && /*#__PURE__*/React.createElement(Icon, {
    name: "zap",
    size: 13,
    stroke: 2.4,
    color: "var(--accent)"
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      color: 'var(--fg3)'
    }
  }, smart ? `${srvName(server, lang)} · ${server.ping}ms` : `${srvSub(server, lang)} · ${server.ping}ms`)), /*#__PURE__*/React.createElement(Icon, {
    name: "chevron-right",
    size: 20,
    color: "var(--fg3)"
  })), status === 'on' && /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 10
    }
  }, [['arrow-down', tt('download'), '86.4', 'Mb/s'], ['arrow-up', tt('upload'), '12.1', 'Mb/s'], ['zap', tt('latency'), String(server.ping), 'ms']].map(([ic, l, v, u]) => /*#__PURE__*/React.createElement("div", {
    key: ic,
    style: {
      ...card,
      flex: 1,
      padding: '11px 13px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 5,
      color: 'var(--fg3)',
      fontSize: 11,
      fontWeight: 600,
      marginBottom: 4
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: ic,
    size: 13,
    stroke: 2.2,
    color: "var(--accent)"
  }), l), /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 16,
      fontWeight: 500,
      color: 'var(--fg1)'
    }
  }, v, /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 10.5,
      color: 'var(--fg3)'
    }
  }, " ", u)))))));
}

/* ── 节点视图 ── */
function TabNodes({
  t,
  tt,
  lang,
  current,
  onPick
}) {
  const [q, setQ] = useState('');
  const list = SERVERS.filter(s => (s.name + s.en).toLowerCase().includes(q.toLowerCase()));
  const smartActive = current === 'AUTO';
  return /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '6px 28px 24px',
      overflow: 'auto',
      height: '100%',
      boxSizing: 'border-box'
    }
  }, /*#__PURE__*/React.createElement("button", {
    onClick: () => onPick('AUTO'),
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 13,
      width: '100%',
      textAlign: 'left',
      cursor: 'pointer',
      background: 'var(--accent-subtle)',
      border: `1.5px solid ${smartActive ? 'var(--accent)' : 'var(--accent-border)'}`,
      borderRadius: 'var(--radius-xl)',
      padding: '15px 16px',
      boxShadow: smartActive ? 'var(--shadow-md)' : 'var(--shadow-sm)',
      marginBottom: 14,
      minHeight: 56
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 42,
      height: 42,
      borderRadius: 'var(--radius-md)',
      background: 'linear-gradient(150deg,var(--clay-500),var(--clay-700))',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "zap",
    size: 21,
    stroke: 2.2,
    color: "#fff"
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 8
    }
  }, /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-sans)',
      fontSize: 15.5,
      fontWeight: 700,
      color: 'var(--fg1)'
    }
  }, t('smartSelect')), /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 10,
      fontWeight: 700,
      color: '#fff',
      background: 'var(--accent)',
      padding: '2px 8px',
      borderRadius: 999,
      letterSpacing: '0.04em'
    }
  }, t('recommended'))), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      color: 'var(--fg2)',
      marginTop: 3
    }
  }, t('smartSub'))), smartActive && /*#__PURE__*/React.createElement(Icon, {
    name: "check",
    size: 19,
    color: "var(--accent)",
    stroke: 2.6
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 10,
      background: 'var(--bg-subtle)',
      borderRadius: 'var(--radius-md)',
      padding: '11px 14px',
      marginBottom: 14,
      maxWidth: 380
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "search",
    size: 18,
    color: "var(--fg3)"
  }), /*#__PURE__*/React.createElement("input", {
    value: q,
    onChange: e => setQ(e.target.value),
    placeholder: tt('searchPh'),
    style: {
      border: 'none',
      background: 'transparent',
      outline: 'none',
      flex: 1,
      fontFamily: 'var(--font-sans)',
      fontSize: 14.5,
      color: 'var(--fg1)'
    }
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'grid',
      gridTemplateColumns: '1fr 1fr',
      gap: 11
    }
  }, list.map(s => {
    const active = s.code === current;
    return /*#__PURE__*/React.createElement("button", {
      key: s.code,
      onClick: () => onPick(s.code),
      style: {
        display: 'flex',
        alignItems: 'center',
        gap: 12,
        textAlign: 'left',
        cursor: 'pointer',
        background: active ? 'var(--accent-subtle)' : 'var(--surface)',
        border: `1.5px solid ${active ? 'var(--accent-border)' : 'var(--border)'}`,
        borderRadius: 'var(--radius-lg)',
        padding: '13px 15px',
        boxShadow: 'var(--shadow-sm)',
        minHeight: 56
      }
    }, /*#__PURE__*/React.createElement(CC, {
      code: s.code,
      active: active
    }), /*#__PURE__*/React.createElement("div", {
      style: {
        flex: 1,
        minWidth: 0
      }
    }, /*#__PURE__*/React.createElement("div", {
      style: {
        fontFamily: 'var(--font-sans)',
        fontSize: 14.5,
        fontWeight: 600,
        color: 'var(--fg1)'
      }
    }, srvName(s, lang)), /*#__PURE__*/React.createElement("div", {
      style: {
        fontSize: 12,
        color: 'var(--fg3)',
        whiteSpace: 'nowrap',
        overflow: 'hidden',
        textOverflow: 'ellipsis'
      }
    }, srvSub(s, lang))), /*#__PURE__*/React.createElement("div", {
      style: {
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'flex-end',
        gap: 5
      }
    }, /*#__PURE__*/React.createElement("span", {
      style: {
        fontFamily: 'var(--font-mono)',
        fontSize: 12,
        color: 'var(--fg2)'
      }
    }, s.ping, "ms"), /*#__PURE__*/React.createElement(Signal, {
      ping: s.ping
    })), active && /*#__PURE__*/React.createElement(Icon, {
      name: "check",
      size: 18,
      color: "var(--accent)"
    }));
  })));
}

/* ── 统计视图 ── */
function TabStats({
  tt,
  lang
}) {
  const vals = [2.1, 3.4, 1.8, 4.6, 5.2, 6.1, 3.0];
  const days = TSTR.days[lang];
  const max = Math.max(...vals);
  const card = {
    background: 'var(--surface)',
    border: '1px solid var(--border)',
    borderRadius: 'var(--radius-lg)',
    boxShadow: 'var(--shadow-sm)'
  };
  return /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '6px 28px 24px',
      overflow: 'auto',
      height: '100%',
      boxSizing: 'border-box'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 14,
      marginBottom: 20
    }
  }, [[tt('statTraffic'), '42.6 GB'], [tt('statPing'), '29 ms'], [tt('statTime'), '86.4 h']].map(([l, v]) => /*#__PURE__*/React.createElement("div", {
    key: l,
    style: {
      ...card,
      flex: 1,
      padding: '18px 20px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12.5,
      color: 'var(--fg3)',
      fontWeight: 600
    }
  }, l), /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 26,
      fontWeight: 500,
      color: 'var(--fg1)',
      marginTop: 7
    }
  }, v)))), /*#__PURE__*/React.createElement("div", {
    style: {
      ...card,
      padding: '20px 22px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13.5,
      fontWeight: 600,
      color: 'var(--fg1)',
      marginBottom: 20
    }
  }, tt('weekTraffic')), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'flex-end',
      gap: 22,
      height: 150
    }
  }, vals.map((v, i) => /*#__PURE__*/React.createElement("div", {
    key: i,
    style: {
      flex: 1,
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      gap: 9
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 10.5,
      color: 'var(--fg3)'
    }
  }, v), /*#__PURE__*/React.createElement("div", {
    style: {
      width: '100%',
      maxWidth: 40,
      height: `${v / max * 104}px`,
      background: 'var(--accent)',
      borderRadius: '6px 6px 0 0',
      opacity: 0.85
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11.5,
      color: 'var(--fg3)'
    }
  }, days[i]))))));
}

/* ── 账户视图 ── */
function TabToggle({
  on,
  onChange
}) {
  return /*#__PURE__*/React.createElement("div", {
    onClick: onChange,
    style: {
      width: 48,
      height: 29,
      borderRadius: 999,
      position: 'relative',
      cursor: 'pointer',
      flexShrink: 0,
      background: on ? 'var(--accent)' : 'var(--border-strong)',
      transition: 'background 220ms var(--ease-out)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'absolute',
      top: 3,
      left: on ? 22 : 3,
      width: 23,
      height: 23,
      borderRadius: '50%',
      background: '#fff',
      boxShadow: 'var(--shadow-sm)',
      transition: 'left 220ms var(--ease-out)'
    }
  }));
}
function TabAccount({
  t,
  tt,
  lang,
  setLang,
  dark,
  setDark,
  free,
  setFree
}) {
  const [smartRoute, setSmartRoute] = useState(true);
  const [kill, setKill] = useState(true);
  const card = {
    background: 'var(--surface)',
    border: '1px solid var(--border)',
    borderRadius: 'var(--radius-lg)',
    boxShadow: 'var(--shadow-sm)',
    overflow: 'hidden',
    marginBottom: 16
  };
  const Row = ({
    icon,
    title,
    sub,
    right,
    last
  }) => /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 13,
      padding: '15px 18px',
      borderBottom: last ? 'none' : '1px solid var(--border)',
      minHeight: 48,
      boxSizing: 'border-box'
    }
  }, icon && /*#__PURE__*/React.createElement("div", {
    style: {
      width: 34,
      height: 34,
      borderRadius: 'var(--radius-sm)',
      background: 'var(--accent-subtle)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: icon,
    size: 17,
    color: "var(--accent)",
    stroke: 2.2
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 15,
      fontWeight: 500,
      color: 'var(--fg1)'
    }
  }, title), sub && /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      color: 'var(--fg3)',
      marginTop: 2
    }
  }, sub)), right);
  const seg = val => ({
    border: 'none',
    cursor: 'pointer',
    padding: '7px 16px',
    borderRadius: 'var(--radius-full)',
    fontFamily: 'var(--font-sans)',
    fontSize: 13,
    fontWeight: 600,
    minHeight: 32,
    background: lang === val ? 'var(--surface)' : 'transparent',
    color: lang === val ? 'var(--fg1)' : 'var(--fg3)',
    boxShadow: lang === val ? 'var(--shadow-sm)' : 'none'
  });
  return /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '6px 28px 24px',
      overflow: 'auto',
      height: '100%',
      boxSizing: 'border-box',
      maxWidth: 640
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      background: free ? 'var(--surface)' : 'linear-gradient(155deg,var(--clay-600),var(--clay-800))',
      border: free ? '1px solid var(--border)' : 'none',
      borderRadius: 'var(--radius-xl)',
      padding: 20,
      color: free ? 'var(--fg1)' : '#fff',
      marginBottom: 18,
      boxShadow: 'var(--shadow-md)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 12
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 46,
      height: 46,
      borderRadius: '50%',
      background: free ? 'var(--bg-subtle)' : 'rgba(255,255,255,0.18)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center'
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: free ? 'user' : 'crown',
    size: 22,
    color: free ? 'var(--fg2)' : '#fff'
  })), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontWeight: 700,
      fontSize: 16.5
    }
  }, "me@pangolin.vpn"), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'inline-block',
      fontSize: 11,
      fontWeight: 600,
      background: free ? 'var(--bg-subtle)' : 'rgba(255,255,255,0.2)',
      color: free ? 'var(--fg2)' : '#fff',
      padding: '2px 9px',
      borderRadius: 999,
      marginTop: 5
    }
  }, free ? tt('freeBanner') : t('proMember')))), /*#__PURE__*/React.createElement("div", {
    style: {
      marginTop: 14,
      paddingTop: 13,
      borderTop: `1px solid ${free ? 'var(--border)' : 'rgba(255,255,255,0.18)'}`,
      fontSize: 12.5,
      opacity: free ? 1 : 0.92,
      color: free ? 'var(--fg2)' : '#fff'
    }
  }, free ? tt('trialNote') : '2026-12-31 · 42.6 GB')), /*#__PURE__*/React.createElement("div", {
    style: card
  }, /*#__PURE__*/React.createElement(Row, {
    icon: "zap",
    title: tt('smartRoute'),
    sub: tt('smartRouteSub'),
    right: /*#__PURE__*/React.createElement(TabToggle, {
      on: smartRoute,
      onChange: () => setSmartRoute(!smartRoute)
    })
  }), /*#__PURE__*/React.createElement(Row, {
    icon: "shield",
    title: tt('killSwitch'),
    sub: tt('killSub'),
    right: /*#__PURE__*/React.createElement(TabToggle, {
      on: kill,
      onChange: () => setKill(!kill)
    }),
    last: true
  })), /*#__PURE__*/React.createElement("div", {
    style: card
  }, /*#__PURE__*/React.createElement(Row, {
    icon: "globe",
    title: tt('language'),
    right: /*#__PURE__*/React.createElement("div", {
      style: {
        display: 'flex',
        gap: 4,
        background: 'var(--bg-subtle)',
        borderRadius: 'var(--radius-full)',
        padding: 3
      }
    }, /*#__PURE__*/React.createElement("button", {
      style: seg('zh'),
      onClick: () => setLang('zh')
    }, "\u4E2D\u6587"), /*#__PURE__*/React.createElement("button", {
      style: seg('en'),
      onClick: () => setLang('en')
    }, "EN"))
  }), /*#__PURE__*/React.createElement(Row, {
    icon: dark ? 'moon' : 'sun',
    title: tt('darkMode'),
    right: /*#__PURE__*/React.createElement(TabToggle, {
      on: dark,
      onChange: () => setDark(!dark)
    })
  }), /*#__PURE__*/React.createElement(Row, {
    icon: "clock",
    title: t('freeDemo'),
    sub: t('freeDemoSub'),
    right: /*#__PURE__*/React.createElement(TabToggle, {
      on: free,
      onChange: () => setFree(!free)
    }),
    last: true
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      textAlign: 'center',
      fontSize: 12,
      color: 'var(--fg3)',
      fontFamily: 'var(--font-mono)'
    }
  }, tt('version')));
}

/* ── iPad 外壳 + 应用 ── */
function TabletApp() {
  const [view, setView] = useState('connect');
  const [status, setStatus] = useState('off');
  const [code, setCode] = useState('AUTO');
  const [lang, setLang] = useState('zh');
  const [dark, setDark] = useState(false);
  const [free, setFree] = useState(true);
  const [mins, setMins] = useState(6);
  const [adDone, setAdDone] = useState(false);
  const [elapsed, setElapsed] = useState(0);
  const timer = useRef(null);
  const t = makeT(lang),
    tt = makeTT(lang);
  const smart = code === 'AUTO';
  const server = smart ? SERVERS.reduce((a, b) => a.ping < b.ping ? a : b) : SERVERS.find(s => s.code === code);
  const titles = {
    connect: tt('navConnect'),
    nodes: tt('navNodes'),
    stats: tt('navStats'),
    account: tt('navAccount')
  };
  function toggle() {
    if (status === 'off') {
      setStatus('connecting');
      setTimeout(() => {
        setStatus('on');
        setElapsed(0);
      }, 1500);
    } else setStatus('off');
  }
  function pick(c) {
    setCode(c);
    setView('connect');
    if (status === 'on') {
      setStatus('connecting');
      setTimeout(() => {
        setStatus('on');
        setElapsed(0);
      }, 1200);
    }
  }
  useEffect(() => {
    if (status === 'on') timer.current = setInterval(() => setElapsed(e => e + 1), 1000);
    return () => clearInterval(timer.current);
  }, [status]);
  let main;
  if (view === 'connect') main = /*#__PURE__*/React.createElement(TabConnect, {
    t: t,
    tt: tt,
    lang: lang,
    status: status,
    onToggle: toggle,
    server: server,
    smart: smart,
    free: free,
    mins: mins,
    adDone: adDone,
    onAd: () => setAdDone(true),
    elapsed: elapsed,
    goNodes: () => setView('nodes')
  });else if (view === 'nodes') main = /*#__PURE__*/React.createElement(TabNodes, {
    t: t,
    tt: tt,
    lang: lang,
    current: code,
    onPick: pick
  });else if (view === 'stats') main = /*#__PURE__*/React.createElement(TabStats, {
    tt: tt,
    lang: lang
  });else main = /*#__PURE__*/React.createElement(TabAccount, {
    t: t,
    tt: tt,
    lang: lang,
    setLang: setLang,
    dark: dark,
    setDark: setDark,
    free: free,
    setFree: setFree
  });
  return /*#__PURE__*/React.createElement("div", {
    style: {
      background: '#1a1714',
      borderRadius: 34,
      padding: 16,
      boxShadow: '0 0 0 1px rgba(0,0,0,0.3), 0 30px 80px rgba(0,0,0,0.45)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    "data-theme": dark ? 'dark' : 'light',
    style: {
      width: 1180,
      height: 820,
      borderRadius: 20,
      overflow: 'hidden',
      background: 'var(--bg)',
      display: 'flex',
      flexDirection: 'column',
      fontFamily: 'var(--font-sans)',
      position: 'relative'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      height: 30,
      flexShrink: 0,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-between',
      padding: '0 22px',
      fontFamily: 'var(--font-sans)',
      fontSize: 12.5,
      fontWeight: 600,
      color: 'var(--fg1)'
    }
  }, /*#__PURE__*/React.createElement("span", null, "9:41"), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 8
    }
  }, /*#__PURE__*/React.createElement(Icon, {
    name: "wifi",
    size: 15,
    stroke: 2.2,
    color: "var(--fg1)"
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 11.5
    }
  }, "87%"), /*#__PURE__*/React.createElement("div", {
    style: {
      width: 24,
      height: 12,
      border: '1.5px solid var(--fg2)',
      borderRadius: 3.5,
      padding: 1.5,
      boxSizing: 'border-box'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: '80%',
      height: '100%',
      background: 'var(--fg1)',
      borderRadius: 1.5
    }
  })))), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      minHeight: 0,
      display: 'flex'
    }
  }, /*#__PURE__*/React.createElement(TabRail, {
    tt: tt,
    view: view,
    setView: setView,
    free: free,
    t: t
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      minWidth: 0,
      display: 'flex',
      flexDirection: 'column'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      height: 56,
      flexShrink: 0,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-between',
      padding: '0 28px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 19,
      color: 'var(--fg1)'
    }
  }, titles[view]), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 12.5,
      fontWeight: 600,
      color: status === 'on' ? 'var(--success)' : 'var(--fg3)',
      whiteSpace: 'nowrap'
    }
  }, status === 'on' ? '● ' + server.code : '○')), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      minHeight: 0
    }
  }, main)))));
}
Object.assign(window, {
  TabletApp
});
})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/tablet/tabapp.jsx", error: String((e && e.message) || e) }); }

// ui_kits/usercenter/ucapp.jsx
try { (() => {
/* ucapp.jsx — 穿山甲 Web 用户中心 · views */
const {
  useState: useStateU
} = React;
const ucCard = {
  background: 'var(--surface)',
  border: '1px solid var(--border)',
  borderRadius: 'var(--radius-xl)',
  boxShadow: 'var(--shadow-sm)'
};
const ucInput = {
  border: '1.5px solid var(--border-strong)',
  borderRadius: 'var(--radius-md)',
  padding: '12px 14px',
  fontFamily: 'var(--font-sans)',
  fontSize: 14.5,
  color: 'var(--fg1)',
  background: 'var(--surface)',
  outline: 'none',
  width: '100%',
  boxSizing: 'border-box'
};

/* viewport hook — mobile ≤ 700px */
function useIsMobileUC() {
  const [m, setM] = useStateU(typeof window !== 'undefined' && window.innerWidth <= 700);
  React.useEffect(() => {
    const f = () => setM(window.innerWidth <= 700);
    window.addEventListener('resize', f);
    return () => window.removeEventListener('resize', f);
  }, []);
  return m;
}
function UCLang({
  lang,
  setLang
}) {
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      background: 'var(--bg-subtle)',
      borderRadius: 999,
      padding: 3,
      gap: 2
    }
  }, [['zh', '中文'], ['en', 'EN']].map(([v, l]) => /*#__PURE__*/React.createElement("button", {
    key: v,
    onClick: () => setLang(v),
    style: {
      border: 'none',
      cursor: 'pointer',
      borderRadius: 999,
      padding: '5px 12px',
      fontFamily: 'var(--font-sans)',
      fontSize: 12.5,
      fontWeight: 700,
      background: lang === v ? 'var(--accent)' : 'transparent',
      color: lang === v ? 'var(--fg-on-accent)' : 'var(--fg3)'
    }
  }, l)));
}

/* ───────── Login (+ PRO 2FA step) ───────── */
function UCLogin({
  t,
  lang,
  setLang,
  onDone
}) {
  const [email, setEmail] = useStateU('');
  const [pw, setPw] = useStateU('');
  const [step, setStep] = useStateU('cred'); // cred | totp
  const [otp, setOtp] = useStateU('');
  const ok = /\S+@\S+\.\S+/.test(email) && pw.length > 0;
  return /*#__PURE__*/React.createElement("div", {
    style: {
      minHeight: '100vh',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      background: 'var(--bg)',
      padding: 24
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      ...ucCard,
      width: 400,
      maxWidth: '100%',
      padding: '36px 34px',
      boxSizing: 'border-box'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-between',
      marginBottom: 26
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 10
    }
  }, /*#__PURE__*/React.createElement(UCMark, {
    size: 32
  }), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 17,
      color: 'var(--fg1)',
      lineHeight: 1
    }
  }, "\u7A7F\u5C71\u7532"), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 8.5,
      fontWeight: 600,
      letterSpacing: '0.2em',
      color: 'var(--accent)',
      marginTop: 3
    }
  }, "PANGOLIN"))), /*#__PURE__*/React.createElement(UCLang, {
    lang: lang,
    setLang: setLang
  })), step === 'cred' ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 22,
      color: 'var(--fg1)'
    }
  }, t('loginTitle')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13.5,
      color: 'var(--fg3)',
      margin: '6px 0 24px'
    }
  }, t('loginSub')), /*#__PURE__*/React.createElement("label", {
    style: {
      display: 'block',
      marginBottom: 14
    }
  }, /*#__PURE__*/React.createElement("span", {
    style: {
      display: 'block',
      fontSize: 12.5,
      fontWeight: 600,
      color: 'var(--fg2)',
      marginBottom: 6
    }
  }, t('emailLabel')), /*#__PURE__*/React.createElement("input", {
    style: ucInput,
    value: email,
    onChange: e => setEmail(e.target.value),
    placeholder: t('emailPh')
  })), /*#__PURE__*/React.createElement("label", {
    style: {
      display: 'block'
    }
  }, /*#__PURE__*/React.createElement("span", {
    style: {
      display: 'block',
      fontSize: 12.5,
      fontWeight: 600,
      color: 'var(--fg2)',
      marginBottom: 6
    }
  }, t('pwLabel')), /*#__PURE__*/React.createElement("input", {
    style: ucInput,
    type: "password",
    value: pw,
    onChange: e => setPw(e.target.value),
    placeholder: t('pwPh')
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      textAlign: 'right',
      margin: '10px 0 18px'
    }
  }, /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 13,
      color: 'var(--accent)',
      fontWeight: 600,
      cursor: 'pointer'
    }
  }, t('forgotPw'))), /*#__PURE__*/React.createElement("button", {
    onClick: ok ? () => setStep('totp') : undefined,
    disabled: !ok,
    style: {
      width: '100%',
      border: 'none',
      borderRadius: 'var(--radius-full)',
      padding: '13px',
      fontFamily: 'var(--font-sans)',
      fontWeight: 700,
      fontSize: 15,
      cursor: ok ? 'pointer' : 'not-allowed',
      background: 'var(--accent)',
      color: 'var(--fg-on-accent)',
      opacity: ok ? 1 : 0.45
    }
  }, t('doLogin')), /*#__PURE__*/React.createElement("div", {
    style: {
      textAlign: 'center',
      fontSize: 12.5,
      color: 'var(--fg3)',
      marginTop: 18
    }
  }, t('noAccount'))) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 9,
      marginBottom: 6
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: "shield-check",
    size: 20,
    color: "var(--accent)"
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 20,
      color: 'var(--fg1)'
    }
  }, t('twoFATitle')), /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 10.5,
      fontWeight: 700,
      color: 'var(--accent)',
      background: 'var(--accent-subtle)',
      border: '1px solid var(--accent-border)',
      padding: '2px 8px',
      borderRadius: 999
    }
  }, "PRO")), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13,
      color: 'var(--fg3)',
      margin: '4px 0 20px',
      lineHeight: 1.6
    }
  }, t('twoFAHint')), /*#__PURE__*/React.createElement("input", {
    value: otp,
    onChange: e => setOtp(e.target.value.replace(/\D/g, '').slice(0, 6)),
    placeholder: "\xB7\xB7\xB7\xB7\xB7\xB7",
    style: {
      ...ucInput,
      fontFamily: 'var(--font-mono)',
      fontSize: 22,
      letterSpacing: '0.5em',
      textAlign: 'center',
      padding: '14px'
    }
  }), /*#__PURE__*/React.createElement("button", {
    onClick: otp.length === 6 ? onDone : undefined,
    disabled: otp.length !== 6,
    style: {
      width: '100%',
      border: 'none',
      borderRadius: 'var(--radius-full)',
      padding: '13px',
      marginTop: 16,
      fontFamily: 'var(--font-sans)',
      fontWeight: 700,
      fontSize: 15,
      cursor: otp.length === 6 ? 'pointer' : 'not-allowed',
      background: 'var(--accent)',
      color: 'var(--fg-on-accent)',
      opacity: otp.length === 6 ? 1 : 0.45
    }
  }, t('twoFAConfirm')), /*#__PURE__*/React.createElement("div", {
    onClick: () => setStep('cred'),
    style: {
      textAlign: 'center',
      fontSize: 12.5,
      color: 'var(--fg3)',
      marginTop: 18,
      cursor: 'pointer'
    }
  }, t('twoFABack')))));
}

/* ───────── Overview ───────── */
function UCOverview({
  t,
  lang,
  free,
  mobile,
  goSub,
  goRedeem
}) {
  const vals = [1.8, 2.4, 1.2, 3.1, 4.0, 5.2, 2.6];
  const max = 5.2;
  const labels = lang === 'zh' ? ['一', '二', '三', '四', '五', '六', '日'] : ['M', 'T', 'W', 'T', 'F', 'S', 'S'];
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      gap: 20
    }
  }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontSize: 25,
      fontWeight: 700,
      color: 'var(--fg1)'
    }
  }, t('greeting')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13.5,
      color: 'var(--fg3)',
      marginTop: 3
    }
  }, "me@pangolin.vpn")), /*#__PURE__*/React.createElement("div", {
    style: {
      ...ucCard,
      background: 'linear-gradient(150deg,var(--clay-600),var(--clay-800))',
      border: 'none',
      color: '#fff',
      padding: '20px 24px',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-between',
      gap: 16,
      flexWrap: 'wrap'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 14
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 46,
      height: 46,
      borderRadius: '50%',
      background: 'rgba(255,255,255,.18)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center'
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: "crown",
    size: 23,
    color: "#fff"
  })), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      opacity: .8
    }
  }, t('curPlan')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontSize: 19,
      fontWeight: 700,
      marginTop: 2
    }
  }, free ? t('freePlan') : t('proMember')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11.5,
      opacity: .8,
      marginTop: 3,
      fontFamily: 'var(--font-mono)',
      whiteSpace: 'nowrap'
    }
  }, free ? t('quotaFree') : `${t('expires')} 2026-12-31`))), /*#__PURE__*/React.createElement("button", {
    onClick: goRedeem,
    style: {
      border: 'none',
      background: '#fff',
      color: 'var(--clay-700)',
      fontWeight: 700,
      fontSize: 13.5,
      padding: '11px 20px',
      borderRadius: 'var(--radius-full)',
      cursor: 'pointer',
      display: 'inline-flex',
      alignItems: 'center',
      gap: 7
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: "ticket",
    size: 15,
    color: "var(--clay-700)"
  }), t('renew'))), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'grid',
      gridTemplateColumns: 'repeat(auto-fit,minmax(160px,1fr))',
      gap: 14
    }
  }, [['clock', t('quotaToday'), free ? '6' : '∞', free ? 'min' : ''], ['arrow-down', t('dataToday'), '0.8', 'GB'], ['smartphone', t('devices'), '2 / 5', '']].map(([ic, l, v, u]) => /*#__PURE__*/React.createElement("div", {
    key: l,
    style: {
      ...ucCard,
      padding: '16px 18px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 7,
      color: 'var(--fg3)',
      fontSize: 12,
      fontWeight: 600
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: ic,
    size: 15,
    color: "var(--accent)"
  }), l), /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 23,
      fontWeight: 500,
      color: 'var(--fg1)',
      marginTop: 7
    }
  }, v, u && /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 12,
      color: 'var(--fg3)'
    }
  }, " ", u))))), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'grid',
      gridTemplateColumns: mobile ? '1fr' : '1.6fr 1fr',
      gap: 14,
      alignItems: 'start'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      ...ucCard,
      padding: '18px 22px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13.5,
      fontWeight: 600,
      color: 'var(--fg1)',
      marginBottom: 16
    }
  }, t('usageTitle')), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'flex-end',
      gap: 14,
      height: 110
    }
  }, vals.map((v, i) => /*#__PURE__*/React.createElement("div", {
    key: i,
    style: {
      flex: 1,
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      gap: 6
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 9.5,
      color: 'var(--fg3)'
    }
  }, v), /*#__PURE__*/React.createElement("div", {
    style: {
      width: '100%',
      maxWidth: 30,
      height: `${v / max * 76}px`,
      background: 'var(--accent)',
      borderRadius: '5px 5px 0 0',
      opacity: .85
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 10.5,
      color: 'var(--fg3)'
    }
  }, labels[i]))))), /*#__PURE__*/React.createElement("div", {
    style: {
      ...ucCard,
      padding: '16px 18px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13.5,
      fontWeight: 600,
      color: 'var(--fg1)',
      marginBottom: 12
    }
  }, t('quickSub')), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      gap: 8
    }
  }, [['link', t('qaSub'), goSub], ['ticket', t('qaRedeem'), goRedeem], ['download', t('qaApp'), null]].map(([ic, l, fn]) => /*#__PURE__*/React.createElement("button", {
    key: l,
    onClick: fn || undefined,
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 11,
      width: '100%',
      textAlign: 'left',
      cursor: 'pointer',
      background: 'var(--bg-subtle)',
      border: '1px solid var(--border)',
      borderRadius: 'var(--radius-md)',
      padding: '11px 13px'
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: ic,
    size: 16,
    color: "var(--accent)"
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      flex: 1,
      fontSize: 13.5,
      fontWeight: 600,
      color: 'var(--fg1)'
    }
  }, l), /*#__PURE__*/React.createElement(UCIcon, {
    name: "chevron-right",
    size: 15,
    color: "var(--fg3)"
  })))))));
}

/* ───────── Subscription ───────── */
function UCSub({
  t,
  lang,
  mobile
}) {
  const [copied, setCopied] = useStateU(false);
  const [reset, setReset] = useStateU(false);
  const url = 'https://sub.pangolin.vpn/s/8f3kx92m' + (reset ? '-new' : '');
  const clients = [{
    name: '穿山甲 App',
    sub: 'iOS / Android / 桌面',
    icon: 'shield-check',
    accent: true
  }, {
    name: 'Shadowrocket',
    sub: 'iOS',
    icon: 'external-link'
  }, {
    name: 'Clash Verge',
    sub: 'Windows / macOS',
    icon: 'external-link'
  }, {
    name: 'v2rayN',
    sub: 'Windows',
    icon: 'external-link'
  }, {
    name: 'sing-box',
    sub: '全平台',
    icon: 'external-link'
  }];
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      gap: 18,
      maxWidth: 720
    }
  }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontSize: 25,
      fontWeight: 700,
      color: 'var(--fg1)'
    }
  }, t('subTitle')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13,
      color: 'var(--fg3)',
      marginTop: 5,
      lineHeight: 1.6
    }
  }, t('subDesc'))), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'grid',
      gridTemplateColumns: mobile ? '1fr' : '1fr auto',
      gap: 14,
      alignItems: 'start'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      ...ucCard,
      padding: '18px 20px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 9,
      background: 'var(--bg-subtle)',
      border: '1px solid var(--border)',
      borderRadius: 'var(--radius-md)',
      padding: '11px 13px',
      marginBottom: 12
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: "link",
    size: 15,
    color: "var(--fg3)"
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      flex: 1,
      fontFamily: 'var(--font-mono)',
      fontSize: 12.5,
      color: 'var(--fg1)',
      overflow: 'hidden',
      textOverflow: 'ellipsis',
      whiteSpace: 'nowrap'
    }
  }, url)), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 10,
      flexWrap: 'wrap'
    }
  }, /*#__PURE__*/React.createElement("button", {
    onClick: () => {
      setCopied(true);
      setTimeout(() => setCopied(false), 1800);
    },
    style: {
      display: 'inline-flex',
      alignItems: 'center',
      gap: 7,
      border: 'none',
      borderRadius: 'var(--radius-full)',
      padding: '10px 18px',
      background: 'var(--accent)',
      color: '#fff',
      fontWeight: 700,
      fontSize: 13.5,
      cursor: 'pointer'
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: copied ? 'check' : 'copy',
    size: 15,
    color: "#fff"
  }), copied ? t('subCopied') : t('subCopy')), /*#__PURE__*/React.createElement("button", {
    onClick: () => setReset(true),
    style: {
      display: 'inline-flex',
      alignItems: 'center',
      gap: 7,
      border: '1.5px solid var(--border-strong)',
      borderRadius: 'var(--radius-full)',
      padding: '10px 18px',
      background: 'transparent',
      color: 'var(--fg2)',
      fontWeight: 600,
      fontSize: 13.5,
      cursor: 'pointer'
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: "refresh-cw",
    size: 14,
    color: "var(--fg2)"
  }), t('subReset'))), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11.5,
      color: reset ? 'var(--success)' : 'var(--fg3)',
      marginTop: 10,
      display: 'flex',
      alignItems: 'center',
      gap: 6
    }
  }, reset && /*#__PURE__*/React.createElement(UCIcon, {
    name: "check-circle",
    size: 13,
    color: "var(--success)"
  }), reset ? t('subResetOk') : t('subResetSub'))), /*#__PURE__*/React.createElement("div", {
    style: {
      ...ucCard,
      padding: '16px',
      width: mobile ? '100%' : 170,
      boxSizing: 'border-box',
      textAlign: 'center'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 138,
      height: 138,
      margin: '0 auto',
      borderRadius: 'var(--radius-md)',
      background: 'var(--bg-subtle)',
      border: '1px dashed var(--border-strong)',
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      justifyContent: 'center',
      gap: 8
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: "qr-code",
    size: 42,
    color: "var(--fg3)",
    stroke: 1.5
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 10.5,
      color: 'var(--fg3)',
      fontWeight: 600
    }
  }, t('scanTitle'))), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 10.5,
      color: 'var(--fg3)',
      marginTop: 10,
      lineHeight: 1.5
    }
  }, t('scanSub')))), /*#__PURE__*/React.createElement("div", {
    style: {
      ...ucCard,
      padding: '18px 20px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 14.5,
      fontWeight: 700,
      color: 'var(--fg1)'
    }
  }, t('importTitle')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12.5,
      color: 'var(--fg3)',
      margin: '4px 0 14px'
    }
  }, t('importSub')), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'grid',
      gridTemplateColumns: 'repeat(auto-fill,minmax(190px,1fr))',
      gap: 10
    }
  }, clients.map(c => /*#__PURE__*/React.createElement("button", {
    key: c.name,
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 11,
      textAlign: 'left',
      cursor: 'pointer',
      background: c.accent ? 'var(--accent-subtle)' : 'var(--surface)',
      border: `1px solid ${c.accent ? 'var(--accent-border)' : 'var(--border)'}`,
      borderRadius: 'var(--radius-lg)',
      padding: '12px 14px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 34,
      height: 34,
      borderRadius: 'var(--radius-md)',
      background: c.accent ? 'var(--accent)' : 'var(--bg-subtle)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: c.icon,
    size: 17,
    color: c.accent ? '#fff' : 'var(--accent)'
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      minWidth: 0
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13.5,
      fontWeight: 600,
      color: 'var(--fg1)',
      whiteSpace: 'nowrap'
    }
  }, c.name), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11,
      color: 'var(--fg3)'
    }
  }, c.sub))))), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11.5,
      color: 'var(--fg3)',
      marginTop: 12
    }
  }, t('fmtNote'))));
}

/* ───────── Redeem ───────── */
function UCRedeem({
  t,
  lang
}) {
  const [code, setCode] = useStateU('');
  const [ok, setOk] = useStateU(false);
  const channels = [{
    icon: 'shopping-bag',
    name: t('chStore'),
    sub: t('chStoreSub'),
    accent: true
  }, {
    icon: 'credit-card',
    name: 'USDT (TRC20)',
    sub: t('chUsdtSub')
  }, {
    icon: 'send',
    name: 'Telegram',
    sub: '@PangolinVPN_bot',
    mono: true
  }, {
    icon: 'message-circle',
    name: 'LINE',
    sub: '@pangolinvpn',
    mono: true
  }, {
    icon: 'mail',
    name: t('chEmail'),
    sub: 'buy@pangolin.vpn',
    mono: true
  }];
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      gap: 18,
      maxWidth: 680
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontSize: 25,
      fontWeight: 700,
      color: 'var(--fg1)'
    }
  }, t('navRedeem')), /*#__PURE__*/React.createElement("div", {
    style: {
      ...ucCard,
      padding: '20px 22px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 14.5,
      fontWeight: 700,
      color: 'var(--fg1)',
      marginBottom: 12
    }
  }, t('redeemTitle')), ok ? /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 9,
      color: 'var(--success)',
      fontWeight: 600,
      fontSize: 15,
      padding: '4px 0'
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: "check-circle",
    size: 19,
    color: "var(--success)"
  }), t('redeemOk')) : /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 10
    }
  }, /*#__PURE__*/React.createElement("input", {
    value: code,
    onChange: e => setCode(e.target.value.toUpperCase()),
    placeholder: t('redeemPh'),
    style: {
      ...ucInput,
      fontFamily: 'var(--font-mono)',
      letterSpacing: '0.08em'
    }
  }), /*#__PURE__*/React.createElement("button", {
    onClick: () => code.length >= 4 && setOk(true),
    style: {
      border: 'none',
      borderRadius: 'var(--radius-md)',
      padding: '0 22px',
      background: 'var(--accent)',
      color: '#fff',
      fontWeight: 700,
      fontSize: 14,
      cursor: 'pointer',
      flexShrink: 0
    }
  }, t('redeemBtn')))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 14.5,
      fontWeight: 700,
      color: 'var(--fg1)',
      marginBottom: 5
    }
  }, t('buyTitle')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12.5,
      color: 'var(--fg3)',
      lineHeight: 1.5,
      marginBottom: 13
    }
  }, t('buySub')), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'grid',
      gridTemplateColumns: 'repeat(auto-fit,minmax(240px,1fr))',
      gap: 11
    }
  }, channels.map(c => /*#__PURE__*/React.createElement("button", {
    key: c.name,
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 12,
      textAlign: 'left',
      cursor: 'pointer',
      background: c.accent ? 'var(--accent-subtle)' : 'var(--surface)',
      border: `1px solid ${c.accent ? 'var(--accent-border)' : 'var(--border)'}`,
      borderRadius: 'var(--radius-lg)',
      padding: '13px 15px',
      boxShadow: 'var(--shadow-sm)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      width: 38,
      height: 38,
      borderRadius: 'var(--radius-md)',
      background: c.accent ? 'var(--accent)' : 'var(--bg-subtle)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: c.icon,
    size: 18,
    color: c.accent ? '#fff' : 'var(--accent)'
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      minWidth: 0
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 14,
      fontWeight: 600,
      color: 'var(--fg1)'
    }
  }, c.name), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 11.5,
      color: 'var(--fg3)',
      fontFamily: c.mono ? 'var(--font-mono)' : 'var(--font-sans)',
      whiteSpace: 'nowrap',
      overflow: 'hidden',
      textOverflow: 'ellipsis'
    }
  }, c.sub)), /*#__PURE__*/React.createElement(UCIcon, {
    name: "external-link",
    size: 15,
    color: "var(--fg3)"
  }))))));
}

/* ───────── Invite ───────── */
function UCInvite({
  t,
  lang
}) {
  const [copied, setCopied] = useStateU(false);
  const records = [{
    mail: 'k***@gmail.com',
    date: '2026-06-08',
    paid: true
  }, {
    mail: 'w***@outlook.com',
    date: '2026-06-05',
    paid: false
  }, {
    mail: 'z***@qq.com',
    date: '2026-05-30',
    paid: true
  }];
  return /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      flexDirection: 'column',
      gap: 18,
      maxWidth: 680
    }
  }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-display)',
      fontSize: 25,
      fontWeight: 700,
      color: 'var(--fg1)'
    }
  }, t('inviteTitle')), /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 13,
      color: 'var(--fg3)',
      marginTop: 5,
      lineHeight: 1.6
    }
  }, t('inviteSub'))), /*#__PURE__*/React.createElement("div", {
    style: {
      ...ucCard,
      padding: '18px 20px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12.5,
      fontWeight: 600,
      color: 'var(--fg2)',
      marginBottom: 8
    }
  }, t('inviteLink')), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      gap: 10
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      display: 'flex',
      alignItems: 'center',
      gap: 9,
      background: 'var(--bg-subtle)',
      border: '1px solid var(--border)',
      borderRadius: 'var(--radius-md)',
      padding: '11px 13px',
      minWidth: 0
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: "gift",
    size: 15,
    color: "var(--fg3)"
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 12.5,
      color: 'var(--fg1)',
      overflow: 'hidden',
      textOverflow: 'ellipsis',
      whiteSpace: 'nowrap'
    }
  }, "https://pangolin.vpn/r/PG8F3K")), /*#__PURE__*/React.createElement("button", {
    onClick: () => {
      setCopied(true);
      setTimeout(() => setCopied(false), 1800);
    },
    style: {
      display: 'inline-flex',
      alignItems: 'center',
      gap: 7,
      border: 'none',
      borderRadius: 'var(--radius-md)',
      padding: '0 18px',
      background: 'var(--accent)',
      color: '#fff',
      fontWeight: 700,
      fontSize: 13.5,
      cursor: 'pointer',
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: copied ? 'check' : 'copy',
    size: 15,
    color: "#fff"
  }), copied ? t('subCopied') : t('subCopy')))), /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'grid',
      gridTemplateColumns: 'repeat(auto-fit,minmax(150px,1fr))',
      gap: 14
    }
  }, [[t('invited'), '8', ''], [t('paidUsers'), '3', ''], [t('earned'), '¥45', '']].map(([l, v]) => /*#__PURE__*/React.createElement("div", {
    key: l,
    style: {
      ...ucCard,
      padding: '16px 18px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      fontSize: 12,
      color: 'var(--fg3)',
      fontWeight: 600
    }
  }, l), /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 23,
      fontWeight: 500,
      color: 'var(--fg1)',
      marginTop: 7
    }
  }, v)))), /*#__PURE__*/React.createElement("div", {
    style: {
      ...ucCard,
      overflow: 'hidden'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      padding: '13px 18px',
      fontSize: 13.5,
      fontWeight: 700,
      color: 'var(--fg1)',
      borderBottom: '1px solid var(--border)'
    }
  }, t('inviteRecord')), records.map((r, i) => /*#__PURE__*/React.createElement("div", {
    key: i,
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 12,
      padding: '12px 18px',
      borderBottom: i < records.length - 1 ? '1px solid var(--border)' : 'none'
    }
  }, /*#__PURE__*/React.createElement("span", {
    style: {
      flex: 1,
      fontFamily: 'var(--font-mono)',
      fontSize: 13,
      color: 'var(--fg1)'
    }
  }, r.mail), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-mono)',
      fontSize: 12,
      color: 'var(--fg3)'
    }
  }, r.date), /*#__PURE__*/React.createElement("span", {
    style: {
      fontSize: 11,
      fontWeight: 600,
      padding: '3px 10px',
      borderRadius: 999,
      background: r.paid ? 'var(--success-subtle)' : 'var(--bg-subtle)',
      color: r.paid ? 'var(--success)' : 'var(--fg3)'
    }
  }, r.paid ? t('recPaid') : t('recRegistered'))))));
}

/* ───────── App shell ───────── */
function UserCenterApp() {
  const [stage, setStage] = useStateU('app'); // app | login — opens on the dashboard
  const [view, setView] = useStateU('overview');
  const [lang, setLang] = useStateU('zh');
  const [free] = useStateU(false);
  const [dir, setDir] = useStateU(0); // -1 左进 / 1 右进 / 0 无动画
  const mobile = useIsMobileUC();
  const t = ucT(lang);
  const touchRef = React.useRef({
    x: 0,
    y: 0
  });
  const ORDER = ['overview', 'sub', 'redeem', 'invite'];
  function go(id) {
    const a = ORDER.indexOf(view),
      b = ORDER.indexOf(id);
    setDir(b > a ? 1 : b < a ? -1 : 0);
    setView(id);
    setTimeout(() => setDir(0), 300);
  }
  function onTouchStart(e) {
    const p = e.touches ? e.touches[0] : e;
    touchRef.current = {
      x: p.clientX,
      y: p.clientY
    };
  }
  function onTouchEnd(e) {
    const p = e.changedTouches ? e.changedTouches[0] : e;
    const dx = p.clientX - touchRef.current.x,
      dy = p.clientY - touchRef.current.y;
    if (Math.abs(dx) > 60 && Math.abs(dx) > Math.abs(dy) * 1.5) {
      const i = ORDER.indexOf(view);
      const ni = dx < 0 ? Math.min(ORDER.length - 1, i + 1) : Math.max(0, i - 1);
      if (ni !== i) go(ORDER[ni]);
    }
  }
  if (stage === 'login') return /*#__PURE__*/React.createElement(UCLogin, {
    t: t,
    lang: lang,
    setLang: setLang,
    onDone: () => setStage('app')
  });
  const nav = [['overview', 'layout-dashboard', t('navOverview')], ['sub', 'link', t('navSub')], ['redeem', 'ticket', t('navRedeem')], ['invite', 'users', t('navInvite')]];
  let main;
  if (view === 'overview') main = /*#__PURE__*/React.createElement(UCOverview, {
    t: t,
    lang: lang,
    free: free,
    mobile: mobile,
    goSub: () => setView('sub'),
    goRedeem: () => setView('redeem')
  });else if (view === 'sub') main = /*#__PURE__*/React.createElement(UCSub, {
    t: t,
    lang: lang,
    mobile: mobile
  });else if (view === 'redeem') main = /*#__PURE__*/React.createElement(UCRedeem, {
    t: t,
    lang: lang
  });else main = /*#__PURE__*/React.createElement(UCInvite, {
    t: t,
    lang: lang
  });
  const navBtns = nav.map(([id, ic, l]) => /*#__PURE__*/React.createElement("button", {
    key: id,
    onClick: () => go(id),
    style: {
      display: 'inline-flex',
      alignItems: 'center',
      gap: 7,
      border: 'none',
      cursor: 'pointer',
      borderRadius: 'var(--radius-md)',
      padding: '8px 13px',
      flexShrink: 0,
      background: view === id ? 'var(--accent-subtle)' : 'transparent',
      color: view === id ? 'var(--accent)' : 'var(--fg2)',
      fontFamily: 'var(--font-sans)',
      fontSize: 13.5,
      fontWeight: view === id ? 700 : 500,
      whiteSpace: 'nowrap'
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: ic,
    size: 15,
    color: view === id ? 'var(--accent)' : 'var(--fg3)'
  }), l));
  return /*#__PURE__*/React.createElement("div", {
    style: {
      minHeight: '100vh',
      background: 'var(--bg)',
      fontFamily: 'var(--font-sans)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      position: 'sticky',
      top: 0,
      zIndex: 10,
      background: 'color-mix(in srgb, var(--bg) 85%, transparent)',
      backdropFilter: 'blur(12px)',
      borderBottom: '1px solid var(--border)'
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      maxWidth: 1000,
      margin: '0 auto',
      padding: mobile ? '0 16px' : '0 24px',
      height: mobile ? 54 : 60,
      display: 'flex',
      alignItems: 'center',
      gap: mobile ? 12 : 22
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: 'flex',
      alignItems: 'center',
      gap: 9
    }
  }, /*#__PURE__*/React.createElement(UCMark, {
    size: 26
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: 'var(--font-display)',
      fontWeight: 700,
      fontSize: 16.5,
      color: 'var(--fg1)'
    }
  }, "\u7A7F\u5C71\u7532")), !mobile && /*#__PURE__*/React.createElement("nav", {
    style: {
      display: 'flex',
      gap: 4,
      flex: 1
    }
  }, navBtns), mobile && /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1
    }
  }), /*#__PURE__*/React.createElement(UCLang, {
    lang: lang,
    setLang: setLang
  }), /*#__PURE__*/React.createElement("button", {
    onClick: () => setStage('login'),
    style: {
      display: 'inline-flex',
      alignItems: 'center',
      gap: 7,
      border: 'none',
      background: 'transparent',
      cursor: 'pointer',
      color: 'var(--fg2)',
      fontSize: 13,
      fontWeight: 600,
      padding: 6
    }
  }, /*#__PURE__*/React.createElement(UCIcon, {
    name: "log-out",
    size: 15,
    color: "var(--fg3)"
  }), !mobile && t('signOut'))), mobile && /*#__PURE__*/React.createElement("nav", {
    style: {
      display: 'flex',
      gap: 2,
      padding: '0 12px 8px',
      overflowX: 'auto'
    }
  }, navBtns)), /*#__PURE__*/React.createElement("div", {
    onTouchStart: mobile ? onTouchStart : undefined,
    onTouchEnd: mobile ? onTouchEnd : undefined,
    style: {
      maxWidth: 1000,
      margin: '0 auto',
      padding: mobile ? '20px 16px 40px' : '30px 24px 48px'
    }
  }, /*#__PURE__*/React.createElement("div", {
    key: view,
    onAnimationEnd: () => setDir(0),
    style: {
      animation: dir !== 0 ? `uc-in-${dir === 1 ? 'l' : 'r'} 200ms var(--ease-out)` : 'none'
    }
  }, main)));
}
Object.assign(window, {
  UserCenterApp
});
})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/usercenter/ucapp.jsx", error: String((e && e.message) || e) }); }

// ui_kits/usercenter/ucparts.jsx
try { (() => {
/* ucparts.jsx — 穿山甲 Web 用户中心 · atoms + i18n */
const UCLUCIDE = {
  'layout-dashboard': '<rect width="7" height="9" x="3" y="3" rx="1"/><rect width="7" height="5" x="14" y="3" rx="1"/><rect width="7" height="9" x="14" y="12" rx="1"/><rect width="7" height="5" x="3" y="16" rx="1"/>',
  link: '<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>',
  ticket: '<path d="M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z"/><path d="M13 5v2"/><path d="M13 17v2"/><path d="M13 11v2"/>',
  users: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
  copy: '<rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/>',
  'refresh-cw': '<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M3 21v-5h5"/>',
  'qr-code': '<rect width="5" height="5" x="3" y="3" rx="1"/><rect width="5" height="5" x="16" y="3" rx="1"/><rect width="5" height="5" x="3" y="16" rx="1"/><path d="M21 16h-3a2 2 0 0 0-2 2v3"/><path d="M21 21v.01"/><path d="M12 7v3a2 2 0 0 1-2 2H7"/><path d="M3 12h.01"/><path d="M12 3h.01"/><path d="M12 16v.01"/><path d="M16 12h1"/><path d="M21 12v.01"/><path d="M12 21v-1"/>',
  download: '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/>',
  check: '<path d="M20 6 9 17l-5-5"/>',
  'check-circle': '<path d="M21.801 10A10 10 0 1 1 17 3.335"/><path d="m9 11 3 3L22 4"/>',
  zap: '<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>',
  clock: '<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>',
  'shield-check': '<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/>',
  crown: '<path d="M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z"/><path d="M5 21h14"/>',
  'credit-card': '<rect width="20" height="14" x="2" y="5" rx="2"/><line x1="2" x2="22" y1="10" y2="10"/>',
  send: '<path d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"/><path d="m21.854 2.147-10.94 10.939"/>',
  'message-circle': '<path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/>',
  mail: '<rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>',
  'shopping-bag': '<path d="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z"/><path d="M3 6h18"/><path d="M16 10a4 4 0 0 1-8 0"/>',
  'log-out': '<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/>',
  'external-link': '<path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>',
  gift: '<rect x="3" y="8" width="18" height="4" rx="1"/><path d="M12 8v13"/><path d="M19 12v7a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-7"/><path d="M7.5 8a2.5 2.5 0 0 1 0-5A4.8 8 0 0 1 12 8a4.8 8 0 0 1 4.5-5 2.5 2.5 0 0 1 0 5"/>',
  smartphone: '<rect width="14" height="20" x="5" y="2" rx="2" ry="2"/><path d="M12 18h.01"/>',
  lock: '<rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>',
  'chevron-right': '<path d="m9 18 6-6-6-6"/>',
  'arrow-down': '<path d="M12 5v14"/><path d="m19 12-7 7-7-7"/>'
};
function UCIcon({
  name,
  size = 18,
  stroke = 2,
  color = 'currentColor',
  style = {}
}) {
  return /*#__PURE__*/React.createElement("svg", {
    width: size,
    height: size,
    viewBox: "0 0 24 24",
    fill: "none",
    stroke: color,
    strokeWidth: stroke,
    strokeLinecap: "round",
    strokeLinejoin: "round",
    style: {
      display: 'block',
      flexShrink: 0,
      ...style
    },
    dangerouslySetInnerHTML: {
      __html: UCLUCIDE[name] || ''
    }
  });
}
function UCMark({
  size = 30,
  color = 'var(--accent)'
}) {
  return /*#__PURE__*/React.createElement("svg", {
    width: size,
    height: size,
    viewBox: "0 0 96 96",
    fill: "none",
    style: {
      display: 'block'
    }
  }, /*#__PURE__*/React.createElement("g", {
    transform: "translate(96,0) scale(-1,1)"
  }, /*#__PURE__*/React.createElement("path", {
    d: "M16 59 Q17 51 26 50 Q34 31 45 30 Q55 30 62 37 Q69 41 75 45 Q85 49 89 44 Q92 50 84 52 Q75 53 67 53 Q66 62 60 62 L56 62 Q54 55 49 55 Q47 62 37 62 L33 62 Q31 56 26 56 Q20 59 16 59 Z",
    fill: color
  }), /*#__PURE__*/React.createElement("g", {
    stroke: "#fff",
    strokeWidth: "2.4",
    strokeLinecap: "round",
    strokeLinejoin: "round",
    fill: "none",
    opacity: "0.5"
  }, /*#__PURE__*/React.createElement("path", {
    d: "M27 50 Q35 43 43 50"
  }), /*#__PURE__*/React.createElement("path", {
    d: "M37 48 Q45 41 53 48"
  }), /*#__PURE__*/React.createElement("path", {
    d: "M47 48 Q55 41 63 49"
  })), /*#__PURE__*/React.createElement("circle", {
    cx: "19",
    cy: "56",
    r: "2.2",
    fill: "#fff",
    opacity: "0.85"
  })));
}
const UCSTRINGS = {
  navOverview: {
    zh: '概览',
    en: 'Overview'
  },
  navSub: {
    zh: '订阅',
    en: 'Subscription'
  },
  navRedeem: {
    zh: '兑换 & 购买',
    en: 'Redeem & buy'
  },
  navInvite: {
    zh: '邀请返利',
    en: 'Referral'
  },
  signOut: {
    zh: '退出',
    en: 'Sign out'
  },
  /* login */
  loginTitle: {
    zh: '登录用户中心',
    en: 'Log in to your account'
  },
  loginSub: {
    zh: '管理订阅、兑换激活码、查看用量',
    en: 'Manage subscription, redeem codes, track usage'
  },
  emailLabel: {
    zh: '邮箱',
    en: 'Email'
  },
  emailPh: {
    zh: '你的邮箱地址',
    en: 'your@email.com'
  },
  pwLabel: {
    zh: '密码',
    en: 'Password'
  },
  pwPh: {
    zh: '输入密码',
    en: 'Enter password'
  },
  doLogin: {
    zh: '登录',
    en: 'Log in'
  },
  forgotPw: {
    zh: '忘记密码?',
    en: 'Forgot password?'
  },
  noAccount: {
    zh: '没有账户?在 App 内注册',
    en: 'No account? Sign up in the app'
  },
  /* overview */
  greeting: {
    zh: '欢迎回来',
    en: 'Welcome back'
  },
  curPlan: {
    zh: '当前套餐',
    en: 'Current plan'
  },
  freePlan: {
    zh: '免费版',
    en: 'Free'
  },
  proMember: {
    zh: 'PRO 会员',
    en: 'PRO member'
  },
  expires: {
    zh: '有效期至',
    en: 'Expires'
  },
  renew: {
    zh: '续费 / 升级',
    en: 'Renew / Upgrade'
  },
  quotaToday: {
    zh: '今日剩余时长',
    en: 'Time left today'
  },
  dataToday: {
    zh: '今日已用流量',
    en: 'Data used today'
  },
  devices: {
    zh: '在线设备',
    en: 'Devices online'
  },
  quotaFree: {
    zh: '免费版 · 每日 10 分钟',
    en: 'Free · 10 min/day'
  },
  usageTitle: {
    zh: '近 7 日流量 (GB)',
    en: 'Last 7 days (GB)'
  },
  quickSub: {
    zh: '快速操作',
    en: 'Quick actions'
  },
  qaSub: {
    zh: '获取订阅链接',
    en: 'Get subscription'
  },
  qaRedeem: {
    zh: '兑换激活码',
    en: 'Redeem a code'
  },
  qaApp: {
    zh: '下载 App',
    en: 'Download apps'
  },
  /* subscription */
  subTitle: {
    zh: '我的订阅',
    en: 'My subscription'
  },
  subDesc: {
    zh: '订阅链接是你的专属凭证,泄露后他人可使用你的额度。请勿分享。',
    en: 'Your subscription link is a private credential. Never share it.'
  },
  subCopy: {
    zh: '复制链接',
    en: 'Copy link'
  },
  subCopied: {
    zh: '已复制',
    en: 'Copied'
  },
  subReset: {
    zh: '重置链接',
    en: 'Reset link'
  },
  subResetSub: {
    zh: '旧链接立即失效,所有设备需重新导入',
    en: 'Old link stops working; re-import on all devices'
  },
  subResetOk: {
    zh: '已重置,请重新导入',
    en: 'Reset — re-import on your devices'
  },
  scanTitle: {
    zh: '扫码导入',
    en: 'Scan to import'
  },
  scanSub: {
    zh: '用穿山甲 App 或三方客户端扫码',
    en: 'Scan with the Pangolin app or a 3rd-party client'
  },
  importTitle: {
    zh: '一键导入三方客户端',
    en: 'One-tap import'
  },
  importSub: {
    zh: '已安装对应客户端时,点击即自动导入订阅。',
    en: 'If the client is installed, tapping imports the subscription automatically.'
  },
  fmtNote: {
    zh: '同一链接同时兼容 sing-box / Clash.Meta / v2ray 格式。',
    en: 'One link serves sing-box / Clash.Meta / v2ray formats.'
  },
  /* redeem */
  redeemTitle: {
    zh: '兑换激活码',
    en: 'Redeem a code'
  },
  redeemPh: {
    zh: '输入激活码',
    en: 'Enter activation code'
  },
  redeemBtn: {
    zh: '激活',
    en: 'Redeem'
  },
  redeemOk: {
    zh: '激活成功 · 套餐已到账',
    en: 'Activated — plan applied'
  },
  buyTitle: {
    zh: '购买渠道',
    en: 'Where to buy'
  },
  buySub: {
    zh: '本站不直接收款。通过以下渠道购买激活码,回到本页兑换即可:',
    en: 'We never take payment on this site. Buy a code via a channel below, then redeem here:'
  },
  chStore: {
    zh: '自助发卡商店',
    en: 'Self-serve store'
  },
  chStoreSub: {
    zh: '支付宝 / 微信 · 自动发码',
    en: 'Alipay / WeChat · instant code'
  },
  chUsdtSub: {
    zh: '链上转账 · 最隐私 · 自动发码',
    en: 'On-chain · most private · instant code'
  },
  chEmail: {
    zh: '邮箱客服',
    en: 'Email support'
  },
  /* invite */
  inviteTitle: {
    zh: '邀请返利',
    en: 'Referral'
  },
  inviteSub: {
    zh: '好友通过你的链接注册并付费,你获得其首单 20% 余额返利,可抵扣续费。',
    en: 'When a friend signs up and pays via your link, you earn 20% of their first order as credit.'
  },
  inviteLink: {
    zh: '我的邀请链接',
    en: 'My invite link'
  },
  invited: {
    zh: '已邀请',
    en: 'Invited'
  },
  paidUsers: {
    zh: '已付费',
    en: 'Converted'
  },
  earned: {
    zh: '累计返利',
    en: 'Credit earned'
  },
  inviteRecord: {
    zh: '邀请记录',
    en: 'History'
  },
  recEmpty: {
    zh: '暂无邀请记录',
    en: 'No referrals yet'
  },
  recRegistered: {
    zh: '已注册',
    en: 'Registered'
  },
  recPaid: {
    zh: '已付费',
    en: 'Paid'
  },
  /* 2FA */
  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'
  }
};
function ucT(lang) {
  return k => {
    const v = UCSTRINGS[k];
    return v ? v[lang] || k : k;
  };
}
Object.assign(window, {
  UCIcon,
  UCMark,
  UCSTRINGS,
  ucT
});
})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/usercenter/ucparts.jsx", error: String((e && e.message) || e) }); }

// ui_kits/website/site.js
try { (() => {
/* site.js — 穿山甲 VPN 官网 · i18n + 交互 */
(function () {
  // ---------- i18n ----------
  const I18N = {
    'ann.txt': ['新用户注册即享 7 天免费试用', 'New users get a 7-day free trial'],
    'ann.cta': ['立即注册 →', 'Sign up →'],
    'su.ph': ['输入邮箱,免费注册', 'Enter email to sign up free'],
    'su.btn': ['免费注册', 'Sign up free'],
    'su.ok': ['验证码已发送!下载 App 并用同一邮箱继续完成注册。', 'Code sent! Download the app and continue with the same email.'],
    'su.hint': ['免费注册 · 无需付款 · 7 天免费试用', 'Free to join · no payment · 7-day free trial'],
    'su.dl': ['或直接下载 App', 'or just download the app'],
    'why.eyebrow': ['免费注册', 'Sign up'],
    'why.h': ['注册一次,处处可用', 'One account, everywhere'],
    'why.sub': ['一个邮箱就能开始。注册免费,不需要任何付款信息。', 'All you need is an email. Free to join — no payment details, ever.'],
    'why.1t': ['7 天免费试用', '7-day free trial'],
    'why.1d': ['新用户注册即享 7 天免费使用,无需任何付款信息。', 'New accounts get 7 days of free, unrestricted use — no payment details.'],
    'why.2t': ['多端同步', 'Multi-device sync'],
    'why.2d': ['手机、平板、电脑共用一个账户,套餐与设置随身走。', 'Phone, tablet and desktop share one account — your plan follows you.'],
    'why.3t': ['无需付款信息', 'No payment details'],
    'why.3d': ['注册只要邮箱。想升级时,再通过外部渠道兑换激活码。', 'Just an email to join. Upgrade later with an activation code.'],
    'why.s1': ['填写邮箱', 'Enter email'],
    'why.s2': ['输入验证码', 'Verify code'],
    'why.s3': ['开始畅连', 'Start connecting'],
    'why.cta': ['立即免费注册', 'Sign up free'],
    'cta.btn2': ['免费注册', 'Sign up free'],
    'nav.product': ['产品', 'Product'],
    'nav.pricing': ['定价', 'Pricing'],
    'nav.download': ['下载', 'Download'],
    'nav.docs': ['文档', 'Docs'],
    'nav.blog': ['Blog', 'Blog'],
    'nav.login': ['登录', 'Log in'],
    'nav.get': ['立即下载', 'Get the app'],
    'hero.eyebrow': ['极速 · 稳定 · 省心', 'Fast · Stable · Effortless'],
    'hero.h1': ['极速畅连,\n网络如丝顺滑', 'Faster, smoother,\neverywhere'],
    'hero.lede': ['轻盈、亲和、即开即用的跨平台网络加速应用。一键连接,智能选线,稳定不掉线。', 'A lightweight, friendly cross-platform network accelerator. One tap, smart routing, rock-solid.'],
    'hero.cta1': ['免费下载', 'Download free'],
    'hero.cta2': ['查看定价', 'See pricing'],
    'hero.t1': ['80+ 全球加速线路', '80+ global routes'],
    'hero.t2': ['严格无日志', 'Strict no-logs'],
    'hero.t3': ['端到端加密', 'End-to-end encrypted'],
    'orb.cap': ['已连接', 'CONNECTED'],
    'orb.down': ['下载', 'Down'],
    'orb.up': ['上传', 'Up'],
    'orb.node': ['香港 · 流媒体', 'Hong Kong'],
    'orb.nodesub': ['延迟 18ms · 已连接', '18ms · Connected'],
    'strip.txt': ['已支持', 'Available on'],
    'feat.eyebrow': ['产品', 'Product'],
    'feat.h': ['为日常而生的连接体验', 'Built for everyday connection'],
    'feat.sub': ['没有复杂配置,没有技术门槛。打开就用,把稳定与隐私留给我们。', 'No complex setup, no jargon. Just open and go — we handle speed and privacy.'],
    'feat.1t': ['一键连接', 'One-tap connect'],
    'feat.1d': ['一颗按钮,智能挑选最快线路。无需手动配置,也能秒连。', 'One button picks the fastest route. No manual setup, instant connect.'],
    'feat.2t': ['智能分流', 'Smart routing'],
    'feat.2d': ['按规则智能分流,该加速的加速,本地服务直连,互不打扰。', 'Smart rule-based routing — accelerate what needs it, keep local traffic direct.'],
    'feat.3t': ['80+ 全球加速线路', '80+ global routes'],
    'feat.3d': ['覆盖港日新美欧韩等地,视频与游戏优化线路随心选。', 'Routes across HK / JP / SG / US / EU and more, tuned for video & gaming.'],
    'feat.4t': ['严格无日志', 'Strict no-logs'],
    'feat.4d': ['我们不记录你的浏览数据。隐私是底线,不是卖点。', 'We never log your browsing. Privacy is the baseline, not a feature.'],
    'feat.5t': ['Kill Switch', 'Kill Switch'],
    'feat.5d': ['一旦连接中断,立即阻断网络,杜绝真实 IP 泄露。', 'If the tunnel drops, traffic is blocked instantly — no IP leaks.'],
    'feat.6t': ['多端同步', 'Multi-device'],
    'feat.6d': ['一个账户,手机、平板、电脑同时在线,最多 5 台设备。', 'One account across phone, tablet and desktop — up to 5 devices.'],
    'price.eyebrow': ['定价', 'Pricing'],
    'price.h': ['简单透明的价格', 'Simple, honest pricing'],
    'price.sub': ['随时升级或取消。所有套餐均含核心加密与无日志承诺。', 'Upgrade or cancel anytime. Every plan includes core encryption and our no-logs promise.'],
    'price.monthly': ['按月', 'Monthly'],
    'price.yearly': ['按年', 'Yearly'],
    'price.save': ['省 20%', 'Save 20%'],
    'price.permo': ['/月', '/mo'],
    'price.free': ['免费版', 'Free'],
    'price.freedesc': ['适合轻度使用与尝鲜', 'For light, casual use'],
    'price.pro': ['专业版', 'Pro'],
    'price.prodesc': ['个人用户的最佳选择', 'Best for individuals'],
    'price.team': ['团队版', 'Team'],
    'price.teamdesc': ['小团队集中管理', 'For small teams'],
    'price.popular': ['最受欢迎', 'Most popular'],
    'price.cta_free': ['免费下载', 'Download free'],
    'price.cta_pro': ['获取激活码', 'Get a code'],
    'price.cta_team': ['获取激活码', 'Get a code'],
    'pf.free1': ['每日 10 分钟时长', '10 min per day'],
    'pf.free2': ['仅 1 个基础节点', '1 basic node only'],
    'pf.free3': ['使用前观看广告', 'Watch an ad to start'],
    'pf.free4': ['核心加密 · 无日志', 'Core encryption · no-logs'],
    'pf.pro1': ['80+ 全球加速线路', '80+ global routes'],
    'pf.pro2': ['无限流量 · 极速', 'Unlimited · top speed'],
    'pf.pro3': ['5 台设备同时在线', '5 devices at once'],
    'pf.pro4': ['流媒体 & P2P 优化', 'Streaming & P2P routes'],
    'pf.pro5': ['Kill Switch · 智能分流', 'Kill Switch · smart routing'],
    'pf.team1': ['专业版全部功能', 'Everything in Pro'],
    'pf.team2': ['10 个成员席位', '10 seats'],
    'pf.team3': ['集中计费与管理', 'Central billing & admin'],
    'pf.team4': ['优先客服', 'Priority support'],
    'pay.title': ['为什么网页上没有支付按钮?', 'Why no checkout on this page?'],
    'pay.body': ['出于风控与隐私考虑,穿山甲不在网页或 App 内直接收款。你可以通过以下任一渠道获取激活码,在客户端内兑换即可开通。', 'For risk and privacy reasons, Pangolin never takes payment in the web or app. Get an activation code through any channel below, then redeem it in the client.'],
    'pay.store': ['自助发卡商店', 'Self-serve store'],
    'pay.usdt': ['USDT (TRC20) · 最隐私', 'USDT (TRC20) · most private'],
    'cmp.h': ['功能对比', 'Compare plans'],
    'cmp.feature': ['功能', 'Feature'],
    'cmp.locations': ['可用线路', 'Routes'],
    'cmp.data': ['流量', 'Data'],
    'cmp.time': ['每日时长', 'Daily time'],
    'cmp.time_free': ['10 分钟/天(试用期不限)', '10 min/day (trial: unlimited)'],
    'cmp.devices': ['设备数', 'Devices'],
    'cmp.speed': ['极速线路', 'Top-speed routes'],
    'cmp.stream': ['视频优化', 'Video routes'],
    'cmp.kill': ['Kill Switch', 'Kill Switch'],
    'cmp.support': ['客服', 'Support'],
    'cmp.unlimited': ['无限', 'Unlimited'],
    'cmp.daily': ['不限', 'Unlimited'],
    'cmp.basic': ['标准', 'Standard'],
    'cmp.priority': ['优先', 'Priority'],
    'dl.eyebrow': ['下载', 'Download'],
    'dl.h': ['全平台,随处可用', 'Every platform, everywhere'],
    'dl.sub': ['一个账户,所有设备同步。下载即用,无需配置。', 'One account syncs every device. Download and go.'],
    'dl.get': ['下载', 'Download'],
    'docs.eyebrow': ['文档', 'Docs'],
    'docs.h': ['需要帮助?都在这里', 'Need help? It’s all here'],
    'docs.sub': ['从快速上手到协议细节,清晰直接。', 'From quickstart to protocol details — clear and direct.'],
    'docs.1t': ['快速开始', 'Quickstart'],
    'docs.1d': ['三分钟完成注册、下载与首次连接。', 'Sign up, download and connect in three minutes.'],
    'docs.2t': ['常见问题', 'FAQ'],
    'docs.2d': ['连接、计费、设备与兑换码的常见疑问。', 'Connection, billing, devices and redeem codes.'],
    'docs.3t': ['协议与安全', 'Protocol & security'],
    'docs.3d': ['WireGuard、加密方式与无日志架构说明。', 'WireGuard, encryption and our no-logs architecture.'],
    'docs.4t': ['隐私政策', 'Privacy policy'],
    'docs.4d': ['我们收集什么、不收集什么,一目了然。', 'Exactly what we collect — and what we never do.'],
    'docs.read': ['阅读', 'Read'],
    'blog.eyebrow': ['Blog', 'Blog'],
    'blog.h': ['来自团队的最新动态', 'Latest from the team'],
    'blog.sub': ['产品更新、安全科普与节点公告。', 'Product updates, security explainers and node news.'],
    'blog.1tag': ['产品更新', 'Product'],
    'blog.1t': ['v2.4:更快的智能分流与全新统计页', 'v2.4: faster smart routing & a new stats tab'],
    'blog.1d': ['本次更新重写了分流引擎,连接建立速度提升约 40%。', 'We rewrote the routing engine — connections are ~40% faster.'],
    'blog.2tag': ['安全', 'Security'],
    'blog.2t': ['无日志到底意味着什么?', 'What “no-logs” really means'],
    'blog.2d': ['我们逐条拆解收集与不收集的数据,以及背后的架构。', 'A line-by-line look at what we keep — and what we never touch.'],
    'blog.3tag': ['公告', 'News'],
    'blog.3t': ['新增首尔与法兰克福高速节点', 'New high-speed nodes: Seoul & Frankfurt'],
    'blog.3d': ['两条新线路已上线,为东北亚与欧洲用户带来更低延迟。', 'Two new routes are live, cutting latency for NE Asia and Europe.'],
    'blog.readmore': ['阅读全文', 'Read more'],
    'cta.h': ['准备好体验极速畅连了吗?', 'Ready for a faster connection?'],
    'cta.p': ['免费下载,数分钟内开始你的第一次极速连接。', 'Download free and get connected in minutes.'],
    'cta.btn': ['免费下载', 'Download free'],
    'ft.tag': ['极简、轻量、亲和的跨平台网络加速应用。守护你的每一次连接。', 'A minimal, friendly cross-platform network accelerator. Protecting every connection.'],
    'ft.product': ['产品', 'Product'],
    'ft.resources': ['资源', 'Resources'],
    'ft.contact': ['联系与渠道', 'Contact'],
    'ft.features': ['功能', 'Features'],
    'ft.pricing': ['定价', 'Pricing'],
    'ft.download': ['下载', 'Download'],
    'ft.docs': ['文档', 'Docs'],
    'ft.blog': ['Blog', 'Blog'],
    'ft.faq': ['常见问题', 'FAQ'],
    'ft.privacy': ['隐私政策', 'Privacy'],
    'ft.status': ['服务状态', 'Status'],
    'ft.hours': ['服务时间 每日 9:00–24:00 (GMT+8)', 'Hours: Daily 9:00–24:00 (GMT+8)'],
    'ft.copy': ['© 2026 穿山甲 · Pangolin', '© 2026 Pangolin'],
    'ft.madenote': ['App 内不支持直接支付 · 资金流全走外部渠道', 'No in-app payment · all purchases via external channels']
  };
  let lang = localStorage.getItem('pg_site_lang') || 'zh';
  function applyLang() {
    const i = lang === 'zh' ? 0 : 1;
    document.documentElement.lang = lang === 'zh' ? 'zh' : 'en';
    document.querySelectorAll('[data-i18n]').forEach(el => {
      const k = el.getAttribute('data-i18n');
      if (I18N[k]) el.textContent = I18N[k][i];
    });
    document.querySelectorAll('[data-i18n-ph]').forEach(el => {
      const k = el.getAttribute('data-i18n-ph');
      if (I18N[k]) el.placeholder = I18N[k][i];
    });
    document.querySelectorAll('.langseg button').forEach(b => b.classList.toggle('on', b.dataset.lang === lang));
  }
  window.__setLang = function (l) {
    lang = l;
    localStorage.setItem('pg_site_lang', l);
    applyLang();
  };

  // ---------- pricing monthly/yearly ----------
  const PRICES = {
    free: ['¥0', '¥0'],
    pro: ['¥25', '¥20'],
    team: ['¥99', '¥79']
  };
  let cycle = 'monthly';
  window.__setCycle = function (c) {
    cycle = c;
    const i = c === 'monthly' ? 0 : 1;
    document.querySelectorAll('[data-price]').forEach(el => {
      const p = el.getAttribute('data-price');
      el.firstChild.textContent = PRICES[p][i];
    });
    document.querySelectorAll('.price-toggle button').forEach(b => b.classList.toggle('on', b.dataset.cycle === c));
  };

  // ---------- signup (demo: real impl sends a verification code) ----------
  window.__signup = function (e) {
    e.preventDefault();
    const em = document.getElementById('su-email');
    if (!/\S+@\S+\.\S+/.test(em.value)) {
      em.focus();
      return false;
    }
    document.getElementById('su-ok').hidden = false;
    return false;
  };

  // ---------- announcement bar ----------
  window.__closeAnn = function () {
    const a = document.getElementById('ann');
    if (a) a.remove();
  };

  // ---------- mobile menu ----------
  window.__toggleMenu = function () {
    document.getElementById('mnav').classList.toggle('open');
  };

  // ---------- scroll glass header ----------
  function onScroll() {
    document.querySelector('.hdr').classList.toggle('scrolled', window.scrollY > 8);
  }
  window.addEventListener('scroll', onScroll, {
    passive: true
  });

  // ---------- init ----------
  document.addEventListener('DOMContentLoaded', function () {
    applyLang();
    onScroll();
    // close mobile menu when a link is tapped
    document.querySelectorAll('#mnav a').forEach(a => a.addEventListener('click', () => document.getElementById('mnav').classList.remove('open')));
    if (window.lucide) lucide.createIcons();
  });
})();
})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/website/site.js", error: String((e && e.message) || e) }); }

})();
