most-box 0.2.8 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/out/admin/index.html +0 -0
  2. package/out/app/index.html +0 -0
  3. package/out/assets/{FilePreviewOverlay-D8H61qbp.js → FilePreviewOverlay-CM5IqnZD.js} +1 -1
  4. package/out/assets/{MarketingHeader-CrYsQsQ5.js → MarketingHeader-B45AaM29.js} +1 -1
  5. package/out/assets/{MarketingLayout-CQurMOSD.js → MarketingLayout-A00pEOa2.js} +1 -1
  6. package/out/assets/{MilkdownEditor-DrsyaR4h.js → MilkdownEditor-BTq9bDAf.js} +1 -1
  7. package/out/assets/{OpenSidebarButton-DnEgqP0S.js → OpenSidebarButton-D8qfUGzU.js} +1 -1
  8. package/out/assets/{SidebarAccount-B4OAl0as.js → SidebarAccount-_RBE5K_o.js} +1 -1
  9. package/out/assets/{SidebarHomeLink-BdsUM4Kt.js → SidebarHomeLink-qMFEGjZt.js} +1 -1
  10. package/out/assets/{downloadValidation-DbVOwdmC.js → downloadValidation-CSXwoQKW.js} +1 -1
  11. package/out/assets/index-BHZhApbo.css +1 -0
  12. package/out/assets/index-BRhsWNj1.css +1 -0
  13. package/out/assets/{index-BZ-f0CZd.js → index-C-_ZwxuN.js} +2 -2
  14. package/out/assets/index-CYVRmppz.css +1 -0
  15. package/out/assets/index.lazy-0YYV0CR3.js +1 -0
  16. package/out/assets/index.lazy-BTYGr9Vb.js +1 -0
  17. package/out/assets/{index.lazy-B7AbDiMU.js → index.lazy-BVAtQtTa.js} +1 -1
  18. package/out/assets/{index.lazy-oFaoa4qT.js → index.lazy-BbdLA2L-.js} +1 -1
  19. package/out/assets/{index.lazy-DVeqmqaA.js → index.lazy-CbiLtziY.js} +1 -1
  20. package/out/assets/{index.lazy-CvKEcWlH.js → index.lazy-CcEdBg3i.js} +2 -2
  21. package/out/assets/index.lazy-CePHsLXG.js +1 -0
  22. package/out/assets/{index.lazy-rfgjFZNH.js → index.lazy-DG_3_VdF.js} +1 -1
  23. package/out/assets/{index.lazy-zpQXhgmn.js → index.lazy-DR0rWEWZ.js} +1 -1
  24. package/out/assets/{index.lazy-hF807bh0.js → index.lazy-DSyTSCJD.js} +1 -1
  25. package/out/assets/{index.lazy-DB9Ht9LJ.js → index.lazy-DUhsuPLv.js} +1 -1
  26. package/out/assets/{index.lazy-BsciBHf_.js → index.lazy-DVnhWbzH.js} +1 -1
  27. package/out/assets/{index.lazy-CgKPe02l.js → index.lazy-DZpkg1DJ.js} +1 -1
  28. package/out/assets/useChannelMessages-DOaWHdAP.js +4 -0
  29. package/out/assets/{useGameRoom-CRJL0kcm.js → useGameRoom-hHkV65ii.js} +1 -1
  30. package/out/assets/{userProfile-DBkH4s29.js → userProfile-DwZip0Dt.js} +1 -1
  31. package/out/chat/index.html +0 -0
  32. package/out/chat/join/index.html +0 -0
  33. package/out/download/index.html +2 -2
  34. package/out/game/gandengyan/index.html +0 -0
  35. package/out/game/index.html +0 -0
  36. package/out/game/zhajinhua/index.html +0 -0
  37. package/out/index.html +2 -2
  38. package/out/note/index.html +0 -0
  39. package/out/ping/index.html +2 -2
  40. package/out/profile/index.html +0 -0
  41. package/out/web3/index.html +0 -0
  42. package/package.json +1 -1
  43. package/server/index.js +59 -2
  44. package/server/src/http/app.js +7 -1
  45. package/server/src/http/nodeStatus.js +6 -0
  46. package/server/src/http/routes/channelRoutes.js +12 -0
  47. package/server/src/index.js +510 -5
  48. package/out/assets/index-3OD3Chi9.css +0 -1
  49. package/out/assets/index-BSOvFG3o.css +0 -1
  50. package/out/assets/index-Cde4g_dk.css +0 -1
  51. package/out/assets/index.lazy-BxoGfWEW.js +0 -1
  52. package/out/assets/index.lazy-CKbrHko5.js +0 -1
  53. package/out/assets/index.lazy-Citucq1G.js +0 -1
  54. package/out/assets/useChannelMessages-B6RMaNDH.js +0 -3
@@ -1,4 +1,4 @@
1
- <!DOCTYPE html><html lang="zh-CN" data-scroll-behavior="smooth"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><link rel="stylesheet" href="/assets/index-Cde4g_dk.css" data-precedence="default"/><title>MostBox - 网络连通性</title><meta name="theme-color" content="#5e6ad2"/><meta name="description" content="测试到全球主流网站的网络连通性和延迟"/><link rel="modulepreload" href="/assets/index-BZ-f0CZd.js"/><link rel="modulepreload" href="/assets/jsx-runtime-Bt-cYkS5.js"/><link rel="modulepreload" href="/assets/ui-BpDGD3IR.js"/><link rel="modulepreload" href="/assets/useNavigate-DWlBD_-b.js"/><link rel="modulepreload" href="/assets/i18n-NjvOSuV6.js"/><link rel="icon" href="/logo.svg" type="image/svg+xml"/><script>
1
+ <!DOCTYPE html><html lang="zh-CN" data-scroll-behavior="smooth"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><link rel="stylesheet" href="/assets/index-BHZhApbo.css" data-precedence="default"/><title>MostBox - 网络连通性</title><meta name="theme-color" content="#5e6ad2"/><meta name="description" content="测试到全球主流网站的网络连通性和延迟"/><link rel="modulepreload" href="/assets/index-C-_ZwxuN.js"/><link rel="modulepreload" href="/assets/jsx-runtime-Bt-cYkS5.js"/><link rel="modulepreload" href="/assets/ui-BpDGD3IR.js"/><link rel="modulepreload" href="/assets/useNavigate-DWlBD_-b.js"/><link rel="modulepreload" href="/assets/i18n-NjvOSuV6.js"/><link rel="icon" href="/logo.svg" type="image/svg+xml"/><script>
2
2
  (function() {
3
3
  var theme = localStorage.getItem('theme');
4
4
  if (theme === 'dark' || (!theme && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
@@ -17,4 +17,4 @@
17
17
  window.onunhandledrejection = function(event) {
18
18
  console.error('[Unhandled Promise Rejection]', event.reason);
19
19
  };
20
- </script><!--$--><div class="mkt-layout"><nav class="mkt-nav"><div class="mkt-nav-inner"><a href="/" class="mkt-nav-logo"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="8" height="8" rx="2" fill="var(--accent)" opacity="0.4"></rect><rect x="14" y="2" width="8" height="8" rx="2" fill="var(--accent)" opacity="0.7"></rect><rect x="2" y="14" width="8" height="8" rx="2" fill="var(--accent)" opacity="0.7"></rect><rect x="14" y="14" width="8" height="8" rx="2" fill="var(--accent)"></rect></svg>MOST PEOPLE</a><div class="mkt-nav-cta"><button type="button" class="mkt-theme-toggle" aria-label="切换主题" title="切换主题"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-moon" aria-hidden="true"><path d="M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401"></path></svg></button><span class="ui-action-menu-anchor"><button type="button" aria-haspopup="menu" aria-expanded="false" aria-controls="_R_55r6_" class="language-toggle mkt-theme-toggle" aria-label="选择语言" title="选择语言 (当前语言: 简体中文)"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-languages" aria-hidden="true"><path d="m5 8 6 6"></path><path d="m4 14 6-6 2-3"></path><path d="M2 5h12"></path><path d="M7 2h1"></path><path d="m22 22-5-10-5 10"></path><path d="M14 18h6"></path></svg></button></span><a href="/download/" class="btn btn-primary mkt-nav-preview"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-download" aria-hidden="true"><path d="M12 15V3"></path><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><path d="m7 10 5 5 5-5"></path></svg>下载客户端</a><button type="button" class="btn btn-secondary">开始使用</button></div></div></nav><main class="mkt-layout-main"><div class="ping-page"><div class="ping-header"><div class="ping-title-wrap"><svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-wifi ping-title-icon" aria-hidden="true"><path d="M12 20h.01"></path><path d="M2 8.82a15 15 0 0 1 20 0"></path><path d="M5 12.859a10 10 0 0 1 14 0"></path><path d="M8.5 16.429a5 5 0 0 1 7 0"></path></svg><div><h1 class="ping-title">网络连通性</h1><p class="ping-subtitle">通过向对应网站发送请求进行测试,延迟值仅供参考。</p></div></div><button class="btn btn-icon" aria-label="重新测试全部" title="重新测试全部"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-grid"><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-search" aria-hidden="true"><path d="m21 21-4.34-4.34"></path><circle cx="11" cy="11" r="8"></circle></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://google.com" target="_blank" rel="noreferrer" class="ping-card-name">Google</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Google" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-cloud" aria-hidden="true"><path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://cloudflare.com" target="_blank" rel="noreferrer" class="ping-card-name">Cloudflare</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Cloudflare" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-play" aria-hidden="true"><path d="M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://youtube.com" target="_blank" rel="noreferrer" class="ping-card-name">YouTube</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 YouTube" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-terminal" aria-hidden="true"><path d="M12 19h8"></path><path d="m4 17 6-6-6-6"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://github.com" target="_blank" rel="noreferrer" class="ping-card-name">GitHub</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 GitHub" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bot" aria-hidden="true"><path d="M12 8V4H8"></path><rect width="16" height="12" x="4" y="8" rx="2"></rect><path d="M2 14h2"></path><path d="M20 14h2"></path><path d="M15 13v2"></path><path d="M9 13v2"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://chatgpt.com" target="_blank" rel="noreferrer" class="ping-card-name">ChatGPT</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 ChatGPT" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-at-sign" aria-hidden="true"><circle cx="12" cy="12" r="4"></circle><path d="M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-4 8"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://x.com" target="_blank" rel="noreferrer" class="ping-card-name">X</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 X" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-camera" aria-hidden="true"><path d="M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z"></path><circle cx="12" cy="13" r="3"></circle></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://instagram.com" target="_blank" rel="noreferrer" class="ping-card-name">Instagram</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Instagram" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-message-square" aria-hidden="true"><path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://reddit.com" target="_blank" rel="noreferrer" class="ping-card-name">Reddit</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Reddit" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-book-open" aria-hidden="true"><path d="M12 7v14"></path><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://wikipedia.org" target="_blank" rel="noreferrer" class="ping-card-name">Wikipedia</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Wikipedia" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-smartphone" aria-hidden="true"><rect width="14" height="20" x="5" y="2" rx="2" ry="2"></rect><path d="M12 18h.01"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://apple.com" target="_blank" rel="noreferrer" class="ping-card-name">Apple</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Apple" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-send" aria-hidden="true"><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><path d="m21.854 2.147-10.94 10.939"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://telegram.org" target="_blank" rel="noreferrer" class="ping-card-name">Telegram</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Telegram" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-messages-square" aria-hidden="true"><path d="M16 10a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 14.286V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path><path d="M20 9a2 2 0 0 1 2 2v10.286a.71.71 0 0 1-1.212.502l-2.202-2.202A2 2 0 0 0 17.172 19H10a2 2 0 0 1-2-2v-1"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://discord.com" target="_blank" rel="noreferrer" class="ping-card-name">Discord</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Discord" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-music" aria-hidden="true"><path d="M9 18V5l12-2v13"></path><circle cx="6" cy="18" r="3"></circle><circle cx="18" cy="16" r="3"></circle></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://tiktok.com" target="_blank" rel="noreferrer" class="ping-card-name">TikTok</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 TikTok" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-package" aria-hidden="true"><path d="M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z"></path><path d="M12 22V12"></path><polyline points="3.29 7 12 12 20.71 7"></polyline><path d="m7.5 4.27 9 5.15"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://npmjs.com" target="_blank" rel="noreferrer" class="ping-card-name">npm</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 npm" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-triangle" aria-hidden="true"><path d="M13.73 4a2 2 0 0 0-3.46 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://vercel.com" target="_blank" rel="noreferrer" class="ping-card-name">Vercel</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Vercel" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div></div></div></main><footer class="mkt-footer"><div class="mkt-container"><div class="mkt-footer-inner"><div class="mkt-footer-links"><a href="/">关于</a><a class="active" href="/ping/" data-status="active" aria-current="page">网络</a><a href="https://github.com/most-people/most" target="_blank" rel="noopener noreferrer">GitHub</a></div><span class="mkt-footer-copy">© <!-- -->2026<!-- --> MOST PEOPLE · MIT License</span><span class="mkt-footer-build" translate="no">v<!-- -->0.2.8</span></div></div></footer></div><script>(function(a,f){let l;try{l=JSON.parse(sessionStorage.getItem(a)||"{}")}catch{return}const n=l?.[f||history.state?.__TSR_key];let c=!1;for(const t in n){const e=n[t],o=e?.scrollX,s=e?.scrollY;if(Number.isFinite(o)&&Number.isFinite(s)){if(t==="window")scrollTo(o,s),c=!0;else if(t)try{const r=document.querySelector(t);r&&(r.scrollLeft=o,r.scrollTop=s)}catch{}}}if(c)return;const i=location.hash.slice(1);if(i){const t=history.state?.__hashScrollIntoViewOptions??!0;if(t){const e=document.getElementById(i);e&&e.scrollIntoView(t)}return}scrollTo(0,0)})("tsr-scroll-restoration-v1_3");document.currentScript.remove()</script><!--/$--><script class="$tsr" id="$tsr-stream-barrier">(self.$R=self.$R||{})["tsr"]=[];self.$_TSR={h(){this.hydrated=!0,this.c()},e(){this.streamEnded=!0,this.c()},c(){this.hydrated&&this.streamEnded&&(delete self.$_TSR,delete self.$R.tsr)},p(e){this.initialized?e():this.buffer.push(e)},buffer:[]};$_TSR.router=($R=>$R[0]={manifest:$R[1]={routes:$R[2]={__root__:$R[3]={preloads:$R[4]=["/assets/index-BZ-f0CZd.js","/assets/jsx-runtime-Bt-cYkS5.js","/assets/ui-BpDGD3IR.js","/assets/useNavigate-DWlBD_-b.js","/assets/i18n-NjvOSuV6.js"],scripts:$R[5]=[$R[6]={attrs:$R[7]={type:"module",async:!0,src:"/assets/index-BZ-f0CZd.js"}}],css:$R[8]=["/assets/index-Cde4g_dk.css"]}}},matches:$R[9]=[$R[10]={i:"__root__",u:1782269158787,s:"success",ssr:!0},$R[11]={i:"pingping",u:1782269158791,s:"success",ssr:!0}],lastMatchId:"pingping"})($R["tsr"]);$_TSR.e();document.currentScript.remove()</script><script type="module" async="" src="/assets/index-BZ-f0CZd.js"></script></body></html>
20
+ </script><!--$--><div class="mkt-layout"><nav class="mkt-nav"><div class="mkt-nav-inner"><a href="/" class="mkt-nav-logo"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="8" height="8" rx="2" fill="var(--accent)" opacity="0.4"></rect><rect x="14" y="2" width="8" height="8" rx="2" fill="var(--accent)" opacity="0.7"></rect><rect x="2" y="14" width="8" height="8" rx="2" fill="var(--accent)" opacity="0.7"></rect><rect x="14" y="14" width="8" height="8" rx="2" fill="var(--accent)"></rect></svg>MOST PEOPLE</a><div class="mkt-nav-cta"><button type="button" class="mkt-theme-toggle" aria-label="切换主题" title="切换主题"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-moon" aria-hidden="true"><path d="M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401"></path></svg></button><span class="ui-action-menu-anchor"><button type="button" aria-haspopup="menu" aria-expanded="false" aria-controls="_R_55r6_" class="language-toggle mkt-theme-toggle" aria-label="选择语言" title="选择语言 (当前语言: 简体中文)"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-languages" aria-hidden="true"><path d="m5 8 6 6"></path><path d="m4 14 6-6 2-3"></path><path d="M2 5h12"></path><path d="M7 2h1"></path><path d="m22 22-5-10-5 10"></path><path d="M14 18h6"></path></svg></button></span><a href="/download/" class="btn btn-primary mkt-nav-preview"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-download" aria-hidden="true"><path d="M12 15V3"></path><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><path d="m7 10 5 5 5-5"></path></svg>下载客户端</a><button type="button" class="btn btn-secondary">开始使用</button></div></div></nav><main class="mkt-layout-main"><div class="ping-page"><div class="ping-header"><div class="ping-title-wrap"><svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-wifi ping-title-icon" aria-hidden="true"><path d="M12 20h.01"></path><path d="M2 8.82a15 15 0 0 1 20 0"></path><path d="M5 12.859a10 10 0 0 1 14 0"></path><path d="M8.5 16.429a5 5 0 0 1 7 0"></path></svg><div><h1 class="ping-title">网络连通性</h1><p class="ping-subtitle">通过向对应网站发送请求进行测试,延迟值仅供参考。</p></div></div><button class="btn btn-icon" aria-label="重新测试全部" title="重新测试全部"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-grid"><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-search" aria-hidden="true"><path d="m21 21-4.34-4.34"></path><circle cx="11" cy="11" r="8"></circle></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://google.com" target="_blank" rel="noreferrer" class="ping-card-name">Google</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Google" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-cloud" aria-hidden="true"><path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://cloudflare.com" target="_blank" rel="noreferrer" class="ping-card-name">Cloudflare</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Cloudflare" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-play" aria-hidden="true"><path d="M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://youtube.com" target="_blank" rel="noreferrer" class="ping-card-name">YouTube</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 YouTube" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-terminal" aria-hidden="true"><path d="M12 19h8"></path><path d="m4 17 6-6-6-6"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://github.com" target="_blank" rel="noreferrer" class="ping-card-name">GitHub</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 GitHub" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bot" aria-hidden="true"><path d="M12 8V4H8"></path><rect width="16" height="12" x="4" y="8" rx="2"></rect><path d="M2 14h2"></path><path d="M20 14h2"></path><path d="M15 13v2"></path><path d="M9 13v2"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://chatgpt.com" target="_blank" rel="noreferrer" class="ping-card-name">ChatGPT</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 ChatGPT" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-at-sign" aria-hidden="true"><circle cx="12" cy="12" r="4"></circle><path d="M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-4 8"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://x.com" target="_blank" rel="noreferrer" class="ping-card-name">X</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 X" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-camera" aria-hidden="true"><path d="M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z"></path><circle cx="12" cy="13" r="3"></circle></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://instagram.com" target="_blank" rel="noreferrer" class="ping-card-name">Instagram</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Instagram" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-message-square" aria-hidden="true"><path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://reddit.com" target="_blank" rel="noreferrer" class="ping-card-name">Reddit</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Reddit" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-book-open" aria-hidden="true"><path d="M12 7v14"></path><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://wikipedia.org" target="_blank" rel="noreferrer" class="ping-card-name">Wikipedia</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Wikipedia" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-smartphone" aria-hidden="true"><rect width="14" height="20" x="5" y="2" rx="2" ry="2"></rect><path d="M12 18h.01"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://apple.com" target="_blank" rel="noreferrer" class="ping-card-name">Apple</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Apple" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-send" aria-hidden="true"><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><path d="m21.854 2.147-10.94 10.939"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://telegram.org" target="_blank" rel="noreferrer" class="ping-card-name">Telegram</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Telegram" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-messages-square" aria-hidden="true"><path d="M16 10a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 14.286V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path><path d="M20 9a2 2 0 0 1 2 2v10.286a.71.71 0 0 1-1.212.502l-2.202-2.202A2 2 0 0 0 17.172 19H10a2 2 0 0 1-2-2v-1"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://discord.com" target="_blank" rel="noreferrer" class="ping-card-name">Discord</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Discord" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-music" aria-hidden="true"><path d="M9 18V5l12-2v13"></path><circle cx="6" cy="18" r="3"></circle><circle cx="18" cy="16" r="3"></circle></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://tiktok.com" target="_blank" rel="noreferrer" class="ping-card-name">TikTok</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 TikTok" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-package" aria-hidden="true"><path d="M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z"></path><path d="M12 22V12"></path><polyline points="3.29 7 12 12 20.71 7"></polyline><path d="m7.5 4.27 9 5.15"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://npmjs.com" target="_blank" rel="noreferrer" class="ping-card-name">npm</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 npm" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div><div class="ping-card pending"><div class="ping-card-top"><span class="ping-card-icon"><span class="brand-icon-wrap"><span class="brand-icon-fallback "><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-triangle" aria-hidden="true"><path d="M13.73 4a2 2 0 0 0-3.46 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"></path></svg></span><span class="brand-icon-real "><span></span></span></span></span><a href="https://vercel.com" target="_blank" rel="noreferrer" class="ping-card-name">Vercel</a><button class="ping-card-refresh" disabled="" aria-label="重新测试 Vercel" title="重新测试"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw ping-spin" aria-hidden="true"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg></button></div><div class="ping-card-bottom"><span class="ping-pulse-dot"></span><span class="ping-latency is-muted">--</span></div></div></div></div></main><footer class="mkt-footer"><div class="mkt-container"><div class="mkt-footer-inner"><div class="mkt-footer-links"><a href="/">关于</a><a class="active" href="/ping/" data-status="active" aria-current="page">网络</a><a href="https://github.com/most-people/most" target="_blank" rel="noopener noreferrer">GitHub</a></div><span class="mkt-footer-copy">© <!-- -->2026<!-- --> MOST PEOPLE · MIT License</span><span class="mkt-footer-build" translate="no">v<!-- -->0.3.0</span></div></div></footer></div><script>(function(a,f){let l;try{l=JSON.parse(sessionStorage.getItem(a)||"{}")}catch{return}const n=l?.[f||history.state?.__TSR_key];let c=!1;for(const t in n){const e=n[t],o=e?.scrollX,s=e?.scrollY;if(Number.isFinite(o)&&Number.isFinite(s)){if(t==="window")scrollTo(o,s),c=!0;else if(t)try{const r=document.querySelector(t);r&&(r.scrollLeft=o,r.scrollTop=s)}catch{}}}if(c)return;const i=location.hash.slice(1);if(i){const t=history.state?.__hashScrollIntoViewOptions??!0;if(t){const e=document.getElementById(i);e&&e.scrollIntoView(t)}return}scrollTo(0,0)})("tsr-scroll-restoration-v1_3");document.currentScript.remove()</script><!--/$--><script class="$tsr" id="$tsr-stream-barrier">(self.$R=self.$R||{})["tsr"]=[];self.$_TSR={h(){this.hydrated=!0,this.c()},e(){this.streamEnded=!0,this.c()},c(){this.hydrated&&this.streamEnded&&(delete self.$_TSR,delete self.$R.tsr)},p(e){this.initialized?e():this.buffer.push(e)},buffer:[]};$_TSR.router=($R=>$R[0]={manifest:$R[1]={routes:$R[2]={__root__:$R[3]={preloads:$R[4]=["/assets/index-C-_ZwxuN.js","/assets/jsx-runtime-Bt-cYkS5.js","/assets/ui-BpDGD3IR.js","/assets/useNavigate-DWlBD_-b.js","/assets/i18n-NjvOSuV6.js"],scripts:$R[5]=[$R[6]={attrs:$R[7]={type:"module",async:!0,src:"/assets/index-C-_ZwxuN.js"}}],css:$R[8]=["/assets/index-BHZhApbo.css"]}}},matches:$R[9]=[$R[10]={i:"__root__",u:1782289898869,s:"success",ssr:!0},$R[11]={i:"pingping",u:1782289898874,s:"success",ssr:!0}],lastMatchId:"pingping"})($R["tsr"]);$_TSR.e();document.currentScript.remove()</script><script type="module" async="" src="/assets/index-C-_ZwxuN.js"></script></body></html>
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "most-box",
3
- "version": "0.2.8",
3
+ "version": "0.3.0",
4
4
  "description": "MostBox - P2P file sharing application",
5
5
  "type": "module",
6
6
  "main": "electron/main.js",
package/server/index.js CHANGED
@@ -137,6 +137,9 @@ function bindEngineEvents({
137
137
  engine.on('channel:peer:offline', data =>
138
138
  wsBroadcast('channel:peer:offline', data)
139
139
  )
140
+ engine.on('channel:presence', data =>
141
+ wsSendToChannel(data.channelKey, 'channel:presence', data)
142
+ )
140
143
  engine.on('channel:joined', data => wsBroadcast('channel:joined', data))
141
144
  engine.on('channel:left', data => wsBroadcast('channel:left', data))
142
145
  engine.on('user:metadata:updated', data => {
@@ -157,23 +160,33 @@ function bindEngineEvents({
157
160
  }
158
161
 
159
162
  function createWebSocketServer({
163
+ engine,
160
164
  serverInstance,
161
165
  validateWebSocketRequest,
166
+ getWebSocketUserAddress,
162
167
  subscribeToChannel,
163
168
  unsubscribeFromChannel,
164
169
  cleanupWsSubscriptions,
165
170
  }) {
166
171
  const wss = new WebSocketServer({ noServer: true })
172
+ let wsConnectionCounter = 0
167
173
 
168
- wss.on('connection', ws => {
174
+ wss.on('connection', (ws, req) => {
175
+ ws.userAddress = getWebSocketUserAddress(req)
176
+ ws.presenceSourceId = `ws:${++wsConnectionCounter}`
169
177
  ws.on('error', () => {})
170
178
  ws.on('close', () => {
171
179
  cleanupWsSubscriptions(ws)
180
+ try {
181
+ engine.clearChannelPresenceSource(ws.presenceSourceId, {
182
+ broadcast: true,
183
+ })
184
+ } catch {}
172
185
  })
173
186
  ws.on('message', raw => {
174
187
  try {
175
188
  const msg = JSON.parse(raw)
176
- const { event, data } = msg
189
+ const { event, data = {} } = msg
177
190
 
178
191
  switch (event) {
179
192
  case 'register':
@@ -189,6 +202,48 @@ function createWebSocketServer({
189
202
  unsubscribeFromChannel(ws, data.channel)
190
203
  }
191
204
  break
205
+ case 'channel:presence:join':
206
+ if (data.channel && ws.userAddress) {
207
+ engine.joinChannelPresence(data.channel, {
208
+ ownerAddress: ws.userAddress,
209
+ sourceId: ws.presenceSourceId,
210
+ sessionId: data.sessionId,
211
+ displayName: data.displayName,
212
+ avatar: data.avatar,
213
+ profileUpdatedAt: data.profileUpdatedAt,
214
+ })
215
+ }
216
+ break
217
+ case 'channel:presence:heartbeat':
218
+ if (data.channel && ws.userAddress) {
219
+ engine.heartbeatChannelPresence(data.channel, {
220
+ ownerAddress: ws.userAddress,
221
+ sourceId: ws.presenceSourceId,
222
+ sessionId: data.sessionId,
223
+ })
224
+ }
225
+ break
226
+ case 'channel:presence:profile':
227
+ if (data.channel && ws.userAddress) {
228
+ engine.updateChannelPresenceProfile(data.channel, {
229
+ ownerAddress: ws.userAddress,
230
+ sourceId: ws.presenceSourceId,
231
+ sessionId: data.sessionId,
232
+ displayName: data.displayName,
233
+ avatar: data.avatar,
234
+ profileUpdatedAt: data.profileUpdatedAt,
235
+ })
236
+ }
237
+ break
238
+ case 'channel:presence:leave':
239
+ if (data.channel && ws.userAddress) {
240
+ engine.leaveChannelPresence(data.channel, {
241
+ ownerAddress: ws.userAddress,
242
+ sourceId: ws.presenceSourceId,
243
+ sessionId: data.sessionId,
244
+ })
245
+ }
246
+ break
192
247
  }
193
248
  } catch (err) {
194
249
  console.error('[WS Message Error]', err.message)
@@ -295,8 +350,10 @@ export async function main() {
295
350
  )
296
351
 
297
352
  wssRef.current = createWebSocketServer({
353
+ engine,
298
354
  serverInstance: serverInstanceRef.current,
299
355
  validateWebSocketRequest: appRuntime.validateWebSocketRequest,
356
+ getWebSocketUserAddress: appRuntime.getWebSocketUserAddress,
300
357
  subscribeToChannel: appRuntime.subscribeToChannel,
301
358
  unsubscribeFromChannel: appRuntime.unsubscribeFromChannel,
302
359
  cleanupWsSubscriptions: appRuntime.cleanupWsSubscriptions,
@@ -225,6 +225,11 @@ export function createApp(engine, options = {}) {
225
225
  return false
226
226
  }
227
227
 
228
+ return Boolean(getWebSocketUserAddress(req))
229
+ }
230
+
231
+ function getWebSocketUserAddress(req) {
232
+ const url = new URL(req.url, `http://localhost:${appPort}`)
228
233
  const address = url.searchParams.get('address') || ''
229
234
  const timestamp = url.searchParams.get('timestamp') || ''
230
235
  const signature = url.searchParams.get('signature') || ''
@@ -233,7 +238,7 @@ export function createApp(engine, options = {}) {
233
238
  'GET',
234
239
  '/ws'
235
240
  )
236
- return auth.ok
241
+ return auth.ok ? auth.address : ''
237
242
  }
238
243
 
239
244
  // 将广播函数挂载到 engine 上供外部测试使用
@@ -310,5 +315,6 @@ export function createApp(engine, options = {}) {
310
315
  unsubscribeFromChannel,
311
316
  cleanupWsSubscriptions,
312
317
  validateWebSocketRequest,
318
+ getWebSocketUserAddress,
313
319
  }
314
320
  }
@@ -266,6 +266,12 @@ export function buildOpenApiSpec(appPort) {
266
266
  responses: { 200: { description: 'Channel peers' } },
267
267
  },
268
268
  },
269
+ '/api/channels/{name}/presence': {
270
+ get: {
271
+ summary: 'List active user presence for a channel',
272
+ responses: { 200: { description: 'Channel presence' } },
273
+ },
274
+ },
269
275
  '/api/channels/{name}/remark': {
270
276
  put: {
271
277
  summary: 'Set an authenticated user channel remark',
@@ -123,6 +123,18 @@ export function registerChannelRoutes(app, { engine }) {
123
123
  }
124
124
  })
125
125
 
126
+ app.get('/api/channels/:name/presence', c => {
127
+ try {
128
+ return c.json(
129
+ engine.getChannelPresence(c.req.param('name'), {
130
+ ownerAddress: c.get('userAddress'),
131
+ })
132
+ )
133
+ } catch (err) {
134
+ return badRequestOrAppError(c, err)
135
+ }
136
+ })
137
+
126
138
  app.put('/api/channels/:name/remark', async c => {
127
139
  const name = c.req.param('name')
128
140
  const body = await c.req.json()