most-box 0.3.2 → 0.3.4

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 (64) hide show
  1. package/README.md +7 -6
  2. package/out/admin/index.html +0 -0
  3. package/out/app/index.html +0 -0
  4. package/out/assets/{AccountMenu-BgbcUc0m.js → AccountMenu-ptQklqvD.js} +1 -1
  5. package/out/assets/{AppTop-DZFTO9-m.js → AppTop-Cy0ZOCxO.js} +1 -1
  6. package/out/assets/{CopyButton-B03fpFFc.js → CopyButton-C8PIDSJZ.js} +1 -1
  7. package/out/assets/{FilePreviewOverlay-CA04_Ved.js → FilePreviewOverlay-faaTnmlN.js} +1 -1
  8. package/out/assets/{MarketingHeader-BVJy8hXd.js → MarketingHeader-CxJ_OVOW.js} +1 -1
  9. package/out/assets/MarketingLayout-CiN5KYcE.js +1 -0
  10. package/out/assets/{MilkdownEditor-Dw_ze7EE.js → MilkdownEditor-BzbYt-xb.js} +1 -1
  11. package/out/assets/{OpenSidebarButton-C2UJYXKh.js → OpenSidebarButton-CGhXxQ5Z.js} +1 -1
  12. package/out/assets/arrow-up-down-B-677ip8.js +1 -0
  13. package/out/assets/{chatJoinInvite-BcPz_IV5.js → chatJoinInvite-B-ucvYdg.js} +1 -1
  14. package/out/assets/chevron-right-D75NRNNs.js +1 -0
  15. package/out/assets/downloadValidation-UPgpJbKz.js +1 -0
  16. package/out/assets/folder-BS_GbpPQ.js +1 -0
  17. package/out/assets/index-D0Uk9-58.js +31 -0
  18. package/out/assets/index-FV6RZlVI.css +1 -0
  19. package/out/assets/{index.lazy-Cd0znkpY.js → index.lazy-B6XDJ8fg.js} +1 -1
  20. package/out/assets/{index.lazy-CtUrBLS0.js → index.lazy-BFdWbm3R.js} +1 -1
  21. package/out/assets/{index.lazy-Bdh8QUOx.js → index.lazy-BzIt7fP4.js} +1 -1
  22. package/out/assets/index.lazy-CLkb32nv.js +1 -0
  23. package/out/assets/{index.lazy-CNQbNKyf.js → index.lazy-CNmqW4-r.js} +1 -1
  24. package/out/assets/index.lazy-Cnkj-gAd.js +3 -0
  25. package/out/assets/index.lazy-Cx1bp84f.js +5 -0
  26. package/out/assets/index.lazy-CxLzR674.js +2 -0
  27. package/out/assets/{index.lazy-C9-w4fAF.js → index.lazy-D4RjTGu-.js} +1 -1
  28. package/out/assets/{index.lazy-BfAHB94y.js → index.lazy-D9xLqvqW.js} +1 -1
  29. package/out/assets/{index.lazy-BUODxlbz.js → index.lazy-DNCF6MTJ.js} +1 -1
  30. package/out/assets/index.lazy-MY-mUG5Z.js +1 -0
  31. package/out/assets/index.lazy-erUKA2rI.js +1 -0
  32. package/out/assets/index.lazy-qTjgLKhY.js +1 -0
  33. package/out/assets/notebook-pen-BzrCXQJE.js +1 -0
  34. package/out/assets/{useGameRoom-B1_r6bc7.js → useGameRoom-CS1w4IqP.js} +1 -1
  35. package/out/chat/index.html +0 -0
  36. package/out/chat/join/demo/index.html +0 -0
  37. package/out/chat/join/index.html +0 -0
  38. package/out/download/index.html +2 -2
  39. package/out/game/gandengyan/index.html +0 -0
  40. package/out/game/index.html +0 -0
  41. package/out/game/zhajinhua/index.html +0 -0
  42. package/out/index.html +2 -2
  43. package/out/note/index.html +0 -0
  44. package/out/ping/index.html +2 -2
  45. package/out/profile/index.html +0 -0
  46. package/out/web3/index.html +0 -0
  47. package/package.json +4 -3
  48. package/server/src/core/channelAttachment.js +2 -2
  49. package/server/src/core/releaseManifest.js +10 -3
  50. package/server/src/index.js +8 -8
  51. package/out/assets/MarketingLayout-Cltu-DRw.js +0 -1
  52. package/out/assets/downloadValidation-Zvllo2SZ.js +0 -1
  53. package/out/assets/folder-DAcox9xz.js +0 -1
  54. package/out/assets/folder-open-Di0oALaC.js +0 -1
  55. package/out/assets/index-B6acG3-t.css +0 -1
  56. package/out/assets/index-DjBN7bZV.js +0 -31
  57. package/out/assets/index.lazy-Ba2rqd32.js +0 -3
  58. package/out/assets/index.lazy-Bo0LfJNK.js +0 -2
  59. package/out/assets/index.lazy-CyNgk0ta.js +0 -1
  60. package/out/assets/index.lazy-D3HxQTg_.js +0 -1
  61. package/out/assets/index.lazy-DSsE3iyf.js +0 -1
  62. package/out/assets/index.lazy-DWXndrGa.js +0 -1
  63. package/out/assets/index.lazy-Dk7cmQ-j.js +0 -2
  64. package/out/assets/notebook-pen-SWT-zZ4v.js +0 -1
@@ -1 +1 @@
1
- import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{A as r,B as i,E as a,H as o,O as s,_ as c,g as l,h as u,k as d,t as f,x as p,y as m}from"./useAppStore-DOnk608w.js";import{t as h}from"./copy-B7pPZ2MP.js";import{n as g}from"./AppTop-DZFTO9-m.js";import{t as ee}from"./play-CvWKSMwY.js";import{a as _,i as te,n as ne,r as re,t as ie}from"./useGameRoom-B1_r6bc7.js";import{A as ae,f as oe,w as se}from"./index-DjBN7bZV.js";var ce=i(`refresh-ccw`,[[`path`,{d:`M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`14sxne`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}],[`path`,{d:`M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16`,key:`1hlbsb`}],[`path`,{d:`M16 16h5v5`,key:`ccwih5`}]]),v=t(e(),1),y=[10,20,50,100],b=[`2`,`3`,`4`,`5`,`6`,`7`,`8`,`9`,`10`,`J`,`Q`,`K`,`A`],x=[`D`,`C`,`H`,`S`],le=new Map(b.map((e,t)=>[e,t+2])),ue=new Map(x.map((e,t)=>[e,t+1])),S={high:1,pair:2,straight:3,flush:4,straightFlush:5,triple:6},de={[S.high]:`散牌`,[S.pair]:`对子`,[S.straight]:`顺子`,[S.flush]:`金花`,[S.straightFlush]:`顺金`,[S.triple]:`豹子`};function C(e){return m(e)}function w(e=`zhajinhua`){return u(e)}function T(){return w(`round`)}function E(){let e=[];for(let t of x)for(let n of b)e.push(`${n}${t}`);return e}function D(e=E(),t=Math.random){let n=[...e];for(let e=n.length-1;e>0;e--){let r=Math.floor(t()*(e+1));[n[e],n[r]]=[n[r],n[e]]}return n}function O(e){let t=String(e||``).trim().toUpperCase(),n=t.slice(-1),r=t.slice(0,-1);if(!le.has(r)||!ue.has(n))throw Error(`Invalid card: ${e}`);return{id:`${r}${n}`,rank:r,suit:n,rankValue:le.get(r),suitValue:ue.get(n)}}function k(e,t){let n=Math.max(e.length,t.length);for(let r=0;r<n;r++){let n=e[r]||0,i=t[r]||0;if(n!==i)return n-i}return 0}function A(e){let t=[...new Set(e)].sort((e,t)=>e-t);return t.length===3?t[0]===2&&t[1]===3&&t[2]===14?3:t[0]+1===t[1]&&t[1]+1===t[2]?t[2]:0:0}function j(e){if(!Array.isArray(e)||e.length!==3)throw Error(`炸金花手牌必须是 3 张牌`);let t=e.map(O),n=t.map(e=>e.rankValue),r=new Map;for(let e of n)r.set(e,(r.get(e)||0)+1);let i=new Set(t.map(e=>e.suit)).size===1,a=A(n),o=[...n].sort((e,t)=>t-e),s=Math.max(...t.map(e=>e.suitValue)),c=S.high,l=o;return r.size===1?(c=S.triple,l=[o[0]]):a&&i?(c=S.straightFlush,l=[a]):i?(c=S.flush,l=o):a?(c=S.straight,l=[a]):r.size===2&&(c=S.pair,l=[[...r.entries()].find(([,e])=>e===2)[0],[...r.entries()].find(([,e])=>e===1)[0]]),{category:c,label:de[c],tiebreakers:l,tieSuit:s,cards:t.map(e=>e.id)}}function M(e,t){let n=j(e),r=j(t);if(n.category!==r.category)return n.category-r.category;let i=k(n.tiebreakers,r.tiebreakers);return i===0?n.tieSuit-r.tieSuit:i}function N(e){return j(e).label}function P({roundId:e,action:t,amount:n,target:r}){return{roundId:e,eventId:w(`action`),action:t,amount:n,target:r}}function fe(e=[]){let t=e.filter(e=>Number(e.chips)>=10);return t.length>=2&&t.length<=5}function pe({roomCode:e,players:t,hostAddress:n,previousSeq:r=0,previousWinner:i=``,roundId:a=T(),random:o=Math.random}){let s=t.filter(e=>Number(e.chips)>=10).slice(0,5);if(s.length<2)throw Error(`至少需要 2 名有足够筹码的玩家`);let u=D(E(),o),d={},f=s.map((e,t)=>{let n=u.slice(t*3,t*3+3);return d[e.address]=n,{address:e.address,name:e.name,avatar:c(e.avatar),publicKey:e.publicKey,chips:Number(e.chips)-10,status:`active`,looked:!1,bet:10}}),p,m=l(i),h=m?f.findIndex(e=>l(e.address)===m):-1;return p=h>=0?f[h].address:f[Math.floor(o()*f.length)].address,{roomCode:C(e),roundId:a,status:`playing`,host:l(n),seq:r+1,startedAt:Date.now(),ante:10,pot:10*f.length,currentBet:10,turnAddress:p,players:f,lastAction:`本局开始`,winner:null,showdown:null,appliedEventIds:[],hands:d,actionCounts:{},compareReveal:{}}}function me(e){if(!e)return null;let t={...e};return delete t.hands,W(t)}function he(e,t){let n=F(e);return!n||!t||typeof t!=`object`?null:{...n,hands:W(t)}}function F(e){return!e||typeof e!=`object`||!e.roundId||!Array.isArray(e.players)?null:{roomCode:C(e.roomCode),roundId:String(e.roundId),status:e.status===`finished`?`finished`:`playing`,host:l(e.host),seq:Number(e.seq)||1,startedAt:Number(e.startedAt)||Date.now(),ante:Number(e.ante)||10,pot:Math.max(0,Number(e.pot)||0),currentBet:Math.max(0,Number(e.currentBet)||10),turnAddress:l(e.turnAddress),players:e.players.map(U).filter(Boolean),lastAction:String(e.lastAction||``),winner:e.winner?l(e.winner):null,showdown:e.showdown&&typeof e.showdown==`object`?W(e.showdown):null,appliedEventIds:Array.isArray(e.appliedEventIds)?e.appliedEventIds.map(String):[],actionCounts:e.actionCounts&&typeof e.actionCounts==`object`?W(e.actionCounts):{},compareReveal:e.compareReveal&&typeof e.compareReveal==`object`?W(e.compareReveal):{},lastCompare:e.lastCompare&&typeof e.lastCompare==`object`?W(e.lastCompare):null,finishedAt:e.finishedAt?Number(e.finishedAt):null}}function I(e,t,n){let r=F(e);if(!r||r.status!==`playing`)return{ok:!1,error:`当前没有进行中的牌局`};let i=l(n),a=r.players.find(e=>e.address===i);if(!a||a.status!==`active`)return{ok:!1,error:`玩家不在本轮牌局中`};if(r.turnAddress!==i)return{ok:!1,error:`还没有轮到你操作`};let o=t?.action;if(![`look`,`call`,`raise`,`compare`,`fold`].includes(o))return{ok:!1,error:`未知操作`};if(o===`look`)return a.looked?{ok:!1,error:`已经看过牌`}:{ok:!0};if(o===`call`)return a.chips>=10?{ok:!0}:{ok:!1,error:`筹码不足,不能跟注`};if(o===`raise`){let e=Number(t.amount);if(!y.includes(e))return{ok:!1,error:`加注档位无效`};let n=r.currentBet+e-a.bet;return a.chips>=n?{ok:!0}:{ok:!1,error:`筹码不足,不能加注`}}if(o===`compare`){let e=l(t.target),n=r.players.find(t=>t.address===e);if(!e||e===i||!n||n.status!==`active`)return{ok:!1,error:`请选择有效的比牌对象`};if(!r.players.filter(e=>e.status===`active`).every(e=>(r.actionCounts?.[e.address]||0)>=1))return{ok:!1,error:`第一轮不能比牌,请先跟注或加注`};let o=Math.max(0,r.currentBet-a.bet);return a.chips>=o?{ok:!0}:{ok:!1,error:`筹码不足,不能比牌`}}return{ok:!0}}function L(e,t,n){let r=I(e,t,n);if(!r.ok)return{ok:!1,error:r.error,state:e};let i=W(e),a=l(n),o=i.players.find(e=>e.address===a),s=String(t.eventId);if(i.appliedEventIds?.includes(s))return{ok:!0,state:i,duplicate:!0};if(Array.isArray(i.appliedEventIds)||(i.appliedEventIds=[]),i.appliedEventIds.push(s),t.action===`look`)return o.looked=!0,i.lastAction=`${o.name} 看牌`,H(i);if(t.action===`fold`)return o.status=`folded`,i.lastAction=`${o.name} 弃牌`,B(i,a),V(i,a);if(t.action===`call`)return o.chips-=10,o.bet+=10,i.pot+=10,i.lastAction=`${o.name} 跟注`,B(i,a),V(i,a);if(t.action===`raise`){let e=Number(t.amount);return i.currentBet+=e,z(i,o),i.lastAction=`${o.name} 加注 ${e}`,B(i,a),V(i,a)}if(t.action===`compare`){z(i,o);let e=l(t.target),n=i.players.find(t=>t.address===e),r=o.looked,s=n.looked,c=M(i.hands?.[a]||[],i.hands?.[e]||[]),u=c>=0?o:n,d=c>=0?n:o;d.status=`folded`,d.looked=!0,i.compareReveal||={};let f=r&&s,p=!r&&!s;if(f)i.compareReveal[a]=i.hands?.[e]||[],i.compareReveal[e]=i.hands?.[a]||[];else if(p)i.compareReveal[d.address]=i.hands?.[u.address]||[];else{let e=r?o:n,t=r?n:o;i.compareReveal[e.address]=i.hands?.[t.address]||[],i.compareReveal[d.address]=i.hands?.[u.address]||[]}return i.lastCompare={initiator:a,target:e,winner:u.address,loser:d.address,initiatorLooked:r,targetLooked:s,timestamp:Date.now()},i.lastAction=`${o.name} 与 ${n.name} 比牌,${d.name} 出局`,B(i,a),V(i,a)}return{ok:!1,error:`未知操作`,state:e}}function R(e){return(e?.players||[]).filter(e=>e.status===`active`)}function ge(e,t){let n=(e?.players||[]).find(e=>e.address===l(t));if(!e||e.status!==`playing`||!n||n.status!==`active`||e.turnAddress!==n.address)return[];let r=[];return n.looked||r.push(`look`),I(e,{action:`call`},n.address).ok&&r.push(`call`),y.some(t=>I(e,{action:`raise`,amount:t},n.address).ok)&&r.push(`raise`),R(e).length>1&&e.players.filter(e=>e.status===`active`).every(t=>(e.actionCounts?.[t.address]||0)>=1)&&r.push(`compare`),r.push(`fold`),r}function z(e,t){let n=Math.max(0,e.currentBet-t.bet);t.chips-=n,t.bet+=n,e.pot+=n}function B(e,t){e.actionCounts||={},e.actionCounts[t]=(e.actionCounts[t]||0)+1}function V(e,t){let n=R(e);return n.length===1?_e(e,n[0].address):(e.turnAddress=ve(e,t),H(e))}function _e(e,t){let n=e.players.find(e=>e.address===t),r=e.pot;return n&&(n.chips+=e.pot),e.status=`finished`,e.winner=t,e.winAmount=r,e.turnAddress=``,e.showdown=e.hands?W(e.hands):null,e.lastAction=n?`${n.name} 赢得 ${r} 筹码`:`本局结束`,e.pot=0,e.finishedAt=Date.now(),H(e)}function ve(e,t){let n=e.players,r=Math.max(0,n.findIndex(e=>e.address===l(t)));for(let e=1;e<=n.length;e++){let t=n[(r+e)%n.length];if(t.status===`active`)return t.address}return``}function H(e){return e.seq=Number(e.seq||0)+1,{ok:!0,state:e}}function U(e){if(!e||typeof e!=`object`)return null;let t=l(e.address);return t?{address:t,name:String(e.name||p(t)).slice(0,50),avatar:c(e.avatar),publicKey:String(e.publicKey||``),chips:Math.max(0,Number(e.chips)||0),status:e.status===`folded`?`folded`:`active`,looked:e.looked===!0,bet:Math.max(0,Number(e.bet)||0)}:null}function W(e){return JSON.parse(JSON.stringify(e))}var G={page:`_page_p8eol_1`,headerActions:`_headerActions_p8eol_12`,entry:`_entry_p8eol_18`,entryBrand:`_entryBrand_p8eol_28`,cardMark:`_cardMark_p8eol_34`,entryPanel:`_entryPanel_p8eol_62`,accountLine:`_accountLine_p8eol_72`,joinForm:`_joinForm_p8eol_89`,status:`_status_p8eol_110`,board:`_board_p8eol_116`,table:`_table_p8eol_123`,tableCenter:`_tableCenter_p8eol_144`,finishBanner:`_finishBanner_p8eol_173`,finishBannerIcon:`_finishBannerIcon_p8eol_192`,seats:`_seats_p8eol_196`,seat:`_seat_p8eol_196`,seatTurn:`_seatTurn_p8eol_218`,seatWinner:`_seatWinner_p8eol_223`,seatFolded:`_seatFolded_p8eol_228`,seatAvatar:`_seatAvatar_p8eol_232`,seatAvatarOffline:`_seatAvatarOffline_p8eol_252`,onlineDot:`_onlineDot_p8eol_257`,seatMain:`_seatMain_p8eol_269`,seatMeta:`_seatMeta_p8eol_270`,panel:`_panel_p8eol_301`,panelSection:`_panelSection_p8eol_308`,panelTitle:`_panelTitle_p8eol_318`,hand:`_hand_p8eol_328`,card:`_card_p8eol_34`,red:`_red_p8eol_362`,black:`_black_p8eol_366`,cardBack:`_cardBack_p8eol_370`,handLabel:`_handLabel_p8eol_391`,actionGrid:`_actionGrid_p8eol_398`,raiseRow:`_raiseRow_p8eol_399`,statusGrid:`_statusGrid_p8eol_410`,muted:`_muted_p8eol_428`,compareOverlay:`_compareOverlay_p8eol_435`,compareBox:`_compareBox_p8eol_447`,compareTitle:`_compareTitle_p8eol_461`,comparePlayers:`_comparePlayers_p8eol_467`,compareSide:`_compareSide_p8eol_474`,compareWinner:`_compareWinner_p8eol_486`,compareName:`_compareName_p8eol_491`,compareCards:`_compareCards_p8eol_502`,compareLabel:`_compareLabel_p8eol_527`,compareVs:`_compareVs_p8eol_533`,compareResult:`_compareResult_p8eol_540`},K=n(),q=`zhajinhua`;function J(...e){return e.filter(Boolean).join(` `)}function Y(e,t){return String(e||``).toLowerCase()===String(t||``).toLowerCase()}function ye(e=``){return e?`${e.slice(0,6)}...${e.slice(-4)}`:``}function be(e){return e.displayName||e.username}function xe(e){let t=String(e||``),n=t.slice(-1);return{rank:t.slice(0,-1),suit:{S:`♠`,H:`♥`,C:`♣`,D:`♦`}[n]||n,color:n===`H`||n===`D`?`red`:`black`}}function X(){let{t:e}=ae(),t=f(e=>e.addToast),n=a(e=>e.initializeUser),[i,o]=(0,v.useState)(``),[c,l]=(0,v.useState)(!1),u=(0,v.useRef)(``),p=(0,v.useRef)(!1),[m,b]=(0,v.useState)(20),[x,le]=(0,v.useState)(``),[ue,S]=(0,v.useState)({}),[de,C]=(0,v.useState)(!0),[w,T]=(0,v.useState)(!1),E=(0,v.useRef)(null),D=(0,v.useRef)(new Set),O=ie({gameId:q,onError:e=>t(e,`error`),getPlayerPayload:e=>{let t=s(e.danger);return{address:e.address,name:be(e),avatar:e.avatar||``,publicKey:t.public_key,joinedAt:Date.now()}}}),k=(0,v.useMemo)(()=>O.userIdentity?.danger?s(O.userIdentity.danger):null,[O.userIdentity?.danger]);(0,v.useEffect)(()=>{n()},[n]),(0,v.useEffect)(()=>{let e=new URLSearchParams(window.location.search).get(`room`)?.toUpperCase();e&&(o(e),u.current=e)},[]),(0,v.useEffect)(()=>{let n=u.current;!n||p.current||!O.isBackendReady||!O.userIdentity||(p.current=!0,u.current=``,O.joinRoom(n).then(n=>{n&&t(e(`game.toast.joinedRoom`),`success`)}))},[O.isBackendReady,O.userIdentity,O.joinRoom,t,e]),(0,v.useEffect)(()=>{if(!O.roomCode)return;let e=`/game/zhajinhua?room=${O.roomCode}`;`${window.location.pathname}${window.location.search}`!==e&&window.history.replaceState(null,``,e)},[O.roomCode]);let A=(0,v.useMemo)(()=>ne(O.messages,{gameId:q,roomCode:O.roomCode}),[O.messages,O.roomCode]),j=(0,v.useMemo)(()=>re(O.messages,{gameId:q,roomCode:O.roomCode}),[O.messages,O.roomCode])?.payload?.round||null,M=j?.host||A.hostAddress,F=Y(M,O.userIdentity?.address),I=O.userIdentity?.address?.toLowerCase()||``,z=j?.players.find(e=>Y(e.address,I)),B=z||A.players.find(e=>Y(e.address,I)),V=ue[j?.roundId||``]||null,_e=j?.showdown&&I?j.showdown[I]:null,ve=j?.compareReveal&&I?j.compareReveal[I]:null,H=_e||ve||(z?.looked?V:null),U=ge(j,I),W=R(j),X=F&&fe(A.players.map(e=>({...e,chips:j?.players.find(t=>Y(t.address,e.address))?.chips??1e3}))),Q=O.roomCode&&typeof window<`u`?`${window.location.origin}/game/zhajinhua?room=${O.roomCode}`:``;(0,v.useEffect)(()=>{if(!(!j||!O.userIdentity||!k||!M))for(let e of O.roomEvents){let t=e.event;if(!t||t.event!==`deal:private`)continue;let n=t.payload;if(n.roundId!==j.roundId||!Y(n.recipient,O.userIdentity.address))continue;let r=d(n.encrypted||``,{senderPublicKey:n.senderPublicKey||``,recipientPrivateKey:k.private_key});if(r)try{let e=JSON.parse(r);Array.isArray(e)&&S(t=>({...t,[j.roundId]:e.map(String)}))}catch{}}},[j?.roundId,O.roomEvents,O.userIdentity,M,k?.private_key]),(0,v.useEffect)(()=>{if(j?.status===`finished`&&j.winner){C(!0);let e=setTimeout(()=>C(!1),5e3);return()=>clearTimeout(e)}},[j?.finishedAt,j?.status,j?.winner]),(0,v.useEffect)(()=>{if(j?.lastCompare?.timestamp){T(!0);let e=setTimeout(()=>T(!1),5e3);return()=>clearTimeout(e)}else T(!1)},[j?.lastCompare?.timestamp,j?.roundId]),(0,v.useEffect)(()=>{if(!F||!j||j.status!==`playing`)return;let e=E.current;if(!e)return;let t=O.roomEvents.filter(e=>{let t=e.event;if(!t||t.event!==`player:action`)return!1;let n=t.payload.actionEvent;return!(!n||n.roundId!==j.roundId||D.current.has(n.eventId)||j.appliedEventIds?.includes(n.eventId))});if(t.length===0)return;let n=!1;async function r(){let r=he(j,e);if(r)for(let e of t){if(n)return;let t=(e.event?.payload).actionEvent,i=L(r,t,e.message.author);if(!i.ok){let n=e.message.author;if(!Y(n,O.userIdentity?.address)&&r.status===`playing`&&Y(r.turnAddress,n)){let e=L(r,P({roundId:r.roundId,action:`call`,amount:void 0,target:void 0}),n);if(e.ok)i=e;else{let e=L(r,P({roundId:r.roundId,action:`fold`,amount:void 0,target:void 0}),n);e.ok&&(i=e)}}if(!i.ok){D.current.add(t.eventId);continue}}if(r=i.state,E.current=i.state.hands,await De(i.state)&&D.current.add(t.eventId),i.state.status===`finished`)break}}return r(),()=>{n=!0}},[j?.roundId,j?.seq,j?.status,O.roomEvents,F]);async function we(){await O.createRoom()&&t(e(`game.toast.roomCreated`),`success`)}async function Te(n){n.preventDefault(),await O.joinRoom(i)&&t(e(`game.toast.joinedRoom`),`success`)}async function Ee(){Q&&(await navigator.clipboard.writeText(Q),l(!0),setTimeout(()=>l(!1),1400))}async function De(e){return O.sendRoomEvent(`room:state`,{round:me(e),seq:e.seq})}async function Oe(){if(!O.userIdentity||!k||!X){t(e(`game.zhajinhua.error.notEnoughPlayers`),`error`);return}try{let n=A.players.map(e=>({...e,chips:j?.players.find(t=>Y(t.address,e.address))?.chips??1e3})),i=pe({roomCode:O.roomCode,players:n,hostAddress:O.userIdentity.address,previousSeq:j?.seq||0,previousWinner:j?.winner||``});E.current=i.hands,D.current.clear(),await De(i);for(let e of i.players){let t=r(JSON.stringify(i.hands[e.address]),{senderPrivateKey:k.private_key,recipientPublicKey:e.publicKey});await O.sendRoomEvent(`deal:private`,{roundId:i.roundId,recipient:e.address,senderPublicKey:k.public_key,encrypted:t})}S(e=>({...e,[i.roundId]:i.hands[O.userIdentity.address.toLowerCase()]})),t(e(`game.zhajinhua.toast.roundStarted`),`success`)}catch(n){t(n instanceof Error?n.message:e(`game.zhajinhua.error.startFailed`),`error`)}}async function $(e,t={}){if(!j||!O.userIdentity)return;let n=P({roundId:j.roundId,action:e,amount:t.amount,target:t.target});await O.sendRoomEvent(`player:action`,{actionEvent:n})}let ke=j?.status===`playing`?Y(j.turnAddress,I)?e(`game.zhajinhua.status.yourTurn`):j.turnAddress?e(`game.zhajinhua.status.waitingPlayer`,{player:Z(j.turnAddress,A.players,O.presenceByAddress)}):e(`game.status.playing`):j?.status===`finished`?e(`game.status.finished`):e(`game.status.waitingStart`),Ae=W.filter(e=>!Y(e.address,I));return(0,K.jsx)(g,{sidebar:({closeSidebar:e})=>(0,K.jsx)(te,{activeGame:`zhajinhua`,closeSidebar:e}),headerTitle:(0,K.jsx)(`h2`,{className:`header-title`,children:e(`game.zhajinhua.title`)}),headerRight:(0,K.jsx)(`div`,{className:G.headerActions,children:O.roomCode&&(0,K.jsxs)(`button`,{className:`btn btn-sm`,onClick:Ee,children:[(0,K.jsx)(h,{size:14}),e(c?`common.copied`:`game.action.shareRoom`)]})}),children:(0,K.jsx)(`main`,{className:G.page,children:O.roomCode?(0,K.jsxs)(`div`,{className:G.board,children:[(0,K.jsxs)(`section`,{className:G.table,children:[j?.status===`finished`&&j.winner&&de&&(0,K.jsxs)(`div`,{className:G.finishBanner,children:[(0,K.jsx)(`span`,{className:G.finishBannerIcon,children:`🏆`}),(0,K.jsx)(`span`,{children:e(`game.zhajinhua.result.winChips`,{player:Z(j.winner,A.players,O.presenceByAddress),amount:j.winAmount??0})})]}),j?.lastCompare&&w&&(0,K.jsx)(Se,{lastCompare:j.lastCompare,compareReveal:j.compareReveal||{},myAddress:I,myDealtHand:V,lobbyPlayers:A.players,presenceByAddress:O.presenceByAddress,onClose:()=>T(!1)}),(0,K.jsxs)(`div`,{className:G.tableCenter,children:[(0,K.jsx)(`span`,{children:e(`game.zhajinhua.pot`)}),(0,K.jsx)(`strong`,{children:j?.pot||0}),(0,K.jsx)(`small`,{children:e(`game.zhajinhua.currentBet`,{amount:j?.currentBet||0})})]}),(0,K.jsx)(`div`,{className:G.seats,children:A.players.map(t=>{let n=j?.players.find(e=>Y(e.address,t.address)),r=Ce(t,O.presenceByAddress,O.onlineAddresses),i=j?.turnAddress===t.address,a=j?.winner===t.address,o=n?.status===`folded`;return(0,K.jsxs)(`div`,{className:J(G.seat,i&&G.seatTurn,a&&G.seatWinner,o&&G.seatFolded),children:[(0,K.jsxs)(`div`,{className:J(G.seatAvatar,!r.online&&G.seatAvatarOffline),children:[(0,K.jsx)(`img`,{src:oe(t.address,r.avatar),alt:``}),r.online&&(0,K.jsx)(`span`,{className:G.onlineDot})]}),(0,K.jsxs)(`div`,{className:G.seatMain,children:[(0,K.jsx)(`strong`,{translate:`no`,children:r.name}),(0,K.jsx)(`span`,{translate:`no`,children:ye(t.address)})]}),(0,K.jsxs)(`div`,{className:G.seatMeta,children:[(0,K.jsx)(`span`,{children:e(`game.zhajinhua.chips`,{amount:n?.chips??1e3})}),(0,K.jsx)(`span`,{children:n?.status===`folded`?e(`game.zhajinhua.player.folded`):n?.looked?e(`game.zhajinhua.player.looked`):e(j?`game.zhajinhua.player.inRound`:`game.status.waitingStart`)})]})]},t.address)})})]}),(0,K.jsxs)(`aside`,{className:G.panel,children:[(0,K.jsxs)(`div`,{className:G.panelSection,children:[(0,K.jsxs)(`div`,{className:G.panelTitle,children:[(0,K.jsx)(_,{size:16}),(0,K.jsx)(`span`,{children:e(`game.zhajinhua.myHand`)})]}),(0,K.jsx)(`div`,{className:G.hand,children:H?H.map(e=>{let t=xe(e),n=`${t.suit}${t.rank}`;return(0,K.jsxs)(`div`,{className:J(G.card,G[t.color]),children:[(0,K.jsx)(`span`,{children:n}),(0,K.jsx)(`i`,{children:t.suit})]},e)}):[0,1,2].map(e=>(0,K.jsx)(`div`,{className:G.cardBack,children:(0,K.jsx)(_,{size:18})},e))}),(0,K.jsx)(`p`,{className:G.handLabel,children:H?N(H):e(V?`game.zhajinhua.hand.unlooked`:`game.zhajinhua.hand.waitingDeal`)})]}),(0,K.jsxs)(`div`,{className:G.panelSection,children:[(0,K.jsxs)(`div`,{className:G.panelTitle,children:[(0,K.jsx)(ee,{size:16}),(0,K.jsx)(`span`,{children:e(`game.actions`)})]}),F?(0,K.jsxs)(`button`,{className:`btn btn-primary btn-full`,onClick:Oe,disabled:!X||j?.status===`playing`,children:[(0,K.jsx)(ce,{size:16}),j?.status===`finished`?e(`game.action.nextRound`):e(`game.action.startRound`)]}):(0,K.jsx)(`p`,{className:G.muted,children:e(`game.waitingHost`)}),F&&j?.status===`finished`&&!X&&(0,K.jsx)(`p`,{className:G.muted,children:e(`game.zhajinhua.error.tooManyLowChips`)}),(0,K.jsxs)(`div`,{className:G.actionGrid,children:[(0,K.jsxs)(`button`,{className:`btn btn-secondary`,disabled:!U.includes(`look`),onClick:()=>$(`look`),children:[(0,K.jsx)(se,{size:16}),e(`game.zhajinhua.action.look`)]}),(0,K.jsx)(`button`,{className:`btn btn-secondary`,disabled:!U.includes(`call`),onClick:()=>$(`call`),children:e(`game.zhajinhua.action.call`)}),(0,K.jsx)(`button`,{className:`btn btn-secondary`,disabled:!U.includes(`fold`),onClick:()=>$(`fold`),children:e(`game.zhajinhua.action.fold`)})]}),(0,K.jsxs)(`div`,{className:G.raiseRow,children:[(0,K.jsx)(`select`,{className:`input input-compact`,value:m,onChange:e=>b(Number(e.target.value)),children:y.map(t=>(0,K.jsx)(`option`,{value:t,children:e(`game.zhajinhua.action.raiseOption`,{amount:t})},t))}),(0,K.jsx)(`button`,{className:`btn btn-secondary`,disabled:!U.includes(`raise`),onClick:()=>$(`raise`,{amount:m}),children:e(`game.zhajinhua.action.raise`)})]}),(0,K.jsxs)(`div`,{className:G.raiseRow,children:[(0,K.jsxs)(`select`,{className:`input input-compact`,value:x,onChange:e=>le(e.target.value),children:[(0,K.jsx)(`option`,{value:``,children:e(`game.zhajinhua.action.comparePlaceholder`)}),Ae.map(e=>(0,K.jsx)(`option`,{value:e.address,children:Z(e.address,Ae,O.presenceByAddress)},e.address))]}),(0,K.jsx)(`button`,{className:`btn btn-secondary`,disabled:!U.includes(`compare`)||!x,onClick:()=>$(`compare`,{target:x}),children:e(`game.zhajinhua.action.compare`)})]})]}),(0,K.jsxs)(`div`,{className:G.panelSection,children:[(0,K.jsx)(`div`,{className:G.panelTitle,children:e(`game.status.title`)}),(0,K.jsxs)(`div`,{className:G.statusGrid,children:[(0,K.jsx)(`span`,{children:e(`game.host`)}),(0,K.jsx)(`strong`,{children:M?ye(M):`-`}),(0,K.jsx)(`span`,{children:e(`game.zhajinhua.myChips`)}),(0,K.jsx)(`strong`,{children:B?.chips??1e3}),(0,K.jsx)(`span`,{children:e(`game.round`)}),(0,K.jsx)(`strong`,{children:ke}),(0,K.jsx)(`span`,{children:e(`game.hint`)}),(0,K.jsx)(`strong`,{children:j?.lastAction||e(`game.waitingPlayers`)})]})]})]})]}):(0,K.jsxs)(`section`,{className:G.entry,children:[(0,K.jsxs)(`div`,{className:G.entryBrand,children:[(0,K.jsx)(`div`,{className:G.cardMark,children:(0,K.jsx)(_,{size:48})}),(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`h1`,{children:e(`game.zhajinhua.hero.title`)}),(0,K.jsx)(`p`,{children:e(`game.hero.desc`)})]})]}),(0,K.jsxs)(`div`,{className:G.entryPanel,children:[(0,K.jsxs)(`div`,{className:G.accountLine,children:[(0,K.jsx)(`span`,{children:e(`game.currentAccount`)}),(0,K.jsx)(`strong`,{translate:`no`,children:O.userIdentity?.displayName||e(`web3.notSignedIn`)})]}),(0,K.jsxs)(`button`,{className:`btn btn-primary`,disabled:O.joining,onClick:we,children:[(0,K.jsx)(ee,{size:16}),e(`game.action.createRoom`)]}),(0,K.jsxs)(`form`,{onSubmit:Te,className:G.joinForm,children:[(0,K.jsxs)(`label`,{children:[e(`game.roomCode`),(0,K.jsx)(`input`,{value:i,maxLength:8,onChange:e=>o(e.target.value.toUpperCase()),placeholder:e(`game.roomCode.placeholder`)})]}),(0,K.jsx)(`button`,{className:`btn`,disabled:O.joining||!i,children:e(`game.action.joinRoom`)})]}),(0,K.jsx)(`p`,{className:G.status,children:O.isBackendReady?e(`game.status.nodeConnected`):e(`game.status.nodeConnecting`)})]})]})})})}function Se({lastCompare:e,compareReveal:t,myAddress:n,myDealtHand:r,lobbyPlayers:i,presenceByAddress:a,onClose:o}){let{t:s}=ae(),c=Z(e.initiator,i,a),l=Z(e.target,i,a),u=Z(e.winner,i,a),d=Y(n,e.initiator),f=Y(n,e.target),p=d||f;function m(e,i){return t[e]||(p&&Y(e,n)&&i&&r?r:null)}let h=m(e.initiator,e.initiatorLooked),g=m(e.target,e.targetLooked);return(0,K.jsx)(`div`,{className:G.compareOverlay,onClick:o,children:(0,K.jsxs)(`div`,{className:G.compareBox,onClick:e=>e.stopPropagation(),children:[(0,K.jsx)(`div`,{className:G.compareTitle,children:s(`game.zhajinhua.compareResult`)}),(0,K.jsxs)(`div`,{className:G.comparePlayers,children:[(0,K.jsxs)(`div`,{className:J(G.compareSide,Y(e.winner,e.initiator)&&G.compareWinner),children:[(0,K.jsx)(`div`,{className:G.compareName,children:c}),(0,K.jsx)(`div`,{className:G.compareCards,children:h?h.map(e=>{let t=xe(e);return(0,K.jsxs)(`div`,{className:J(G.card,G[t.color]),children:[(0,K.jsx)(`span`,{children:t.rank}),(0,K.jsx)(`i`,{children:t.suit})]},e)}):[0,1,2].map(e=>(0,K.jsx)(`div`,{className:G.cardBack,children:(0,K.jsx)(_,{size:18})},e))}),h&&(0,K.jsx)(`div`,{className:G.compareLabel,children:N(h)})]}),(0,K.jsx)(`div`,{className:G.compareVs,children:`VS`}),(0,K.jsxs)(`div`,{className:J(G.compareSide,Y(e.winner,e.target)&&G.compareWinner),children:[(0,K.jsx)(`div`,{className:G.compareName,children:l}),(0,K.jsx)(`div`,{className:G.compareCards,children:g?g.map(e=>{let t=xe(e);return(0,K.jsxs)(`div`,{className:J(G.card,G[t.color]),children:[(0,K.jsx)(`span`,{children:t.rank}),(0,K.jsx)(`i`,{children:t.suit})]},e)}):[0,1,2].map(e=>(0,K.jsx)(`div`,{className:G.cardBack,children:(0,K.jsx)(_,{size:18})},e))}),g&&(0,K.jsx)(`div`,{className:G.compareLabel,children:N(g)})]})]}),(0,K.jsx)(`div`,{className:G.compareResult,children:s(`game.zhajinhua.result.winner`,{player:u})}),(0,K.jsx)(`button`,{className:`btn btn-sm`,onClick:o,children:s(`common.close`)})]})})}function Z(e,t,n){let r=Q(e);return n.get(r)?.displayName||t.find(e=>Q(e.address)===r)?.name||ye(e)}function Q(e=``){return String(e||``).trim().toLowerCase()}function Ce(e,t,n){let r=Q(e.address),i=t.get(r);return{name:Z(e.address,[e],t),avatar:i?.avatar||e.avatar||``,online:r?n.has(r):!1}}var we=o(`/game/zhajinhua/`)({component:X});export{we as Route};
1
+ import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{A as r,B as i,E as a,H as o,O as s,_ as c,g as l,h as u,k as d,t as f,x as p,y as m}from"./useAppStore-DOnk608w.js";import{t as h}from"./copy-B7pPZ2MP.js";import{n as g}from"./AppTop-Cy0ZOCxO.js";import{t as ee}from"./play-CvWKSMwY.js";import{a as _,i as te,n as ne,r as re,t as ie}from"./useGameRoom-CS1w4IqP.js";import{A as ae,f as oe,w as se}from"./index-D0Uk9-58.js";var ce=i(`refresh-ccw`,[[`path`,{d:`M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`14sxne`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}],[`path`,{d:`M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16`,key:`1hlbsb`}],[`path`,{d:`M16 16h5v5`,key:`ccwih5`}]]),v=t(e(),1),y=[10,20,50,100],b=[`2`,`3`,`4`,`5`,`6`,`7`,`8`,`9`,`10`,`J`,`Q`,`K`,`A`],x=[`D`,`C`,`H`,`S`],le=new Map(b.map((e,t)=>[e,t+2])),ue=new Map(x.map((e,t)=>[e,t+1])),S={high:1,pair:2,straight:3,flush:4,straightFlush:5,triple:6},de={[S.high]:`散牌`,[S.pair]:`对子`,[S.straight]:`顺子`,[S.flush]:`金花`,[S.straightFlush]:`顺金`,[S.triple]:`豹子`};function C(e){return m(e)}function w(e=`zhajinhua`){return u(e)}function T(){return w(`round`)}function E(){let e=[];for(let t of x)for(let n of b)e.push(`${n}${t}`);return e}function D(e=E(),t=Math.random){let n=[...e];for(let e=n.length-1;e>0;e--){let r=Math.floor(t()*(e+1));[n[e],n[r]]=[n[r],n[e]]}return n}function O(e){let t=String(e||``).trim().toUpperCase(),n=t.slice(-1),r=t.slice(0,-1);if(!le.has(r)||!ue.has(n))throw Error(`Invalid card: ${e}`);return{id:`${r}${n}`,rank:r,suit:n,rankValue:le.get(r),suitValue:ue.get(n)}}function k(e,t){let n=Math.max(e.length,t.length);for(let r=0;r<n;r++){let n=e[r]||0,i=t[r]||0;if(n!==i)return n-i}return 0}function A(e){let t=[...new Set(e)].sort((e,t)=>e-t);return t.length===3?t[0]===2&&t[1]===3&&t[2]===14?3:t[0]+1===t[1]&&t[1]+1===t[2]?t[2]:0:0}function j(e){if(!Array.isArray(e)||e.length!==3)throw Error(`炸金花手牌必须是 3 张牌`);let t=e.map(O),n=t.map(e=>e.rankValue),r=new Map;for(let e of n)r.set(e,(r.get(e)||0)+1);let i=new Set(t.map(e=>e.suit)).size===1,a=A(n),o=[...n].sort((e,t)=>t-e),s=Math.max(...t.map(e=>e.suitValue)),c=S.high,l=o;return r.size===1?(c=S.triple,l=[o[0]]):a&&i?(c=S.straightFlush,l=[a]):i?(c=S.flush,l=o):a?(c=S.straight,l=[a]):r.size===2&&(c=S.pair,l=[[...r.entries()].find(([,e])=>e===2)[0],[...r.entries()].find(([,e])=>e===1)[0]]),{category:c,label:de[c],tiebreakers:l,tieSuit:s,cards:t.map(e=>e.id)}}function M(e,t){let n=j(e),r=j(t);if(n.category!==r.category)return n.category-r.category;let i=k(n.tiebreakers,r.tiebreakers);return i===0?n.tieSuit-r.tieSuit:i}function N(e){return j(e).label}function P({roundId:e,action:t,amount:n,target:r}){return{roundId:e,eventId:w(`action`),action:t,amount:n,target:r}}function fe(e=[]){let t=e.filter(e=>Number(e.chips)>=10);return t.length>=2&&t.length<=5}function pe({roomCode:e,players:t,hostAddress:n,previousSeq:r=0,previousWinner:i=``,roundId:a=T(),random:o=Math.random}){let s=t.filter(e=>Number(e.chips)>=10).slice(0,5);if(s.length<2)throw Error(`至少需要 2 名有足够筹码的玩家`);let u=D(E(),o),d={},f=s.map((e,t)=>{let n=u.slice(t*3,t*3+3);return d[e.address]=n,{address:e.address,name:e.name,avatar:c(e.avatar),publicKey:e.publicKey,chips:Number(e.chips)-10,status:`active`,looked:!1,bet:10}}),p,m=l(i),h=m?f.findIndex(e=>l(e.address)===m):-1;return p=h>=0?f[h].address:f[Math.floor(o()*f.length)].address,{roomCode:C(e),roundId:a,status:`playing`,host:l(n),seq:r+1,startedAt:Date.now(),ante:10,pot:10*f.length,currentBet:10,turnAddress:p,players:f,lastAction:`本局开始`,winner:null,showdown:null,appliedEventIds:[],hands:d,actionCounts:{},compareReveal:{}}}function me(e){if(!e)return null;let t={...e};return delete t.hands,W(t)}function he(e,t){let n=F(e);return!n||!t||typeof t!=`object`?null:{...n,hands:W(t)}}function F(e){return!e||typeof e!=`object`||!e.roundId||!Array.isArray(e.players)?null:{roomCode:C(e.roomCode),roundId:String(e.roundId),status:e.status===`finished`?`finished`:`playing`,host:l(e.host),seq:Number(e.seq)||1,startedAt:Number(e.startedAt)||Date.now(),ante:Number(e.ante)||10,pot:Math.max(0,Number(e.pot)||0),currentBet:Math.max(0,Number(e.currentBet)||10),turnAddress:l(e.turnAddress),players:e.players.map(U).filter(Boolean),lastAction:String(e.lastAction||``),winner:e.winner?l(e.winner):null,showdown:e.showdown&&typeof e.showdown==`object`?W(e.showdown):null,appliedEventIds:Array.isArray(e.appliedEventIds)?e.appliedEventIds.map(String):[],actionCounts:e.actionCounts&&typeof e.actionCounts==`object`?W(e.actionCounts):{},compareReveal:e.compareReveal&&typeof e.compareReveal==`object`?W(e.compareReveal):{},lastCompare:e.lastCompare&&typeof e.lastCompare==`object`?W(e.lastCompare):null,finishedAt:e.finishedAt?Number(e.finishedAt):null}}function I(e,t,n){let r=F(e);if(!r||r.status!==`playing`)return{ok:!1,error:`当前没有进行中的牌局`};let i=l(n),a=r.players.find(e=>e.address===i);if(!a||a.status!==`active`)return{ok:!1,error:`玩家不在本轮牌局中`};if(r.turnAddress!==i)return{ok:!1,error:`还没有轮到你操作`};let o=t?.action;if(![`look`,`call`,`raise`,`compare`,`fold`].includes(o))return{ok:!1,error:`未知操作`};if(o===`look`)return a.looked?{ok:!1,error:`已经看过牌`}:{ok:!0};if(o===`call`)return a.chips>=10?{ok:!0}:{ok:!1,error:`筹码不足,不能跟注`};if(o===`raise`){let e=Number(t.amount);if(!y.includes(e))return{ok:!1,error:`加注档位无效`};let n=r.currentBet+e-a.bet;return a.chips>=n?{ok:!0}:{ok:!1,error:`筹码不足,不能加注`}}if(o===`compare`){let e=l(t.target),n=r.players.find(t=>t.address===e);if(!e||e===i||!n||n.status!==`active`)return{ok:!1,error:`请选择有效的比牌对象`};if(!r.players.filter(e=>e.status===`active`).every(e=>(r.actionCounts?.[e.address]||0)>=1))return{ok:!1,error:`第一轮不能比牌,请先跟注或加注`};let o=Math.max(0,r.currentBet-a.bet);return a.chips>=o?{ok:!0}:{ok:!1,error:`筹码不足,不能比牌`}}return{ok:!0}}function L(e,t,n){let r=I(e,t,n);if(!r.ok)return{ok:!1,error:r.error,state:e};let i=W(e),a=l(n),o=i.players.find(e=>e.address===a),s=String(t.eventId);if(i.appliedEventIds?.includes(s))return{ok:!0,state:i,duplicate:!0};if(Array.isArray(i.appliedEventIds)||(i.appliedEventIds=[]),i.appliedEventIds.push(s),t.action===`look`)return o.looked=!0,i.lastAction=`${o.name} 看牌`,H(i);if(t.action===`fold`)return o.status=`folded`,i.lastAction=`${o.name} 弃牌`,B(i,a),V(i,a);if(t.action===`call`)return o.chips-=10,o.bet+=10,i.pot+=10,i.lastAction=`${o.name} 跟注`,B(i,a),V(i,a);if(t.action===`raise`){let e=Number(t.amount);return i.currentBet+=e,z(i,o),i.lastAction=`${o.name} 加注 ${e}`,B(i,a),V(i,a)}if(t.action===`compare`){z(i,o);let e=l(t.target),n=i.players.find(t=>t.address===e),r=o.looked,s=n.looked,c=M(i.hands?.[a]||[],i.hands?.[e]||[]),u=c>=0?o:n,d=c>=0?n:o;d.status=`folded`,d.looked=!0,i.compareReveal||={};let f=r&&s,p=!r&&!s;if(f)i.compareReveal[a]=i.hands?.[e]||[],i.compareReveal[e]=i.hands?.[a]||[];else if(p)i.compareReveal[d.address]=i.hands?.[u.address]||[];else{let e=r?o:n,t=r?n:o;i.compareReveal[e.address]=i.hands?.[t.address]||[],i.compareReveal[d.address]=i.hands?.[u.address]||[]}return i.lastCompare={initiator:a,target:e,winner:u.address,loser:d.address,initiatorLooked:r,targetLooked:s,timestamp:Date.now()},i.lastAction=`${o.name} 与 ${n.name} 比牌,${d.name} 出局`,B(i,a),V(i,a)}return{ok:!1,error:`未知操作`,state:e}}function R(e){return(e?.players||[]).filter(e=>e.status===`active`)}function ge(e,t){let n=(e?.players||[]).find(e=>e.address===l(t));if(!e||e.status!==`playing`||!n||n.status!==`active`||e.turnAddress!==n.address)return[];let r=[];return n.looked||r.push(`look`),I(e,{action:`call`},n.address).ok&&r.push(`call`),y.some(t=>I(e,{action:`raise`,amount:t},n.address).ok)&&r.push(`raise`),R(e).length>1&&e.players.filter(e=>e.status===`active`).every(t=>(e.actionCounts?.[t.address]||0)>=1)&&r.push(`compare`),r.push(`fold`),r}function z(e,t){let n=Math.max(0,e.currentBet-t.bet);t.chips-=n,t.bet+=n,e.pot+=n}function B(e,t){e.actionCounts||={},e.actionCounts[t]=(e.actionCounts[t]||0)+1}function V(e,t){let n=R(e);return n.length===1?_e(e,n[0].address):(e.turnAddress=ve(e,t),H(e))}function _e(e,t){let n=e.players.find(e=>e.address===t),r=e.pot;return n&&(n.chips+=e.pot),e.status=`finished`,e.winner=t,e.winAmount=r,e.turnAddress=``,e.showdown=e.hands?W(e.hands):null,e.lastAction=n?`${n.name} 赢得 ${r} 筹码`:`本局结束`,e.pot=0,e.finishedAt=Date.now(),H(e)}function ve(e,t){let n=e.players,r=Math.max(0,n.findIndex(e=>e.address===l(t)));for(let e=1;e<=n.length;e++){let t=n[(r+e)%n.length];if(t.status===`active`)return t.address}return``}function H(e){return e.seq=Number(e.seq||0)+1,{ok:!0,state:e}}function U(e){if(!e||typeof e!=`object`)return null;let t=l(e.address);return t?{address:t,name:String(e.name||p(t)).slice(0,50),avatar:c(e.avatar),publicKey:String(e.publicKey||``),chips:Math.max(0,Number(e.chips)||0),status:e.status===`folded`?`folded`:`active`,looked:e.looked===!0,bet:Math.max(0,Number(e.bet)||0)}:null}function W(e){return JSON.parse(JSON.stringify(e))}var G={page:`_page_p8eol_1`,headerActions:`_headerActions_p8eol_12`,entry:`_entry_p8eol_18`,entryBrand:`_entryBrand_p8eol_28`,cardMark:`_cardMark_p8eol_34`,entryPanel:`_entryPanel_p8eol_62`,accountLine:`_accountLine_p8eol_72`,joinForm:`_joinForm_p8eol_89`,status:`_status_p8eol_110`,board:`_board_p8eol_116`,table:`_table_p8eol_123`,tableCenter:`_tableCenter_p8eol_144`,finishBanner:`_finishBanner_p8eol_173`,finishBannerIcon:`_finishBannerIcon_p8eol_192`,seats:`_seats_p8eol_196`,seat:`_seat_p8eol_196`,seatTurn:`_seatTurn_p8eol_218`,seatWinner:`_seatWinner_p8eol_223`,seatFolded:`_seatFolded_p8eol_228`,seatAvatar:`_seatAvatar_p8eol_232`,seatAvatarOffline:`_seatAvatarOffline_p8eol_252`,onlineDot:`_onlineDot_p8eol_257`,seatMain:`_seatMain_p8eol_269`,seatMeta:`_seatMeta_p8eol_270`,panel:`_panel_p8eol_301`,panelSection:`_panelSection_p8eol_308`,panelTitle:`_panelTitle_p8eol_318`,hand:`_hand_p8eol_328`,card:`_card_p8eol_34`,red:`_red_p8eol_362`,black:`_black_p8eol_366`,cardBack:`_cardBack_p8eol_370`,handLabel:`_handLabel_p8eol_391`,actionGrid:`_actionGrid_p8eol_398`,raiseRow:`_raiseRow_p8eol_399`,statusGrid:`_statusGrid_p8eol_410`,muted:`_muted_p8eol_428`,compareOverlay:`_compareOverlay_p8eol_435`,compareBox:`_compareBox_p8eol_447`,compareTitle:`_compareTitle_p8eol_461`,comparePlayers:`_comparePlayers_p8eol_467`,compareSide:`_compareSide_p8eol_474`,compareWinner:`_compareWinner_p8eol_486`,compareName:`_compareName_p8eol_491`,compareCards:`_compareCards_p8eol_502`,compareLabel:`_compareLabel_p8eol_527`,compareVs:`_compareVs_p8eol_533`,compareResult:`_compareResult_p8eol_540`},K=n(),q=`zhajinhua`;function J(...e){return e.filter(Boolean).join(` `)}function Y(e,t){return String(e||``).toLowerCase()===String(t||``).toLowerCase()}function ye(e=``){return e?`${e.slice(0,6)}...${e.slice(-4)}`:``}function be(e){return e.displayName||e.username}function xe(e){let t=String(e||``),n=t.slice(-1);return{rank:t.slice(0,-1),suit:{S:`♠`,H:`♥`,C:`♣`,D:`♦`}[n]||n,color:n===`H`||n===`D`?`red`:`black`}}function X(){let{t:e}=ae(),t=f(e=>e.addToast),n=a(e=>e.initializeUser),[i,o]=(0,v.useState)(``),[c,l]=(0,v.useState)(!1),u=(0,v.useRef)(``),p=(0,v.useRef)(!1),[m,b]=(0,v.useState)(20),[x,le]=(0,v.useState)(``),[ue,S]=(0,v.useState)({}),[de,C]=(0,v.useState)(!0),[w,T]=(0,v.useState)(!1),E=(0,v.useRef)(null),D=(0,v.useRef)(new Set),O=ie({gameId:q,onError:e=>t(e,`error`),getPlayerPayload:e=>{let t=s(e.danger);return{address:e.address,name:be(e),avatar:e.avatar||``,publicKey:t.public_key,joinedAt:Date.now()}}}),k=(0,v.useMemo)(()=>O.userIdentity?.danger?s(O.userIdentity.danger):null,[O.userIdentity?.danger]);(0,v.useEffect)(()=>{n()},[n]),(0,v.useEffect)(()=>{let e=new URLSearchParams(window.location.search).get(`room`)?.toUpperCase();e&&(o(e),u.current=e)},[]),(0,v.useEffect)(()=>{let n=u.current;!n||p.current||!O.isBackendReady||!O.userIdentity||(p.current=!0,u.current=``,O.joinRoom(n).then(n=>{n&&t(e(`game.toast.joinedRoom`),`success`)}))},[O.isBackendReady,O.userIdentity,O.joinRoom,t,e]),(0,v.useEffect)(()=>{if(!O.roomCode)return;let e=`/game/zhajinhua?room=${O.roomCode}`;`${window.location.pathname}${window.location.search}`!==e&&window.history.replaceState(null,``,e)},[O.roomCode]);let A=(0,v.useMemo)(()=>ne(O.messages,{gameId:q,roomCode:O.roomCode}),[O.messages,O.roomCode]),j=(0,v.useMemo)(()=>re(O.messages,{gameId:q,roomCode:O.roomCode}),[O.messages,O.roomCode])?.payload?.round||null,M=j?.host||A.hostAddress,F=Y(M,O.userIdentity?.address),I=O.userIdentity?.address?.toLowerCase()||``,z=j?.players.find(e=>Y(e.address,I)),B=z||A.players.find(e=>Y(e.address,I)),V=ue[j?.roundId||``]||null,_e=j?.showdown&&I?j.showdown[I]:null,ve=j?.compareReveal&&I?j.compareReveal[I]:null,H=_e||ve||(z?.looked?V:null),U=ge(j,I),W=R(j),X=F&&fe(A.players.map(e=>({...e,chips:j?.players.find(t=>Y(t.address,e.address))?.chips??1e3}))),Q=O.roomCode&&typeof window<`u`?`${window.location.origin}/game/zhajinhua?room=${O.roomCode}`:``;(0,v.useEffect)(()=>{if(!(!j||!O.userIdentity||!k||!M))for(let e of O.roomEvents){let t=e.event;if(!t||t.event!==`deal:private`)continue;let n=t.payload;if(n.roundId!==j.roundId||!Y(n.recipient,O.userIdentity.address))continue;let r=d(n.encrypted||``,{senderPublicKey:n.senderPublicKey||``,recipientPrivateKey:k.private_key});if(r)try{let e=JSON.parse(r);Array.isArray(e)&&S(t=>({...t,[j.roundId]:e.map(String)}))}catch{}}},[j?.roundId,O.roomEvents,O.userIdentity,M,k?.private_key]),(0,v.useEffect)(()=>{if(j?.status===`finished`&&j.winner){C(!0);let e=setTimeout(()=>C(!1),5e3);return()=>clearTimeout(e)}},[j?.finishedAt,j?.status,j?.winner]),(0,v.useEffect)(()=>{if(j?.lastCompare?.timestamp){T(!0);let e=setTimeout(()=>T(!1),5e3);return()=>clearTimeout(e)}else T(!1)},[j?.lastCompare?.timestamp,j?.roundId]),(0,v.useEffect)(()=>{if(!F||!j||j.status!==`playing`)return;let e=E.current;if(!e)return;let t=O.roomEvents.filter(e=>{let t=e.event;if(!t||t.event!==`player:action`)return!1;let n=t.payload.actionEvent;return!(!n||n.roundId!==j.roundId||D.current.has(n.eventId)||j.appliedEventIds?.includes(n.eventId))});if(t.length===0)return;let n=!1;async function r(){let r=he(j,e);if(r)for(let e of t){if(n)return;let t=(e.event?.payload).actionEvent,i=L(r,t,e.message.author);if(!i.ok){let n=e.message.author;if(!Y(n,O.userIdentity?.address)&&r.status===`playing`&&Y(r.turnAddress,n)){let e=L(r,P({roundId:r.roundId,action:`call`,amount:void 0,target:void 0}),n);if(e.ok)i=e;else{let e=L(r,P({roundId:r.roundId,action:`fold`,amount:void 0,target:void 0}),n);e.ok&&(i=e)}}if(!i.ok){D.current.add(t.eventId);continue}}if(r=i.state,E.current=i.state.hands,await De(i.state)&&D.current.add(t.eventId),i.state.status===`finished`)break}}return r(),()=>{n=!0}},[j?.roundId,j?.seq,j?.status,O.roomEvents,F]);async function we(){await O.createRoom()&&t(e(`game.toast.roomCreated`),`success`)}async function Te(n){n.preventDefault(),await O.joinRoom(i)&&t(e(`game.toast.joinedRoom`),`success`)}async function Ee(){Q&&(await navigator.clipboard.writeText(Q),l(!0),setTimeout(()=>l(!1),1400))}async function De(e){return O.sendRoomEvent(`room:state`,{round:me(e),seq:e.seq})}async function Oe(){if(!O.userIdentity||!k||!X){t(e(`game.zhajinhua.error.notEnoughPlayers`),`error`);return}try{let n=A.players.map(e=>({...e,chips:j?.players.find(t=>Y(t.address,e.address))?.chips??1e3})),i=pe({roomCode:O.roomCode,players:n,hostAddress:O.userIdentity.address,previousSeq:j?.seq||0,previousWinner:j?.winner||``});E.current=i.hands,D.current.clear(),await De(i);for(let e of i.players){let t=r(JSON.stringify(i.hands[e.address]),{senderPrivateKey:k.private_key,recipientPublicKey:e.publicKey});await O.sendRoomEvent(`deal:private`,{roundId:i.roundId,recipient:e.address,senderPublicKey:k.public_key,encrypted:t})}S(e=>({...e,[i.roundId]:i.hands[O.userIdentity.address.toLowerCase()]})),t(e(`game.zhajinhua.toast.roundStarted`),`success`)}catch(n){t(n instanceof Error?n.message:e(`game.zhajinhua.error.startFailed`),`error`)}}async function $(e,t={}){if(!j||!O.userIdentity)return;let n=P({roundId:j.roundId,action:e,amount:t.amount,target:t.target});await O.sendRoomEvent(`player:action`,{actionEvent:n})}let ke=j?.status===`playing`?Y(j.turnAddress,I)?e(`game.zhajinhua.status.yourTurn`):j.turnAddress?e(`game.zhajinhua.status.waitingPlayer`,{player:Z(j.turnAddress,A.players,O.presenceByAddress)}):e(`game.status.playing`):j?.status===`finished`?e(`game.status.finished`):e(`game.status.waitingStart`),Ae=W.filter(e=>!Y(e.address,I));return(0,K.jsx)(g,{sidebar:({closeSidebar:e})=>(0,K.jsx)(te,{activeGame:`zhajinhua`,closeSidebar:e}),headerTitle:(0,K.jsx)(`h2`,{className:`header-title`,children:e(`game.zhajinhua.title`)}),headerRight:(0,K.jsx)(`div`,{className:G.headerActions,children:O.roomCode&&(0,K.jsxs)(`button`,{className:`btn btn-sm`,onClick:Ee,children:[(0,K.jsx)(h,{size:14}),e(c?`common.copied`:`game.action.shareRoom`)]})}),children:(0,K.jsx)(`main`,{className:G.page,children:O.roomCode?(0,K.jsxs)(`div`,{className:G.board,children:[(0,K.jsxs)(`section`,{className:G.table,children:[j?.status===`finished`&&j.winner&&de&&(0,K.jsxs)(`div`,{className:G.finishBanner,children:[(0,K.jsx)(`span`,{className:G.finishBannerIcon,children:`🏆`}),(0,K.jsx)(`span`,{children:e(`game.zhajinhua.result.winChips`,{player:Z(j.winner,A.players,O.presenceByAddress),amount:j.winAmount??0})})]}),j?.lastCompare&&w&&(0,K.jsx)(Se,{lastCompare:j.lastCompare,compareReveal:j.compareReveal||{},myAddress:I,myDealtHand:V,lobbyPlayers:A.players,presenceByAddress:O.presenceByAddress,onClose:()=>T(!1)}),(0,K.jsxs)(`div`,{className:G.tableCenter,children:[(0,K.jsx)(`span`,{children:e(`game.zhajinhua.pot`)}),(0,K.jsx)(`strong`,{children:j?.pot||0}),(0,K.jsx)(`small`,{children:e(`game.zhajinhua.currentBet`,{amount:j?.currentBet||0})})]}),(0,K.jsx)(`div`,{className:G.seats,children:A.players.map(t=>{let n=j?.players.find(e=>Y(e.address,t.address)),r=Ce(t,O.presenceByAddress,O.onlineAddresses),i=j?.turnAddress===t.address,a=j?.winner===t.address,o=n?.status===`folded`;return(0,K.jsxs)(`div`,{className:J(G.seat,i&&G.seatTurn,a&&G.seatWinner,o&&G.seatFolded),children:[(0,K.jsxs)(`div`,{className:J(G.seatAvatar,!r.online&&G.seatAvatarOffline),children:[(0,K.jsx)(`img`,{src:oe(t.address,r.avatar),alt:``}),r.online&&(0,K.jsx)(`span`,{className:G.onlineDot})]}),(0,K.jsxs)(`div`,{className:G.seatMain,children:[(0,K.jsx)(`strong`,{translate:`no`,children:r.name}),(0,K.jsx)(`span`,{translate:`no`,children:ye(t.address)})]}),(0,K.jsxs)(`div`,{className:G.seatMeta,children:[(0,K.jsx)(`span`,{children:e(`game.zhajinhua.chips`,{amount:n?.chips??1e3})}),(0,K.jsx)(`span`,{children:n?.status===`folded`?e(`game.zhajinhua.player.folded`):n?.looked?e(`game.zhajinhua.player.looked`):e(j?`game.zhajinhua.player.inRound`:`game.status.waitingStart`)})]})]},t.address)})})]}),(0,K.jsxs)(`aside`,{className:G.panel,children:[(0,K.jsxs)(`div`,{className:G.panelSection,children:[(0,K.jsxs)(`div`,{className:G.panelTitle,children:[(0,K.jsx)(_,{size:16}),(0,K.jsx)(`span`,{children:e(`game.zhajinhua.myHand`)})]}),(0,K.jsx)(`div`,{className:G.hand,children:H?H.map(e=>{let t=xe(e),n=`${t.suit}${t.rank}`;return(0,K.jsxs)(`div`,{className:J(G.card,G[t.color]),children:[(0,K.jsx)(`span`,{children:n}),(0,K.jsx)(`i`,{children:t.suit})]},e)}):[0,1,2].map(e=>(0,K.jsx)(`div`,{className:G.cardBack,children:(0,K.jsx)(_,{size:18})},e))}),(0,K.jsx)(`p`,{className:G.handLabel,children:H?N(H):e(V?`game.zhajinhua.hand.unlooked`:`game.zhajinhua.hand.waitingDeal`)})]}),(0,K.jsxs)(`div`,{className:G.panelSection,children:[(0,K.jsxs)(`div`,{className:G.panelTitle,children:[(0,K.jsx)(ee,{size:16}),(0,K.jsx)(`span`,{children:e(`game.actions`)})]}),F?(0,K.jsxs)(`button`,{className:`btn btn-primary btn-full`,onClick:Oe,disabled:!X||j?.status===`playing`,children:[(0,K.jsx)(ce,{size:16}),j?.status===`finished`?e(`game.action.nextRound`):e(`game.action.startRound`)]}):(0,K.jsx)(`p`,{className:G.muted,children:e(`game.waitingHost`)}),F&&j?.status===`finished`&&!X&&(0,K.jsx)(`p`,{className:G.muted,children:e(`game.zhajinhua.error.tooManyLowChips`)}),(0,K.jsxs)(`div`,{className:G.actionGrid,children:[(0,K.jsxs)(`button`,{className:`btn btn-secondary`,disabled:!U.includes(`look`),onClick:()=>$(`look`),children:[(0,K.jsx)(se,{size:16}),e(`game.zhajinhua.action.look`)]}),(0,K.jsx)(`button`,{className:`btn btn-secondary`,disabled:!U.includes(`call`),onClick:()=>$(`call`),children:e(`game.zhajinhua.action.call`)}),(0,K.jsx)(`button`,{className:`btn btn-secondary`,disabled:!U.includes(`fold`),onClick:()=>$(`fold`),children:e(`game.zhajinhua.action.fold`)})]}),(0,K.jsxs)(`div`,{className:G.raiseRow,children:[(0,K.jsx)(`select`,{className:`input input-compact`,value:m,onChange:e=>b(Number(e.target.value)),children:y.map(t=>(0,K.jsx)(`option`,{value:t,children:e(`game.zhajinhua.action.raiseOption`,{amount:t})},t))}),(0,K.jsx)(`button`,{className:`btn btn-secondary`,disabled:!U.includes(`raise`),onClick:()=>$(`raise`,{amount:m}),children:e(`game.zhajinhua.action.raise`)})]}),(0,K.jsxs)(`div`,{className:G.raiseRow,children:[(0,K.jsxs)(`select`,{className:`input input-compact`,value:x,onChange:e=>le(e.target.value),children:[(0,K.jsx)(`option`,{value:``,children:e(`game.zhajinhua.action.comparePlaceholder`)}),Ae.map(e=>(0,K.jsx)(`option`,{value:e.address,children:Z(e.address,Ae,O.presenceByAddress)},e.address))]}),(0,K.jsx)(`button`,{className:`btn btn-secondary`,disabled:!U.includes(`compare`)||!x,onClick:()=>$(`compare`,{target:x}),children:e(`game.zhajinhua.action.compare`)})]})]}),(0,K.jsxs)(`div`,{className:G.panelSection,children:[(0,K.jsx)(`div`,{className:G.panelTitle,children:e(`game.status.title`)}),(0,K.jsxs)(`div`,{className:G.statusGrid,children:[(0,K.jsx)(`span`,{children:e(`game.host`)}),(0,K.jsx)(`strong`,{children:M?ye(M):`-`}),(0,K.jsx)(`span`,{children:e(`game.zhajinhua.myChips`)}),(0,K.jsx)(`strong`,{children:B?.chips??1e3}),(0,K.jsx)(`span`,{children:e(`game.round`)}),(0,K.jsx)(`strong`,{children:ke}),(0,K.jsx)(`span`,{children:e(`game.hint`)}),(0,K.jsx)(`strong`,{children:j?.lastAction||e(`game.waitingPlayers`)})]})]})]})]}):(0,K.jsxs)(`section`,{className:G.entry,children:[(0,K.jsxs)(`div`,{className:G.entryBrand,children:[(0,K.jsx)(`div`,{className:G.cardMark,children:(0,K.jsx)(_,{size:48})}),(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`h1`,{children:e(`game.zhajinhua.hero.title`)}),(0,K.jsx)(`p`,{children:e(`game.hero.desc`)})]})]}),(0,K.jsxs)(`div`,{className:G.entryPanel,children:[(0,K.jsxs)(`div`,{className:G.accountLine,children:[(0,K.jsx)(`span`,{children:e(`game.currentAccount`)}),(0,K.jsx)(`strong`,{translate:`no`,children:O.userIdentity?.displayName||e(`web3.notSignedIn`)})]}),(0,K.jsxs)(`button`,{className:`btn btn-primary`,disabled:O.joining,onClick:we,children:[(0,K.jsx)(ee,{size:16}),e(`game.action.createRoom`)]}),(0,K.jsxs)(`form`,{onSubmit:Te,className:G.joinForm,children:[(0,K.jsxs)(`label`,{children:[e(`game.roomCode`),(0,K.jsx)(`input`,{value:i,maxLength:8,onChange:e=>o(e.target.value.toUpperCase()),placeholder:e(`game.roomCode.placeholder`)})]}),(0,K.jsx)(`button`,{className:`btn`,disabled:O.joining||!i,children:e(`game.action.joinRoom`)})]}),(0,K.jsx)(`p`,{className:G.status,children:O.isBackendReady?e(`game.status.nodeConnected`):e(`game.status.nodeConnecting`)})]})]})})})}function Se({lastCompare:e,compareReveal:t,myAddress:n,myDealtHand:r,lobbyPlayers:i,presenceByAddress:a,onClose:o}){let{t:s}=ae(),c=Z(e.initiator,i,a),l=Z(e.target,i,a),u=Z(e.winner,i,a),d=Y(n,e.initiator),f=Y(n,e.target),p=d||f;function m(e,i){return t[e]||(p&&Y(e,n)&&i&&r?r:null)}let h=m(e.initiator,e.initiatorLooked),g=m(e.target,e.targetLooked);return(0,K.jsx)(`div`,{className:G.compareOverlay,onClick:o,children:(0,K.jsxs)(`div`,{className:G.compareBox,onClick:e=>e.stopPropagation(),children:[(0,K.jsx)(`div`,{className:G.compareTitle,children:s(`game.zhajinhua.compareResult`)}),(0,K.jsxs)(`div`,{className:G.comparePlayers,children:[(0,K.jsxs)(`div`,{className:J(G.compareSide,Y(e.winner,e.initiator)&&G.compareWinner),children:[(0,K.jsx)(`div`,{className:G.compareName,children:c}),(0,K.jsx)(`div`,{className:G.compareCards,children:h?h.map(e=>{let t=xe(e);return(0,K.jsxs)(`div`,{className:J(G.card,G[t.color]),children:[(0,K.jsx)(`span`,{children:t.rank}),(0,K.jsx)(`i`,{children:t.suit})]},e)}):[0,1,2].map(e=>(0,K.jsx)(`div`,{className:G.cardBack,children:(0,K.jsx)(_,{size:18})},e))}),h&&(0,K.jsx)(`div`,{className:G.compareLabel,children:N(h)})]}),(0,K.jsx)(`div`,{className:G.compareVs,children:`VS`}),(0,K.jsxs)(`div`,{className:J(G.compareSide,Y(e.winner,e.target)&&G.compareWinner),children:[(0,K.jsx)(`div`,{className:G.compareName,children:l}),(0,K.jsx)(`div`,{className:G.compareCards,children:g?g.map(e=>{let t=xe(e);return(0,K.jsxs)(`div`,{className:J(G.card,G[t.color]),children:[(0,K.jsx)(`span`,{children:t.rank}),(0,K.jsx)(`i`,{children:t.suit})]},e)}):[0,1,2].map(e=>(0,K.jsx)(`div`,{className:G.cardBack,children:(0,K.jsx)(_,{size:18})},e))}),g&&(0,K.jsx)(`div`,{className:G.compareLabel,children:N(g)})]})]}),(0,K.jsx)(`div`,{className:G.compareResult,children:s(`game.zhajinhua.result.winner`,{player:u})}),(0,K.jsx)(`button`,{className:`btn btn-sm`,onClick:o,children:s(`common.close`)})]})})}function Z(e,t,n){let r=Q(e);return n.get(r)?.displayName||t.find(e=>Q(e.address)===r)?.name||ye(e)}function Q(e=``){return String(e||``).trim().toLowerCase()}function Ce(e,t,n){let r=Q(e.address),i=t.get(r);return{name:Z(e.address,[e],t),avatar:i?.avatar||e.avatar||``,online:r?n.has(r):!1}}var we=o(`/game/zhajinhua/`)({component:X});export{we as Route};
@@ -0,0 +1 @@
1
+ import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{B as r,E as i,H as a,c as o,o as s,t as c,u as l}from"./useAppStore-DOnk608w.js";import{t as ee}from"./OpenSidebarButton-CGhXxQ5Z.js";import{a as te,i as u,n as d,r as f,t as ne}from"./FilePreviewOverlay-faaTnmlN.js";import{t as re}from"./arrow-up-down-B-677ip8.js";import{t as p}from"./check-iBCQl0yr.js";import{t as ie}from"./chevron-right-D75NRNNs.js";import{t as ae}from"./copy-B7pPZ2MP.js";import{t as oe}from"./download-COQOcPqI.js";import{t as se}from"./file-text-DiyIGL1I.js";import{t as m}from"./folder-BS_GbpPQ.js";import{t as ce}from"./loader-CwyHYZdX.js";import{i as le,n as ue,t as de}from"./AppTop-Cy0ZOCxO.js";import{t as h}from"./music-Dn9nm9Qb.js";import{t as fe}from"./search-HW4oPOBP.js";import{t as pe}from"./trash-2-BLwoM0ME.js";import{t as me}from"./upload-DVuXJt_o.js";import{A as he,S as g,_ as ge,v as _e,y as _}from"./index-D0Uk9-58.js";import{t as ve}from"./format-CR8oUWq6.js";import{n as v,r as ye,t as be}from"./downloadValidation-UPgpJbKz.js";var xe=r(`files`,[[`path`,{d:`M15 2h-4a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V8`,key:`14sh0y`}],[`path`,{d:`M16.706 2.706A2.4 2.4 0 0 0 15 2v5a1 1 0 0 0 1 1h5a2.4 2.4 0 0 0-.706-1.706z`,key:`1970lx`}],[`path`,{d:`M5 7a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 1.732-1`,key:`l4dndm`}]]),Se=r(`info`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 16v-4`,key:`1dtifu`}],[`path`,{d:`M12 8h.01`,key:`e9boi3`}]]),Ce=r(`star`,[[`path`,{d:`M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z`,key:`r04s7s`}]]),y=t(e(),1);function we(e={}){let t=e.timeout??2e3,[n,r]=(0,y.useState)(null),[i,a]=(0,y.useState)(!1),o=(0,y.useRef)(null);(0,y.useEffect)(()=>()=>{window.clearTimeout(o.current)},[]);let s=e=>{window.clearTimeout(o.current),o.current=window.setTimeout(()=>a(!1),t),a(e)};return{copy:e=>{`clipboard`in navigator?navigator.clipboard.writeText(e).then(()=>{r(null),s(!0)}).catch(e=>r(e)):r(Error(`useClipboard: navigator.clipboard is not supported`))},reset:()=>{a(!1),r(null),window.clearTimeout(o.current)},error:n,copied:i}}var b=n();function x(e){let t=e.lastIndexOf(`/`);return t===-1?{folder:``,name:e}:{folder:e.substring(0,t),name:e.substring(t+1)}}function Te({file:e,isSelected:t,onSelect:n,onPreview:r}){let i=d(e.fileName),a=(0,b.jsx)(se,{size:24,color:`#fff`});return i===`image`?a=(0,b.jsx)(f,{size:24,color:`#fff`}):i===`video`?a=(0,b.jsx)(u,{size:24,color:`#fff`}):i===`audio`&&(a=(0,b.jsx)(h,{size:24,color:`#fff`})),(0,b.jsxs)(`div`,{"data-id":e.cid,onClick:()=>n(e.cid),onDoubleClick:()=>r(e),className:`card ${t?`selected`:``}`,children:[(0,b.jsx)(`div`,{className:`card-icon ${e.starred?`starred`:`file`}`,children:a}),(0,b.jsx)(`p`,{className:`card-name`,translate:`no`,children:x(e.fileName).name})]})}function Ee({folder:e,onClick:t}){return(0,b.jsxs)(`div`,{onClick:t,className:`card`,children:[(0,b.jsx)(`div`,{className:`card-icon folder`,children:(0,b.jsx)(m,{size:28,color:`#fff`})}),(0,b.jsx)(`p`,{className:`card-name`,translate:`no`,children:e.name})]})}function S(e,t){return e?[{path:``,name:t},...e.split(`/`).filter(Boolean).map((e,t,n)=>({path:n.slice(0,t+1).join(`/`),name:e}))]:[]}function De({items:e,allFolders:t,currentPath:n,onMove:r,onClose:i}){let[a,o]=(0,y.useState)(``),[s,c]=(0,y.useState)(n),{t:l}=he(),ee=S(a,l(`move.root`));function te(){r(a||s.trim())}let u=t.filter(e=>{if(a===``)return!e.path.includes(`/`);let t=a+`/`;return e.path.startsWith(t)?!e.path.substring(t.length).includes(`/`):!1});return(0,b.jsx)(_,{onClose:i,children:(0,b.jsxs)(`div`,{className:`move-modal`,onClick:e=>e.stopPropagation(),children:[(0,b.jsxs)(`div`,{className:`modal-header`,children:[(0,b.jsx)(`h3`,{children:l(`move.title`)}),(0,b.jsx)(`button`,{type:`button`,onClick:i,className:`btn btn-icon`,children:(0,b.jsx)(g,{size:18})})]}),(0,b.jsx)(`p`,{className:`move-modal-desc`,children:l(`move.selectedCount`,{count:e.length})}),(0,b.jsx)(`div`,{className:`move-new-folder`,children:(0,b.jsx)(`input`,{type:`text`,className:`input`,value:s,onChange:e=>c(e.target.value),placeholder:l(`move.pathPlaceholder`),translate:`no`})}),(0,b.jsx)(`p`,{className:`move-modal-hint`,children:l(`move.pathExample`)}),(0,b.jsx)(`div`,{className:`move-breadcrumb`,children:ee.map((e,t)=>(0,b.jsxs)(y.Fragment,{children:[t>0&&(0,b.jsx)(`span`,{className:`breadcrumb-separator`,children:`/`}),(0,b.jsx)(`button`,{type:`button`,onClick:()=>{o(e.path),c(e.path)},className:`move-breadcrumb-btn ${a===e.path&&!s?`active`:``}`,children:(0,b.jsx)(`span`,{translate:e.path?`no`:`yes`,children:e.name})})]},e.path))}),(0,b.jsxs)(`div`,{className:`move-folder-list`,children:[u.length===0&&(0,b.jsx)(`p`,{className:`move-modal-empty`,children:l(`move.noSubfolders`)}),u.map(e=>(0,b.jsxs)(`button`,{type:`button`,onClick:()=>o(e.path),className:`move-folder-item ${a===e.path&&!s?`selected`:``}`,children:[(0,b.jsx)(m,{size:16}),(0,b.jsx)(`span`,{translate:`no`,children:e.name})]},e.path))]}),(0,b.jsxs)(`div`,{className:`modal-actions`,children:[(0,b.jsx)(`button`,{type:`button`,onClick:i,className:`btn btn-secondary`,children:l(`common.cancel`)}),(0,b.jsx)(`button`,{type:`button`,onClick:te,className:`btn btn-primary`,children:l(`move.action`)})]})]})})}var C=`https://most.box`;function Oe(e,t){let n=String(t||``).trim(),r=`${C}/cid/${encodeURIComponent(e)}`;return n?`${r}?filename=${encodeURIComponent(n)}`:r}function w(e){return x(e)}function ke(e){let t=new Set;return e.forEach(e=>{let{folder:n}=w(e.fileName),r=n.split(`/`).filter(Boolean),i=``;for(let e of r)i+=(i?`/`:``)+e,t.add(i)}),[...t].sort()}function T(e,t){let n=t?t+`/`:``;return e.filter(e=>{let t=e.toLowerCase().startsWith(n.toLowerCase()),r=e.substring(n.length);return t&&!r.includes(`/`)}).map(e=>({name:e.substring(n.length),path:e}))}function Ae(e,t,n){return{folders:T(t,n),files:e.filter(e=>w(e.fileName).folder===n)}}function je(e,t){return e?[{path:``,name:t},...e.split(`/`).filter(Boolean).map((e,t,n)=>({path:n.slice(0,t+1).join(`/`),name:e}))]:[]}function Me(){let e=c(e=>e.addToast),t=c(e=>e.hasBackend),n=c(e=>e.openConnectModal),r=i(e=>e.identity),a=i(e=>e.openLoginModal),[u,f]=(0,y.useState)([]),[m,h]=(0,y.useState)([]),[x,S]=(0,y.useState)(null),[C,T]=(0,y.useState)(`all`),[Me,E]=(0,y.useState)(!1),[D,O]=(0,y.useState)([]),[Ne,k]=(0,y.useState)(null),[A,j]=(0,y.useState)(null),[Pe,Fe]=le(!1),[Ie,Le]=(0,y.useState)(``),[M,N]=(0,y.useState)(null),[P,Re]=(0,y.useState)(!1),[ze,F]=(0,y.useState)([]),[Be,I]=le(!1),[L,R]=(0,y.useState)(``),{copy:Ve,copied:He}=we({timeout:2e3}),[Ue,We]=le(!1),[z,B]=(0,y.useState)(null),[V,Ge]=(0,y.useState)(null),[Ke,qe]=(0,y.useState)(!1),{t:H,formatDate:Je}=he(),U=t===!0,Ye=e=>e?Je(e):``,W=x||``,Xe=ke(u),{folders:Ze,files:Qe}=Ae(u,Xe,W);function G(){return U?!0:(n(),!1)}function K(){return r?!0:(a(),!1)}let $e=L?u.filter(e=>w(e.fileName).name.toLowerCase().includes(L.toLowerCase())):Qe,q=async()=>{if(!U||!r){f([]);return}try{f(await v.listPublishedFiles()||[])}catch{f([])}},J=async()=>{if(!U||!r){h([]);return}try{h(await v.listTrashFiles()||[])}catch{h([])}},et=e=>{O(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e])},tt=async t=>{if(K()&&G())try{await v.restoreTrashFile(t),e(H(`app.toast.restored`),`success`),q(),J()}catch(t){e(await s(t,H(`app.toast.restoreFailed`)),`error`)}},nt=async()=>{K()&&G()&&B({title:H(`app.clearTrash.title`),message:H(`app.clearTrash.message`),confirmText:H(`app.clear`),danger:!0,onConfirm:async()=>{B(null);try{await v.emptyTrash(),e(H(`app.toast.trashEmptied`),`success`),J()}catch(t){e(await s(t,H(`app.toast.emptyFailed`)),`error`)}}})},rt=async t=>{if(K()&&G())try{let n=await v.toggleStar(t);f(e=>e.map(e=>e.cid===t?{...e,starred:n.starred}:e)),e(n.starred?H(`app.toast.favorited`):H(`app.toast.unfavorited`),`success`)}catch(t){e(await s(t,H(`app.toast.actionFailed`)),`error`)}},it=async()=>{if(!K()||!G())return;let t=C===`trash`;B({title:H(t?`app.permanentDelete`:`app.batchDelete`),message:H(t?`app.deleteSelectedPermanent`:`app.deleteSelected`,{count:D.length}),confirmText:H(t?`app.permanentDelete`:`app.delete`),danger:!0,onConfirm:async()=>{B(null);try{for(let e of D)t?await v.permanentDeleteTrashFile(e):e.startsWith(`__`)||await v.deletePublishedFile(e);O([]),e(H(t?`app.toast.deletedPermanently`:`app.toast.deleted`),`success`),q(),J()}catch(t){e(await s(t,H(`app.toast.deleteFailed`)),`error`)}}})},at=async t=>{if(K()&&G())try{for(let e of D){let n=u.find(t=>t.cid===e);if(!n)continue;let{name:r}=w(n.fileName),i=t?`${t}/${r}`:r;n.fileName!==i&&await v.moveFile(e,i)}O([]),We.close(),e(H(`app.toast.moved`),`success`),q()}catch(t){e(await s(t,H(`app.toast.moveFailed`)),`error`)}},ot=t=>{let n=!!t.path,r=n?t.name:w(t.fileName).name;Ge({title:H(n?`app.renameFolder`:`app.renameFile`),placeholder:H(`app.enterNewName`),defaultValue:r,confirmText:H(`app.rename`),onConfirm:async i=>{if(i!==r&&K()&&G()){qe(!0);try{if(n){let n=t.path.lastIndexOf(`/`),r=n===-1?``:t.path.substring(0,n),a=r?`${r}/${i}`:i;await v.renameFolder(t.path,a),e(H(`app.toast.renamed`),`success`),q(),Q(a)}else{let{folder:n}=w(t.fileName),r=n?`${n}/${i}`:i;await v.moveFile(t.cid,r),e(H(`app.toast.renamed`),`success`),q()}Ge(null)}catch(t){e(await s(t,H(`app.toast.renameFailed`)),`error`)}finally{qe(!1)}}}})},st=async t=>{if(!r){a(),e(H(`app.toast.signInBeforePublish`),`warning`);return}if(!G())return;let n=W?W+`/`:``,i=[];for(let r of Array.from(t)){let t=n+r.name;if(u.some(e=>e.fileName===t)){e(H(`app.fileAlreadyExists`,{fileName:r.name}),`warning`);continue}let a=`upload_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,o={id:a,fileName:r.name,progress:0,type:`upload`,status:`uploading`};i.push(o),F(e=>[...e,o]),i.length>0&&I.open();try{(await v.publishFile(r,t)).alreadyExists?(F(e=>e.map(e=>e.id===a?{...e,status:`completed`}:e)),e(H(`app.fileAlreadyExists`,{fileName:r.name}),`warning`)):(F(e=>e.map(e=>e.id===a?{...e,progress:100,status:`completed`}:e)),e(H(`app.fileAddedLocal`,{fileName:r.name}),`success`))}catch(t){F(e=>e.map(e=>e.id===a?{...e,status:`error`}:e)),e(await s(t,H(`app.publishFailedWithFile`,{fileName:r.name})),`error`)}}setTimeout(()=>{F(e=>e.filter(e=>e.status!==`completed`&&e.status!==`error`&&e.status!==`cancelled`))},3e3),q()},ct=A?Oe(A.cid,A.fileName):``,lt=()=>{ct&&Ve(ct)},[Y,ut]=(0,y.useState)(!1),X=Ie.trim(),Z=M?.status===`success`&&M.link===X,dt=()=>{Fe.close(),N(null)},ft=e=>{Le(e.target.value),N(null)},pt=async()=>{let t=be(X,H);if(t){N({status:`error`,link:X,message:t}),e(t,`warning`);return}if(!(P||Y)&&K()&&G()){Re(!0),N(null);try{let t=await v.checkDownload(X);N({status:`success`,link:X,message:t.alreadyExists?H(`app.fileAlreadyLocal`,{fileName:t.fileName}):H(`app.fileAvailable`,{fileName:t.fileName})}),e(t.alreadyExists?H(`app.fileAlreadyExists`,{fileName:t.fileName}):H(`app.toast.checkPassed`),t.alreadyExists?`warning`:`success`)}catch(t){let n=await ye(t);N({status:`error`,link:X,message:n}),e(n,`error`)}finally{Re(!1)}}},mt=async()=>{if(!r){a(),e(H(`app.toast.signInBeforeDownload`),`warning`);return}if(!G())return;let t=be(X,H);if(t){e(t,`warning`);return}if(!Z){e(H(`app.toast.checkLinkFirst`),`warning`);return}if(!Y){ut(!0);try{let t=await v.downloadFile(X);if(Le(``),N(null),dt(),t.alreadyExists)e(H(`app.fileAlreadyExists`,{fileName:t.fileName}),`warning`);else{let n={id:t.taskId,fileName:H(`app.downloadFallbackName`),progress:0,type:`download`,status:`downloading`};F(e=>[...e,n]),I.open(),e(H(`app.toast.downloadStarted`),`info`)}}catch(t){e(await s(t,H(`app.toast.downloadFailed`)),`error`)}finally{ut(!1)}}},ht=async t=>{if(K()&&G()&&t.type===`download`&&t.status===`downloading`){F(e=>e.map(e=>e.id===t.id?{...e,status:`cancelling`}:e));try{await v.cancelDownload(t.id)}catch(n){F(e=>e.map(e=>e.id===t.id?{...e,status:`downloading`}:e)),e(await s(n,H(`app.toast.cancelFailed`)),`error`)}}},gt=async t=>{if(K()&&G()){if(t.localAvailable===!1){e(H(`app.toast.fileNotLocal`),`warning`);return}try{let n=await fetch(v.getFileDownloadUrl(t.cid),{headers:await o(`GET`,`/api/files/${t.cid}/download`)});if(!n.ok)throw Error(H(`app.toast.getFileFailed`));let r=await n.blob(),i=window.showSaveFilePicker;if(i){let n=await(await i({suggestedName:t.fileName})).createWritable();await n.write(r),await n.close(),e(H(`app.toast.fileSaved`),`success`)}else{let n=URL.createObjectURL(r),i=document.createElement(`a`);i.href=n,i.download=t.fileName,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(n),e(H(`app.toast.fileDownloaded`),`success`)}}catch(t){t.name!==`AbortError`&&e(H(`app.saveFailedWithError`,{error:t.message}),`error`)}}},_t=async t=>{if(K()&&G())try{e(H(`app.toast.startPullLocal`),`info`),await v.cacheFile(t.cid),e(H(`app.toast.pulledAndSeeding`),`success`),q()}catch(t){e(await s(t,H(`app.toast.pullFailed`)),`error`)}},Q=e=>{S(e||null),O([])};(0,y.useEffect)(()=>{if(t!==!0)return;let n=null,r=!1;return(async()=>{if(n=new WebSocket(await l(`/ws`)),r){n.close();return}n.onmessage=t=>{try{let{event:n,data:r}=JSON.parse(t.data);if(n===`publish:success`||n===`download:success`){q();let t=r.taskId||r.fileName;F(e=>e.map(e=>e.id===t||e.fileName===r.fileName?{...e,progress:100,status:`completed`}:e)),n===`download:success`&&(r.alreadyExists?e(H(`app.fileAlreadyExists`,{fileName:r.fileName}),`warning`):e(H(`app.fileDownloadCompleted`,{fileName:r.fileName}),`success`),setTimeout(()=>{F(e=>e.filter(e=>!(e.id===t&&e.status===`completed`)))},3e3))}n===`publish:progress`&&F(e=>e.map(e=>{if(r.file&&e.fileName===r.file&&e.type===`upload`){let t=50;return r.stage===`calculating-cid`?t=25:r.stage===`uploading`?t=75:r.stage===`complete`&&(t=100),{...e,progress:t}}return e})),n===`download:progress`&&F(e=>e.map(e=>e.id===r.taskId?{...e,progress:r.percent||0,loaded:r.loaded,total:r.total}:e)),n===`download:error`&&(F(e=>e.map(e=>e.id===r.taskId?{...e,status:`error`}:e)),e(H(`app.downloadFailedWithError`,{error:r.error}),`error`)),n===`download:status`&&F(e=>e.map(e=>e.id===r.taskId?{...e,fileName:r.file||e.fileName}:e)),n===`download:cancelled`&&(F(e=>e.map(e=>e.id===r.taskId?{...e,status:`cancelled`}:e)),e(H(`app.toast.downloadCancelled`),`warning`)),n===`user:metadata:updated`&&(q(),J())}catch(e){console.warn(`[App WS] Failed to parse message:`,e.message)}}})(),()=>{r=!0,n?.close()}},[t,r?.address]),(0,y.useEffect)(()=>{if(t===!0&&r){q(),J();return}t===!1&&(f([]),h([]))},[t,r?.address]),(0,y.useEffect)(()=>{r||(O([]),k(null),j(null),Le(``),N(null),F([]),R(``),S(null),T(`all`))},[r?.address]);let vt=H(C===`all`?`app.nav.local`:C===`starred`?`app.nav.favorites`:`app.nav.trash`),$=C===`all`?$e:C===`starred`?u.filter(e=>e.starred&&w(e.fileName).name.toLowerCase().includes(L.toLowerCase())):m.filter(e=>w(e.fileName).name.toLowerCase().includes(L.toLowerCase())),yt=C===`starred`?[]:Ze.filter(e=>e.name.toLowerCase().includes(L.toLowerCase())),bt=je(W,H(`app.allContent`));return(0,b.jsxs)(ue,{sidebar:({closeSidebar:e})=>(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(de,{onNavigate:e}),(0,b.jsx)(`nav`,{className:`sidebar-nav`,children:[{id:`all`,icon:(0,b.jsx)(xe,{size:18}),label:H(`app.nav.local`)},{id:`starred`,icon:(0,b.jsx)(Ce,{size:18}),label:H(`app.nav.favorites`)},{id:`trash`,icon:(0,b.jsx)(pe,{size:18}),label:H(`app.nav.trash`)}].map(t=>(0,b.jsxs)(`button`,{onClick:()=>{T(t.id),S(null),O([]),R(``),e()},className:`sidebar-nav-btn ${C===t.id?`active`:``}`,children:[t.icon,(0,b.jsx)(`span`,{children:t.label})]},t.id))})]}),headerTitle:(0,b.jsx)(`h2`,{className:`header-title`,children:vt}),headerRight:(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)(`div`,{className:`search-box`,children:[(0,b.jsx)(fe,{size:14}),(0,b.jsx)(`input`,{type:`text`,value:L,onChange:e=>R(e.target.value),placeholder:H(`app.search.placeholder`)}),L&&(0,b.jsx)(`button`,{onClick:()=>R(``),children:(0,b.jsx)(g,{size:12})})]}),C===`trash`&&m.length>0&&(0,b.jsx)(`button`,{onClick:nt,className:`btn btn-sm btn-empty-trash`,children:H(`app.emptyTrash`)}),(0,b.jsx)(`button`,{onClick:()=>I.open(),className:`btn btn-icon`,children:(0,b.jsx)(re,{size:16})})]}),children:[C===`all`&&(0,b.jsxs)(`div`,{className:`action-grid`,children:[(0,b.jsxs)(`div`,{className:`action-card upload ${Me?`drag-over`:``}`,onDragOver:e=>{e.preventDefault(),E(!0)},onDragLeave:()=>E(!1),onDrop:e=>{e.preventDefault(),E(!1),!(!K()||!G())&&st(e.dataTransfer.files)},children:[(0,b.jsx)(`input`,{type:`file`,multiple:!0,onClick:e=>{(!K()||!G())&&e.preventDefault()},onChange:e=>st(e.target.files),className:`action-card-input`}),(0,b.jsx)(me,{size:20,className:`action-grid-icon`}),(0,b.jsx)(`p`,{children:H(`app.publishFile`)})]}),(0,b.jsxs)(`div`,{className:`action-card action-card-download`,onClick:()=>{!K()||!G()||Fe.open()},children:[(0,b.jsx)(oe,{size:20,className:`action-grid-icon`}),(0,b.jsx)(`p`,{children:H(`app.downloadFile`)})]})]}),C===`all`&&(0,b.jsx)(`div`,{className:`breadcrumb`,children:W?(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(`button`,{onClick:()=>Q(``),children:H(`app.allContent`)}),bt.slice(1).map((e,t)=>(0,b.jsxs)(y.Fragment,{children:[(0,b.jsx)(ie,{size:12}),(0,b.jsx)(`button`,{onClick:()=>Q(e.path),className:t===bt.length-2?`current`:``,children:(0,b.jsx)(`span`,{translate:`no`,children:e.name})}),t===bt.length-2&&(0,b.jsx)(`button`,{onClick:()=>ot(e),className:`breadcrumb-edit-btn`,children:(0,b.jsx)(te,{size:12})})]},e.path))]}):null}),(0,b.jsxs)(`div`,{className:`content-grid`,children:[C===`trash`&&($.length===0?(0,b.jsxs)(`div`,{className:`empty-state app-empty-state`,children:[(0,b.jsx)(`p`,{children:H(L?`app.noMatches`:`app.trashEmpty`)}),(0,b.jsx)(ee,{label:H(`app.openFileNavigation`)})]}):(0,b.jsx)(`div`,{className:`file-grid`,children:$.map(e=>(0,b.jsxs)(`div`,{onClick:()=>O(t=>t.includes(e.cid)?t.filter(t=>t!==e.cid):[...t,e.cid]),onDoubleClick:()=>tt(e.cid),className:`card ${D.includes(e.cid)?`selected`:``}`,children:[(0,b.jsx)(`div`,{className:`card-icon trash`,children:(0,b.jsx)(se,{size:24,color:`#fff`})}),(0,b.jsx)(`p`,{className:`card-name`,translate:`no`,children:w(e.fileName).name}),(0,b.jsx)(`p`,{className:`card-date`,children:H(`app.deletedOn`,{date:Ye(e.deletedAt)})})]},e.cid))})),C!==`trash`&&($.length===0&&yt.length===0?(0,b.jsxs)(`div`,{className:`empty-state app-empty-state`,children:[(0,b.jsx)(`p`,{children:H(L?`app.noMatches`:C===`starred`?`app.noFavorites`:`app.noLocalFiles`)}),(0,b.jsx)(ee,{label:H(`app.openFileNavigation`)})]}):(0,b.jsxs)(`div`,{className:`file-grid`,children:[yt.map(e=>(0,b.jsx)(Ee,{folder:e,onClick:()=>Q(e.path)},e.path)),$.map(t=>(0,b.jsx)(Te,{file:t,isSelected:D.includes(t.cid),onSelect:et,onPreview:t=>{if(t.localAvailable===!1){e(H(`app.toast.fileNotLocal`),`warning`);return}k({...t,subtype:d(t.fileName)})}},t.cid))]}))]}),z&&(0,b.jsx)(_e,{title:z.title,message:z.message,confirmText:z.confirmText,danger:z.danger,onConfirm:z.onConfirm,onClose:()=>B(null)}),V&&(0,b.jsx)(ge,{title:V.title,placeholder:V.placeholder,defaultValue:V.defaultValue,confirmText:V.confirmText,isLoading:Ke,onConfirm:V.onConfirm,onClose:()=>Ge(null)}),Ue&&(0,b.jsx)(De,{items:D.map(e=>u.find(t=>t.cid===e)).filter(Boolean),allFolders:Xe.map(e=>({path:e,name:e.split(`/`).pop()})),currentPath:W,onMove:at,onClose:()=>We.close()}),A&&(0,b.jsx)(_,{onClose:()=>j(null),children:(0,b.jsxs)(`div`,{className:`share-modal`,onClick:e=>e.stopPropagation(),children:[(0,b.jsxs)(`div`,{className:`modal-header`,children:[(0,b.jsx)(`h3`,{children:H(`app.shareLink`)}),(0,b.jsx)(`button`,{onClick:()=>j(null),className:`btn btn-icon`,children:(0,b.jsx)(g,{size:18})})]}),(0,b.jsxs)(`div`,{className:`share-link-box`,children:[(0,b.jsx)(`div`,{className:`share-link-text`,translate:`no`,children:ct}),(0,b.jsx)(`button`,{onClick:lt,className:`btn btn-circle btn-primary ${He?`copied`:``}`,children:He?(0,b.jsx)(p,{size:18}):(0,b.jsx)(ae,{size:18})})]}),(0,b.jsx)(`div`,{className:`share-storage-note`,children:(0,b.jsx)(`span`,{children:H(`app.shareSeedNote`)})})]})}),Pe&&(0,b.jsx)(_,{onClose:dt,children:(0,b.jsxs)(`div`,{className:`download-modal`,onClick:e=>e.stopPropagation(),children:[(0,b.jsxs)(`div`,{className:`modal-header`,children:[(0,b.jsx)(`h3`,{children:H(`app.downloadFile`)}),(0,b.jsx)(`button`,{onClick:dt,className:`btn btn-icon`,children:(0,b.jsx)(g,{size:18})})]}),(0,b.jsxs)(`div`,{className:`download-link-row`,children:[(0,b.jsx)(`input`,{type:`text`,className:`input`,value:Ie,onChange:ft,placeholder:H(`app.downloadLink.placeholder`)}),(0,b.jsxs)(`button`,{type:`button`,onClick:pt,disabled:!X||P||Y,className:`btn btn-secondary download-check-btn`,children:[P?(0,b.jsx)(ce,{size:14,className:`spin`}):Z?(0,b.jsx)(p,{size:14}):(0,b.jsx)(fe,{size:14}),H(P?`app.checking`:Z?`app.passed`:`app.check`)]})]}),M&&(0,b.jsxs)(`div`,{className:`download-check-status ${M.status}`,children:[M.status===`success`?(0,b.jsx)(p,{size:14}):(0,b.jsx)(Se,{size:14}),(0,b.jsx)(`span`,{children:M.message})]}),(0,b.jsxs)(`button`,{onClick:mt,disabled:!Z||Y||P,className:`btn btn-info btn-full`,children:[Y?(0,b.jsx)(ce,{size:14,className:`spin`}):(0,b.jsx)(oe,{size:14}),H(Y?`app.downloading`:`app.startDownload`)]})]})}),Ne&&(0,b.jsx)(ne,{item:Ne,isBackendReady:U,getFileDownloadUrl:v.getFileDownloadUrl,onClose:()=>k(null)}),D.length>0&&(0,b.jsxs)(`div`,{className:`batch-bar`,children:[(0,b.jsx)(`span`,{className:`batch-info`,children:H(`app.selectedItems`,{count:D.length})}),(0,b.jsx)(`button`,{onClick:()=>O([]),className:`batch-dismiss`,children:(0,b.jsx)(g,{size:16})}),(0,b.jsx)(`div`,{className:`batch-divider`}),C===`trash`?(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(`button`,{onClick:async()=>{K()&&G()&&(await Promise.all(D.map(e=>v.restoreTrashFile(e))),O([]),e(H(`app.toast.restored`),`success`),q(),J())},className:`btn btn-sm`,children:H(`app.restore`)}),(0,b.jsx)(`button`,{onClick:it,className:`btn btn-sm btn-danger`,children:H(`app.permanentDelete`)})]}):(0,b.jsxs)(b.Fragment,{children:[D.length===1&&(()=>{let e=u.find(e=>e.cid===D[0]);return e&&d(e.fileName)!==`file`})()&&(0,b.jsx)(`button`,{onClick:()=>{let t=u.find(e=>e.cid===D[0]);if(t){if(t.localAvailable===!1){e(H(`app.toast.fileNotLocal`),`warning`);return}let n=d(t.fileName);k({...t,subtype:n})}},className:`btn btn-sm`,children:H(`app.preview`)}),(0,b.jsx)(`button`,{onClick:()=>{let e=D.some(e=>{let t=u.find(t=>t.cid===e);return t&&!t.starred});D.forEach(t=>{let n=u.find(e=>e.cid===t);n&&(e?!n.starred:n.starred)&&rt(t)})},className:`btn btn-sm btn-star`,children:H(`app.favorite`)}),D.length===1&&(0,b.jsx)(`button`,{onClick:()=>{let e=u.find(e=>e.cid===D[0]);e&&ot(e)},className:`btn btn-sm`,children:H(`app.rename`)}),(0,b.jsx)(`button`,{onClick:()=>We.open(),className:`btn btn-sm btn-move`,children:H(`app.move`)}),(0,b.jsx)(`button`,{onClick:it,className:`btn btn-sm btn-danger`,children:H(`app.delete`)}),D.length===1&&(()=>{let e=u.find(e=>e.cid===D[0]);return e&&e.localAvailable===!1})()&&(0,b.jsx)(`button`,{onClick:()=>{let e=u.find(e=>e.cid===D[0]);e&&_t(e)},className:`btn btn-sm`,children:H(`app.pullToLocal`)}),D.length===1&&(0,b.jsx)(`button`,{onClick:()=>j(u.find(e=>e.cid===D[0])),className:`btn btn-sm`,children:H(`app.share`)}),D.length===1&&(0,b.jsx)(`button`,{onClick:()=>{let e=u.find(e=>e.cid===D[0]);e&&gt(e)},className:`btn btn-sm`,children:H(`app.saveAs`)})]})]}),Be&&(0,b.jsx)(_,{onClose:()=>I.close(),children:(0,b.jsxs)(`div`,{className:`transfer-modal`,onClick:e=>e.stopPropagation(),children:[(0,b.jsxs)(`div`,{className:`modal-header`,children:[(0,b.jsx)(`h3`,{children:H(`app.transfers`)}),(0,b.jsx)(`button`,{onClick:()=>I.close(),className:`btn btn-icon`,children:(0,b.jsx)(g,{size:18})})]}),ze.length===0?(0,b.jsx)(`div`,{className:`empty-transfer`,children:H(`app.noTransfers`)}):ze.map(e=>(0,b.jsxs)(`div`,{className:`transfer-item`,children:[(0,b.jsxs)(`div`,{className:`transfer-item-header`,children:[e.type===`upload`?(0,b.jsx)(me,{size:14}):(0,b.jsx)(oe,{size:14}),(0,b.jsx)(`span`,{className:`transfer-item-name`,translate:`no`,children:e.fileName}),e.status===`downloading`&&e.type===`download`&&(0,b.jsx)(`button`,{onClick:()=>ht(e),className:`transfer-item-cancel`,children:(0,b.jsx)(g,{size:14})})]}),(0,b.jsxs)(`div`,{className:`transfer-progress-row`,children:[(0,b.jsx)(`progress`,{className:`transfer-progress-meter ${e.type===`download`?`download`:``} ${e.status===`error`?`error`:``} ${e.status===`cancelled`?`cancelled`:``}`,value:Math.max(0,Math.min(100,e.progress)),max:100,"aria-label":H(`app.transferProgress`,{fileName:e.fileName})}),(0,b.jsx)(`span`,{className:`transfer-progress-text`,children:e.status===`completed`?H(`app.completed`):e.status===`error`?H(`app.failed`):e.status===`cancelled`?H(`app.cancelled`):e.status===`cancelling`?H(`app.cancelling`):e.loaded&&e.total?`${ve(e.loaded)}/${ve(e.total)}`:`${e.progress}%`})]})]},e.id))]})})]})}var E=a(`/app/`)({component:Me});export{E as Route};
@@ -0,0 +1 @@
1
+ import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{B as r,H as i,W as a,t as o}from"./useAppStore-DOnk608w.js";import{t as s}from"./arrow-right-CXzRt0Fp.js";import{t as c}from"./check-iBCQl0yr.js";import{t as l}from"./download-COQOcPqI.js";import{t as u}from"./external-link-D6tHlYgS.js";import{n as d,t as f}from"./notebook-pen-BzrCXQJE.js";import{t as p}from"./hard-drive-Cqa7Rstj.js";import{t as m}from"./message-square-BgsNXPft.js";import{t as h}from"./wallet-D9Iw4YWE.js";import{A as g,C as _,b as v}from"./index-D0Uk9-58.js";import{t as y}from"./MarketingLayout-CiN5KYcE.js";var b=r(`arrow-up-right`,[[`path`,{d:`M7 7h10v10`,key:`1tivn9`}],[`path`,{d:`M7 17 17 7`,key:`1vkiza`}]]),x=r(`gamepad-2`,[[`line`,{x1:`6`,x2:`10`,y1:`11`,y2:`11`,key:`1gktln`}],[`line`,{x1:`8`,x2:`8`,y1:`9`,y2:`13`,key:`qnk9ow`}],[`line`,{x1:`15`,x2:`15.01`,y1:`12`,y2:`12`,key:`krot7o`}],[`line`,{x1:`18`,x2:`18.01`,y1:`10`,y2:`10`,key:`1lcuu1`}],[`path`,{d:`M17.32 5H6.68a4 4 0 0 0-3.978 3.59c-.006.052-.01.101-.017.152C2.604 9.416 2 14.456 2 16a3 3 0 0 0 3 3c1 0 1.5-.5 2-1l1.414-1.414A2 2 0 0 1 9.828 16h4.344a2 2 0 0 1 1.414.586L17 18c.5.5 1 1 2 1a3 3 0 0 0 3-3c0-1.545-.604-6.584-.685-7.258-.007-.05-.011-.1-.017-.151A4 4 0 0 0 17.32 5z`,key:`mfqc10`}]]),S=t(e(),1),C=n(),w=[{id:`app`,titleKey:`portal.feature.app.title`,subtitleKey:`portal.feature.app.subtitle`,icon:(0,C.jsx)(d,{size:28}),path:`/app/`,requiresBackend:!0,heroKey:`portal.feature.app.hero`,descKey:`portal.feature.app.desc`,featureKeys:[`portal.feature.app.bullet.localIdentity`,`portal.feature.app.bullet.hyperswarm`,`portal.feature.app.bullet.largeFiles`,`portal.feature.app.bullet.cid`,`portal.feature.app.bullet.seedAfterDownload`,`portal.feature.app.bullet.noCloud`,`portal.feature.app.bullet.desktop`,`portal.feature.app.bullet.openSource`],steps:[{num:`1`,titleKey:`portal.feature.app.step.download.title`,descKey:`portal.feature.app.step.download.desc`,link:`/download/`,linkTextKey:`portal.feature.app.step.download.link`,hideInDesktopClient:!0},{num:`2`,titleKey:`portal.feature.app.step.install.title`,descKey:`portal.feature.app.step.install.desc`,hideInDesktopClient:!0},{num:`3`,titleKey:`portal.feature.app.step.share.title`,descKey:`portal.feature.app.step.share.desc`}]},{id:`chat`,titleKey:`portal.feature.chat.title`,subtitleKey:`portal.feature.chat.subtitle`,icon:(0,C.jsx)(m,{size:28}),path:`/chat/`,requiresBackend:!0,heroKey:`portal.feature.chat.hero`,descKey:`portal.feature.chat.desc`,featureKeys:[`portal.feature.chat.bullet.encrypted`,`portal.feature.chat.bullet.identity`,`portal.feature.chat.bullet.sync`,`portal.feature.chat.bullet.offline`,`portal.feature.chat.bullet.noAccount`],steps:[{num:`1`,titleKey:`portal.feature.chat.step.download.title`,descKey:`portal.feature.chat.step.download.desc`,link:`/download/`,linkTextKey:`portal.feature.chat.step.download.link`,hideInDesktopClient:!0},{num:`2`,titleKey:`portal.feature.chat.step.create.title`,descKey:`portal.feature.chat.step.create.desc`},{num:`3`,titleKey:`portal.feature.chat.step.send.title`,descKey:`portal.feature.chat.step.send.desc`}]},{id:`note`,titleKey:`portal.feature.note.title`,subtitleKey:`portal.feature.note.subtitle`,icon:(0,C.jsx)(f,{size:28}),path:`/note/`,requiresBackend:!1,heroKey:`portal.feature.note.hero`,descKey:`portal.feature.note.desc`,featureKeys:[`portal.feature.note.bullet.markdown`,`portal.feature.note.bullet.privacy`,`portal.feature.note.bullet.folders`,`portal.feature.note.bullet.web3`,`portal.feature.note.bullet.backup`,`portal.feature.note.bullet.independent`],steps:[{num:`1`,titleKey:`portal.feature.note.step.account.title`,descKey:`portal.feature.note.step.account.desc`},{num:`2`,titleKey:`portal.feature.note.step.create.title`,descKey:`portal.feature.note.step.create.desc`},{num:`3`,titleKey:`portal.feature.note.step.backup.title`,descKey:`portal.feature.note.step.backup.desc`}]},{id:`gandengyan`,titleKey:`portal.feature.game.title`,subtitleKey:`portal.feature.game.subtitle`,icon:(0,C.jsx)(x,{size:28}),path:`/game/gandengyan/`,requiresBackend:!0,heroKey:`portal.feature.game.hero`,descKey:`portal.feature.game.desc`,featureKeys:[`portal.feature.game.bullet.account`,`portal.feature.game.bullet.channel`,`portal.feature.game.bullet.link`,`portal.feature.game.bullet.rules`,`portal.feature.game.bullet.maintain`],steps:[{num:`1`,titleKey:`portal.feature.game.step.login.title`,descKey:`portal.feature.game.step.login.desc`},{num:`2`,titleKey:`portal.feature.game.step.create.title`,descKey:`portal.feature.game.step.create.desc`},{num:`3`,titleKey:`portal.feature.game.step.test.title`,descKey:`portal.feature.game.step.test.desc`}]},{id:`web3`,titleKey:`portal.feature.web3.title`,subtitleKey:`portal.feature.web3.subtitle`,icon:(0,C.jsx)(h,{size:28}),path:`/web3/`,requiresBackend:!1,heroKey:`portal.feature.web3.hero`,descKey:`portal.feature.web3.desc`,featureKeys:[`portal.feature.web3.bullet.frontend`,`portal.feature.web3.bullet.keys`,`portal.feature.web3.bullet.mnemonic`,`portal.feature.web3.bullet.eth`,`portal.feature.web3.bullet.pem`,`portal.feature.web3.bullet.qr`],steps:[{num:`1`,titleKey:`portal.feature.web3.step.username.title`,descKey:`portal.feature.web3.step.username.desc`},{num:`2`,titleKey:`portal.feature.web3.step.keys.title`,descKey:`portal.feature.web3.step.keys.desc`},{num:`3`,titleKey:`portal.feature.web3.step.export.title`,descKey:`portal.feature.web3.step.export.desc`}]}],T=[`chat`,`app`,`note`,`gandengyan`,`web3`];function E(){let e=o(e=>e.hasBackend),t=o(e=>e.openConnectModal),[n,r]=(0,S.useState)(`chat`),{t:i}=g(),d=v(),f=T.map(e=>w.find(t=>t.id===e)).filter(e=>!!e),m=f.find(e=>e.id===n)||f[0],h=i(m.titleKey),y=m.steps.filter(e=>!(d&&e.hideInDesktopClient));return(0,C.jsxs)(`div`,{className:`portal-page`,children:[(0,C.jsx)(`section`,{className:`portal-hero`,children:(0,C.jsxs)(`div`,{className:`mkt-container`,children:[(0,C.jsx)(`h1`,{className:`portal-hero-title`,children:i(`common.brand`)}),(0,C.jsx)(`p`,{className:`portal-hero-subtitle`,children:i(`portal.hero.subtitle`)})]})}),(0,C.jsx)(`section`,{className:`portal-cards-section`,children:(0,C.jsxs)(`div`,{className:`mkt-container`,children:[(0,C.jsx)(`div`,{className:`portal-cards`,children:f.map(t=>{let o=n===t.id,s=t.requiresBackend,c=s?e===!0?`connected`:e===!1?`disconnected`:`checking`:`none`,l=i(t.titleKey);return(0,C.jsxs)(`button`,{className:`portal-card ${o?`active`:``}`,onClick:()=>r(t.id),children:[(0,C.jsx)(a,{to:t.path,className:`btn btn-icon portal-card-open-btn`,onClick:e=>e.stopPropagation(),title:i(`portal.openFeature`,{title:l}),children:(0,C.jsx)(b,{size:16})}),(0,C.jsx)(`div`,{className:`portal-card-icon`,children:t.icon}),(0,C.jsx)(`div`,{className:`portal-card-title`,children:l}),(0,C.jsx)(`div`,{className:`portal-card-subtitle`,children:i(t.subtitleKey)}),s?(0,C.jsxs)(`div`,{className:`ui-badge portal-card-status ${c}`,children:[c===`checking`&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(`span`,{className:`status-dot checking`}),i(`common.status.checking`)]}),c===`connected`&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(`span`,{className:`status-dot connected`}),i(`common.status.connected`)]}),c===`disconnected`&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(`span`,{className:`status-dot disconnected`}),i(`common.status.needsConnection`)]})]}):(0,C.jsxs)(`div`,{className:`ui-badge portal-card-status ready`,children:[(0,C.jsx)(`span`,{className:`status-dot ready`}),i(`common.status.ready`)]})]},t.id)})}),(0,C.jsxs)(`div`,{className:`portal-node-actions`,"aria-label":i(`portal.nodeEntry`),children:[(0,C.jsxs)(`button`,{onClick:t,className:`btn btn-secondary`,children:[(0,C.jsx)(_,{size:16}),i(`portal.webConnectNode`)]}),(0,C.jsxs)(a,{to:`/admin/`,className:`btn btn-secondary`,children:[(0,C.jsx)(p,{size:16}),i(`portal.nodeAdmin`)]})]})]})}),(0,C.jsx)(`section`,{className:`portal-marketing`,children:(0,C.jsx)(`div`,{className:`mkt-container`,children:(0,C.jsxs)(`div`,{className:`portal-marketing-inner`,children:[(0,C.jsxs)(`div`,{className:`portal-marketing-header`,children:[(0,C.jsx)(`h2`,{children:i(m.heroKey)}),(0,C.jsx)(`p`,{children:i(m.descKey)})]}),(0,C.jsx)(`div`,{className:`portal-marketing-features`,children:m.featureKeys.map(e=>(0,C.jsxs)(`div`,{className:`portal-feature-item`,children:[(0,C.jsx)(`span`,{className:`portal-feature-icon`,children:(0,C.jsx)(c,{size:14,strokeWidth:3})}),(0,C.jsx)(`span`,{children:i(e)})]},e))}),(0,C.jsx)(`div`,{className:`portal-marketing-steps`,children:y.map((e,t)=>(0,C.jsxs)(`div`,{className:`portal-step`,children:[(0,C.jsx)(`span`,{className:`portal-step-num`,children:t+1}),(0,C.jsxs)(`div`,{className:`portal-step-content`,children:[(0,C.jsx)(`strong`,{children:i(e.titleKey)}),(0,C.jsx)(`p`,{children:i(e.descKey)}),e.code&&(0,C.jsx)(`code`,{className:`portal-step-code`,translate:`no`,children:e.code}),e.link&&e.linkTextKey&&(0,C.jsx)(`p`,{className:`portal-step-link`,children:(0,C.jsxs)(a,{to:e.link,children:[i(e.linkTextKey),` `,(0,C.jsx)(u,{size:12})]})})]})]},e.num))}),(0,C.jsxs)(`div`,{className:`portal-actions`,children:[(0,C.jsxs)(a,{to:m.path,className:`btn btn-primary`,children:[i(`portal.enterFeature`,{title:h}),(0,C.jsx)(s,{size:16})]}),m.requiresBackend&&e===!1&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`button`,{onClick:t,className:`btn btn-secondary`,children:[(0,C.jsx)(_,{size:16}),i(`portal.webConnectNode`)]}),!d&&(0,C.jsxs)(a,{to:`/download/`,className:`btn btn-secondary`,children:[(0,C.jsx)(l,{size:16}),i(`nav.downloadClient`)]})]})]})]})})})]})}function D(){return(0,C.jsx)(y,{children:(0,C.jsx)(E,{})})}var O=i(`/`)({component:D});export{O as Route};
@@ -0,0 +1 @@
1
+ import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{B as r,E as i,H as a,O as ee,W as o,n as te,o as ne,t as s}from"./useAppStore-DOnk608w.js";import{n as c,r as l}from"./mp-Dv12gDTx.js";import{t as u}from"./circle-alert-dfN4T6Nq.js";import{t as d}from"./check-iBCQl0yr.js";import{t as re}from"./download-COQOcPqI.js";import{t as ie}from"./external-link-D6tHlYgS.js";import{t as ae}from"./key-round-JR8M3aHl.js";import{i as f}from"./AccountMenu-ptQklqvD.js";import{t as p}from"./loader-CwyHYZdX.js";import{t as m}from"./save-B02sbO9Y.js";import{t as h}from"./shield-check-Boae7Nc6.js";import{t as g}from"./upload-DVuXJt_o.js";import{A as _,D as v,S as y,d as b,f as x,h as S,m as C,n as oe,p as w,v as se,y as ce}from"./index-D0Uk9-58.js";import{t as le}from"./MarketingHeader-CxJ_OVOW.js";import{t as T}from"./CopyButton-C8PIDSJZ.js";import{t as E}from"./MarketingLayout-CiN5KYcE.js";var ue=r(`cloud-download`,[[`path`,{d:`M12 13v8l-4-4`,key:`1f5nwf`}],[`path`,{d:`m12 21 4-4`,key:`1lfcce`}],[`path`,{d:`M4.393 15.269A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.436 8.284`,key:`ui1hmy`}]]),de=r(`cloud-upload`,[[`path`,{d:`M12 13v8`,key:`1l5pq0`}],[`path`,{d:`M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242`,key:`1pljnt`}],[`path`,{d:`m8 17 4-4 4 4`,key:`1quai1`}]]),fe=r(`log-out`,[[`path`,{d:`m16 17 5-5-5-5`,key:`1bji2h`}],[`path`,{d:`M21 12H9`,key:`dn1m92`}],[`path`,{d:`M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4`,key:`1uf3rs`}]]),pe=r(`wallet-cards`,[[`path`,{d:`M3 11h3.75a2 2 0 0 1 1.6.8l.45.6a4 4 0 0 0 6.4 0l.45-.6a2 2 0 0 1 1.6-.8H21`,key:`1vwh6y`}],[`path`,{d:`M3 7h18`,key:`1uiuf2`}],[`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`,key:`h1oib`}]]),D=t(e(),1),O=n(),k=[{value:``,labelKey:`profile.avatar.address`},...b.map(e=>({value:w(e),labelKey:`profile.avatar.${e}`}))];function A(e){if(C(e))return!0;try{let t=new URL(e);return t.protocol===`http:`||t.protocol===`https:`}catch{return!1}}function j(e){return e===`disabled`?`is-disabled`:e===`working`?`is-working`:e===`synced`?`is-synced`:e===`error`?`is-error`:`is-idle`}function M({status:e,busy:t}){return t||e===`working`?(0,O.jsx)(p,{size:16,className:`ui-spinner`}):e===`synced`?(0,O.jsx)(v,{size:16}):e===`error`?(0,O.jsx)(u,{size:16}):(0,O.jsx)(h,{size:16})}function N(){let{formatNumber:e,t}=_(),n=s(e=>e.addToast),r=s(e=>e.hasBackend),a=i(e=>e.identity),u=i(e=>e.openLoginModal),v=i(e=>e.setUserIdentity),b=i(e=>e.logoutUser),C=oe(),[w,N]=(0,D.useState)(``),[I,L]=(0,D.useState)(``),[R,z]=(0,D.useState)(``),[B,V]=(0,D.useState)(!1),[H,U]=(0,D.useState)(null),W=(0,O.jsx)(le,{});(0,D.useEffect)(()=>{if(!a){N(``),L(``),z(``);return}N(a.displayName||a.username),L(S(a.avatar)||a.avatar||``),z(``)},[a]),(0,D.useEffect)(()=>{a&&C.refreshBackupSummary()},[C.refreshBackupSummary,r,a]);let G=(0,D.useMemo)(()=>a?ee(a.danger):null,[a]),me=(0,D.useMemo)(()=>G?c(G.private_key,G.ed_public_key):``,[G]);if(!a)return(0,O.jsx)(E,{header:W,children:(0,O.jsx)(`section`,{className:`profile-page`,children:(0,O.jsx)(`div`,{className:`profile-container narrow`,children:(0,O.jsxs)(`div`,{className:`profile-empty glass`,children:[(0,O.jsx)(`div`,{className:`profile-empty-icon`,children:(0,O.jsx)(f,{size:34})}),(0,O.jsx)(`h1`,{children:t(`profile.signedOut.title`)}),(0,O.jsx)(`p`,{children:t(`profile.signedOut.desc`)}),(0,O.jsxs)(`button`,{type:`button`,className:`btn btn-primary`,onClick:u,children:[(0,O.jsx)(f,{size:16}),t(`account.signIn`)]})]})})})});let he=S(a.avatar)||a.avatar||``,ge=x(a.address,a.avatar),K=a.address.toLowerCase(),_e=I.trim().length>0,ve=j(C.status),q=C.action===`backup`,J=C.action===`restore`,Y=C.action===`export`,X=C.action===`import`,ye=[{key:`notes`,label:t(`profile.backup.summary.notes`),value:C.notesCount},{key:`files`,label:t(`profile.backup.summary.files`),value:C.backupSummary.filesCount},{key:`trash`,label:t(`profile.backup.summary.trash`),value:C.backupSummary.trashFilesCount},{key:`channels`,label:t(`profile.backup.summary.channels`),value:C.backupSummary.channelsCount}];function be(){U({title:t(`profile.backup.confirm.backupTitle`),message:t(`profile.backup.confirm.backupMessage`),confirmText:t(`profile.backup.action.cloudBackup`),onConfirm:async()=>{U(null),await C.backupToCloud()}})}function xe(){U({title:t(`profile.backup.confirm.restoreTitle`),message:t(`profile.backup.confirm.restoreMessage`),confirmText:t(`profile.backup.action.cloudRestore`),onConfirm:async()=>{U(null),await C.restoreFromCloud({confirm:!1})}})}function Se(){return new Promise(e=>{let n=t=>{U(null),e(t)};U({title:t(`profile.backup.confirm.importTitle`),message:t(`profile.backup.confirm.restore`),confirmText:t(`profile.backup.action.importLocal`),onConfirm:()=>n(!0),onClose:()=>n(!1)})})}function Z(){C.importLocalBackup({requestConfirm:Se})}let Ce=[{key:`cloud-backup`,tone:`cloud-backup`,label:t(q?`profile.backup.status.backingUp`:`profile.backup.action.cloudBackup`),icon:q?(0,O.jsx)(p,{size:16,className:`ui-spinner`}):(0,O.jsx)(de,{size:16}),onClick:be},{key:`cloud-restore`,tone:`cloud-restore`,label:t(J?`profile.backup.status.restoring`:`profile.backup.action.cloudRestore`),icon:J?(0,O.jsx)(p,{size:16,className:`ui-spinner`}):(0,O.jsx)(ue,{size:16}),onClick:xe},{key:`export-local`,tone:`export-local`,label:t(Y?`profile.backup.status.exporting`:`profile.backup.action.exportLocal`),icon:Y?(0,O.jsx)(p,{size:16,className:`ui-spinner`}):(0,O.jsx)(re,{size:16}),onClick:C.exportLocalBackup},{key:`import-local`,tone:`import-local`,label:t(X?`profile.backup.status.importing`:`profile.backup.action.importLocal`),icon:X?(0,O.jsx)(p,{size:16,className:`ui-spinner`}):(0,O.jsx)(g,{size:16}),onClick:Z}];async function Q(e){if(r===!0)try{await te.put(`/api/user/profile`,{json:{displayName:e.displayName||e.username,avatar:e.avatar||``,updatedAt:e.profileUpdatedAt||Date.now()}}).json()}catch(e){n(await ne(e,t(`profile.backup.error.profileSaveFailed`)),`error`)}}function $(e){if(!a)return;let r={...a,avatar:e||void 0,profileUpdatedAt:Date.now()};v(r),Q(r),z(``),n(t(`profile.toast.avatarUpdated`),`success`)}function we(){if(!a)return;let e=w.trim()||a.username,r={...a,displayName:e,profileUpdatedAt:Date.now()};v(r),Q(r),N(e),n(t(`profile.toast.saved`),`success`)}function Te(){let e=I.trim();if(!e){$(void 0);return}if(!A(e)){z(t(`nav.avatarUrlInvalid`));return}$(e)}function Ee(){b(),V(!1)}return(0,O.jsxs)(E,{header:W,children:[(0,O.jsx)(`section`,{className:`profile-page`,children:(0,O.jsxs)(`div`,{className:`profile-container`,children:[(0,O.jsxs)(`section`,{className:`profile-panel profile-backup-card`,children:[(0,O.jsxs)(`div`,{className:`profile-panel-header profile-backup-header`,children:[(0,O.jsxs)(`div`,{children:[(0,O.jsx)(`h2`,{children:t(`profile.section.backup`)}),(0,O.jsx)(`p`,{children:t(`profile.section.backup.desc`)})]}),(0,O.jsxs)(`span`,{className:`profile-backup-status ${ve}`,children:[(0,O.jsx)(M,{status:C.status,busy:C.busy}),C.statusLabel]})]}),(0,O.jsx)(`div`,{className:`profile-backup-summary`,"aria-label":t(`profile.backup.summary.label`),children:ye.map(t=>(0,O.jsxs)(`div`,{className:`profile-backup-stat`,children:[(0,O.jsx)(`span`,{className:`profile-backup-stat-value`,children:t.value===null?C.backupSummary.loading?`...`:`-`:e(t.value)}),(0,O.jsx)(`span`,{className:`profile-backup-stat-label`,children:t.label})]},t.key))}),(0,O.jsx)(`div`,{className:`profile-backup-actions`,children:Ce.map(e=>(0,O.jsxs)(`button`,{type:`button`,className:[`btn`,`profile-backup-action`,`is-${e.tone}`].join(` `),disabled:C.busy,onClick:e.onClick,children:[e.icon,e.label]},e.key))})]}),(0,O.jsxs)(`header`,{className:`profile-header`,children:[(0,O.jsx)(`img`,{className:`profile-avatar-large`,src:ge,alt:``}),(0,O.jsxs)(`div`,{className:`profile-heading`,children:[(0,O.jsx)(`p`,{className:`profile-kicker`,children:t(`profile.kicker`)}),(0,O.jsx)(`h1`,{children:a.displayName||a.username}),(0,O.jsxs)(`div`,{className:`profile-address-line`,children:[(0,O.jsx)(`code`,{translate:`no`,children:K}),(0,O.jsx)(T,{text:K}),(0,O.jsxs)(`a`,{href:`https://debank.com/profile/${a.address}`,target:`_blank`,rel:`noopener noreferrer`,className:`btn btn-secondary btn-sm`,children:[(0,O.jsx)(ie,{size:14}),t(`web3.action.view`)]})]})]}),(0,O.jsxs)(`button`,{type:`button`,className:`btn btn-secondary profile-logout-btn`,onClick:()=>V(!0),children:[(0,O.jsx)(fe,{size:16}),t(`account.logout`)]})]}),(0,O.jsxs)(`div`,{className:`profile-grid`,children:[(0,O.jsxs)(`section`,{className:`profile-panel`,children:[(0,O.jsx)(`div`,{className:`profile-panel-header`,children:(0,O.jsxs)(`div`,{children:[(0,O.jsx)(`h2`,{children:t(`profile.section.account`)}),(0,O.jsx)(`p`,{children:t(`profile.section.account.desc`)})]})}),(0,O.jsxs)(`label`,{className:`profile-field`,children:[(0,O.jsx)(`span`,{children:t(`profile.label.displayName`)}),(0,O.jsxs)(`div`,{className:`profile-field-row`,children:[(0,O.jsx)(`input`,{className:`input`,value:w,onChange:e=>N(e.target.value),placeholder:t(`nav.displayNamePlaceholder`)}),(0,O.jsxs)(`button`,{type:`button`,className:`btn btn-primary`,onClick:we,children:[(0,O.jsx)(m,{size:16}),t(`profile.action.save`)]})]})]}),(0,O.jsx)(`div`,{className:`profile-facts`,children:(0,O.jsx)(P,{label:t(`profile.label.username`),value:a.username})})]}),(0,O.jsxs)(`section`,{className:`profile-panel`,children:[(0,O.jsx)(`div`,{className:`profile-panel-header`,children:(0,O.jsxs)(`div`,{children:[(0,O.jsx)(`h2`,{children:t(`profile.section.avatar`)}),(0,O.jsx)(`p`,{children:t(`profile.section.avatar.desc`)})]})}),(0,O.jsx)(`div`,{className:`profile-avatar-grid`,role:`list`,children:k.map(e=>{let n=he===e.value;return(0,O.jsxs)(`button`,{type:`button`,className:[`profile-avatar-option`,n?`selected`:``].filter(Boolean).join(` `),onClick:()=>$(e.value),"aria-pressed":n,title:t(e.labelKey),children:[(0,O.jsx)(`img`,{src:x(a.address,e.value),alt:``,"aria-hidden":`true`}),(0,O.jsx)(`span`,{children:t(e.labelKey)}),n&&(0,O.jsx)(`span`,{className:`profile-avatar-check`,children:(0,O.jsx)(d,{size:14})})]},e.value||`address`)})}),(0,O.jsxs)(`div`,{className:`profile-avatar-url`,children:[(0,O.jsxs)(`label`,{className:`profile-field`,htmlFor:`profile-avatar-url`,children:[(0,O.jsx)(`span`,{children:t(`profile.label.customAvatar`)}),(0,O.jsxs)(`div`,{className:`profile-field-row`,children:[(0,O.jsx)(`input`,{id:`profile-avatar-url`,className:`input`,value:I,onChange:e=>{L(e.target.value),z(``)},placeholder:t(`nav.avatarUrlPlaceholder`)}),(0,O.jsxs)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:Te,disabled:!_e,children:[(0,O.jsx)(m,{size:16}),t(`profile.action.save`)]})]})]}),R&&(0,O.jsx)(`p`,{className:`profile-error`,children:R})]})]})]}),(0,O.jsxs)(`section`,{className:`profile-panel profile-identity-panel`,children:[(0,O.jsxs)(`div`,{className:`profile-panel-header`,children:[(0,O.jsxs)(`div`,{children:[(0,O.jsx)(`h2`,{children:t(`profile.section.identity`)}),(0,O.jsx)(`p`,{children:t(`profile.section.identity.desc`)})]}),(0,O.jsxs)(o,{to:`/web3/`,hash:`wallet`,className:`btn btn-secondary`,children:[(0,O.jsx)(pe,{size:16}),t(`profile.action.openWallet`)]})]}),(0,O.jsxs)(`div`,{className:`profile-key-grid`,children:[G&&(0,O.jsxs)(O.Fragment,{children:[(0,O.jsx)(F,{title:t(`web3.label.ed25519Public`),icon:(0,O.jsx)(l,{size:18}),value:G.ed_public_key}),(0,O.jsx)(F,{title:t(`web3.label.x25519Public`),icon:(0,O.jsx)(ae,{size:18}),value:G.public_key})]}),(0,O.jsx)(F,{title:`IPNS ID`,icon:(0,O.jsx)(h,{size:18}),value:me||`-`})]})]})]})}),H&&(0,O.jsx)(se,{title:H.title,message:H.message,confirmText:H.confirmText,danger:H.danger,onConfirm:H.onConfirm,onClose:H.onClose||(()=>U(null))}),B&&(0,O.jsx)(ce,{className:`profile-logout-overlay`,onClose:()=>V(!1),children:(0,O.jsxs)(`div`,{className:`confirm-modal profile-logout-modal`,onClick:e=>e.stopPropagation(),children:[(0,O.jsxs)(`div`,{className:`modal-header`,children:[(0,O.jsx)(`h3`,{children:t(`account.logoutTitle`)}),(0,O.jsx)(`button`,{type:`button`,className:`btn btn-icon`,onClick:()=>V(!1),"aria-label":t(`common.close`),children:(0,O.jsx)(y,{size:18})})]}),(0,O.jsx)(`p`,{className:`profile-logout-reminder`,children:t(`profile.logout.backupReminder`)}),(0,O.jsxs)(`div`,{className:`profile-logout-backup-actions`,children:[(0,O.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,disabled:C.busy,onClick:()=>void C.backupToCloud(),children:t(`profile.backup.action.cloudBackup`)}),(0,O.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,disabled:C.busy,onClick:()=>void C.exportLocalBackup(),children:t(`profile.backup.action.exportLocal`)})]}),(0,O.jsxs)(`div`,{className:`modal-actions`,children:[(0,O.jsx)(`button`,{type:`button`,className:`btn btn-secondary`,onClick:()=>V(!1),children:t(`common.cancel`)}),(0,O.jsx)(`button`,{type:`button`,className:`btn btn-danger`,onClick:Ee,children:t(`account.logout`)})]})]})})]})}function P({label:e,value:t,copy:n=!1}){return(0,O.jsxs)(`div`,{className:`profile-fact`,children:[(0,O.jsx)(`span`,{children:e}),(0,O.jsxs)(`div`,{className:`profile-fact-value`,children:[(0,O.jsx)(`code`,{translate:`no`,children:t}),n&&(0,O.jsx)(T,{text:t})]})]})}function F({title:e,icon:t,value:n}){return(0,O.jsxs)(`div`,{className:`profile-key-card`,children:[(0,O.jsxs)(`div`,{className:`profile-key-card-header`,children:[(0,O.jsx)(`span`,{className:`profile-key-card-icon`,children:t}),(0,O.jsx)(`span`,{children:e})]}),(0,O.jsxs)(`div`,{className:`mono-row`,children:[(0,O.jsx)(`code`,{className:`mono`,translate:`no`,children:n}),(0,O.jsx)(T,{text:n})]})]})}var I=a(`/profile/`)({component:N});export{I as Route};
@@ -0,0 +1 @@
1
+ import{B as e}from"./useAppStore-DOnk608w.js";var t=e(`folder-open`,[[`path`,{d:`m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2`,key:`usdka0`}]]),n=e(`notebook-pen`,[[`path`,{d:`M13.4 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7.4`,key:`re6nr2`}],[`path`,{d:`M2 6h4`,key:`aawbzj`}],[`path`,{d:`M2 10h4`,key:`l0bgd4`}],[`path`,{d:`M2 14h4`,key:`1gsvsf`}],[`path`,{d:`M2 18h4`,key:`1bu2t1`}],[`path`,{d:`M21.378 5.626a1 1 0 1 0-3.004-3.004l-5.01 5.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z`,key:`pqwjuv`}]]);export{t as n,n as t};
@@ -1 +1 @@
1
- import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{B as r,E as i,W as a,_ as o,b as s,g as c,h as l,o as u,t as d,v as f,x as p,y as m}from"./useAppStore-DOnk608w.js";import{t as h}from"./AppTop-DZFTO9-m.js";import{A as g}from"./index-DjBN7bZV.js";import{i as _,n as v,r as y,t as b}from"./userProfile-BZvkCuet.js";import{t as x}from"./useChannelMessages-CDvw-f_x.js";var S=r(`spade`,[[`path`,{d:`M12 18v4`,key:`jadmvz`}],[`path`,{d:`M2 14.499a5.5 5.5 0 0 0 9.591 3.675.6.6 0 0 1 .818.001A5.5 5.5 0 0 0 22 14.5c0-2.29-1.5-4-3-5.5l-5.492-5.312a2 2 0 0 0-3-.02L5 8.999c-1.5 1.5-3 3.2-3 5.5`,key:`1aw2pz`}]]),C=r(`swords`,[[`polyline`,{points:`14.5 17.5 3 6 3 3 6 3 17.5 14.5`,key:`1hfsw2`}],[`line`,{x1:`13`,x2:`19`,y1:`19`,y2:`13`,key:`1vrmhu`}],[`line`,{x1:`16`,x2:`20`,y1:`16`,y2:`20`,key:`1bron3`}],[`line`,{x1:`19`,x2:`21`,y1:`21`,y2:`19`,key:`13pww6`}],[`polyline`,{points:`14.5 6.5 18 3 21 3 21 6 17.5 9.5`,key:`hbey2j`}],[`line`,{x1:`5`,x2:`9`,y1:`14`,y2:`18`,key:`1hf58s`}],[`line`,{x1:`7`,x2:`4`,y1:`17`,y2:`20`,key:`pidxm4`}],[`line`,{x1:`3`,x2:`5`,y1:`19`,y2:`21`,key:`1pehsh`}]]),w=n(),T=[{id:`gandengyan`,labelKey:`game.gandengyan.title`,href:`/game/gandengyan/`,icon:(0,w.jsx)(C,{size:16})},{id:`zhajinhua`,labelKey:`game.zhajinhua.title`,href:`/game/zhajinhua/`,icon:(0,w.jsx)(S,{size:16})}];function E({activeGame:e,closeSidebar:t}){let{t:n}=g();return(0,w.jsxs)(w.Fragment,{children:[(0,w.jsx)(h,{onNavigate:t}),(0,w.jsx)(`nav`,{className:`sidebar-nav`,children:T.map(r=>(0,w.jsxs)(a,{to:r.href,className:`sidebar-nav-btn ${e===r.id?`active`:``}`,onClick:t,children:[r.icon,(0,w.jsx)(`span`,{children:n(r.labelKey)})]},r.id))})]})}var D=t(e(),1),O=`game`,k=`mostbox.game.event`,A=[`gandengyan`,`zhajinhua`],j=`ABCDEFGHJKLMNPQRSTUVWXYZ23456789`;function M(e){let t=String(e||``).trim().toLowerCase();return A.includes(t)?t:``}function N(e){return m(e)}function P(e){return/^[A-Z0-9]{4,8}$/.test(String(e||``))}function F(){let e=``;for(let t=0;t<6;t++)e+=j[s(32)];return e}function I(e,t){let n=M(e),r=N(t);return!n||!P(r)?``:`game.${n}.${r.toLowerCase()}`}function L({gameId:e,roomCode:t,event:n,payload:r}){let i=M(e);return{kind:k,version:1,gameId:i,roomCode:N(t),event:String(n||``),eventId:l(i||`game`),payload:r||{}}}function R(e,t={}){try{let n=JSON.parse(String(e||``));if(!n||n.kind!==`mostbox.game.event`||n.version!==1||typeof n.event!=`string`||typeof n.eventId!=`string`)return null;let r=M(n.gameId),i=N(n.roomCode);return!r||!P(i)||t.gameId&&r!==M(t.gameId)||t.roomCode&&i!==N(t.roomCode)?null:{...n,gameId:r,roomCode:i,payload:n.payload&&typeof n.payload==`object`?n.payload:{}}}catch{return null}}function z(e=[],t={}){let n=[],r=new Map,i=``;for(let a of U(e)){let e=R(a.content,t);if(e){if(e.event===`room:create`){let t=V(e.payload?.player,a);if(!t)continue;i||=t.address,H(n,r,t);continue}if(e.event===`player:join`){let t=V(e.payload?.player,a);t&&H(n,r,t);continue}if(e.event===`player:leave`){let t=c(e.payload?.player?.address||a.author);if(t){let e=n.findIndex(e=>e.address===t);e!==-1&&(n.splice(e,1),r.delete(t))}}}}return{gameId:M(t.gameId),roomCode:N(t.roomCode),hostAddress:i,players:n}}function B(e=[],t={}){let n=null;for(let r of U(e)){let e=R(r.content,t);if(!e||e.event!==`room:state`)continue;let i=Number(e.payload?.seq||0);(!n||i>=Number(n.payload?.seq||0))&&(n=e)}return n}function V(e,t){if(!e||typeof e!=`object`)return null;let n=t&&typeof t==`object`?t:{author:t},r=n.author,i=c(e.address||r);if(!i||c(r)!==i)return null;let a=f(n.authorName||e.name,p(i)),s=o(n.avatar||e.avatar),l={address:i,name:a,publicKey:String(e.publicKey||``).trim(),joinedAt:Number(e.joinedAt||Date.now())};return s&&(l.avatar=s),l}function H(e,t,n){let r=t.get(n.address);if(r){Object.assign(r,n);return}e.push(n),t.set(n.address,n)}function U(e){return[...e].sort((e,t)=>Number(e.timestamp||0)-Number(t.timestamp||0))}function W({gameId:e,onError:t,getPlayerPayload:n}){let{t:r}=g(),a=d(e=>e.hasBackend),o=d(e=>e.checkBackend),s=d(e=>e.openConnectModal),l=i(e=>e.identity),f=i(e=>e.openLoginModal),[p,m]=(0,D.useState)(``),[h,v]=(0,D.useState)(``),[y,S]=(0,D.useState)([]),[C,w]=(0,D.useState)(!1),T=(0,D.useRef)(h);T.current=h;let E=a===!0,k=(0,D.useMemo)(()=>l?{...b(l),profileUpdatedAt:l.profileUpdatedAt}:{},[l?.avatar,l?.displayName,l?.profileUpdatedAt,l?.username]),A=(0,D.useCallback)(async(e,n)=>{let r=await u(e,n);t&&t(r)},[t]),j=(0,D.useCallback)(async(e=T.current)=>{if(!e||!E)return S([]),[];try{let t=await _.getChannelPresence(e);return T.current===e?(S(t),t):[]}catch(e){return console.warn(`[Game] Failed to fetch channel presence:`,e instanceof Error?e.message:e),[]}},[E]),M=(0,D.useCallback)((e,t)=>{if(e!==`channel:presence`)return;let n=String(t?.channelKey||t?.channel||``).trim(),r=T.current;r&&(!n||n===r)&&j(r)},[j]),P=(0,D.useCallback)(t=>!!R(t.content,{gameId:e,roomCode:p}),[e,p]),z=(0,D.useCallback)(t=>{let n=R(t.content,{gameId:e,roomCode:p});return n?`${t.author}-${n.eventId}`:`${t.author}-${t.timestamp}-${t.content}`},[e,p]),{clearMessages:B,connected:V,messages:H,sendMessage:U,syncMessages:W}=x({isReady:E,enabled:!!l,channelName:h,limit:500,acceptMessage:P,getMessageKey:z,onSyncError:e=>A(e,r(`game.room.error.readLog`)),onSocketEvent:M,onReconnect:()=>{j()},presenceEnabled:!!(h&&l),presenceProfile:k});(0,D.useEffect)(()=>{if(!h||!E){S([]);return}j(h)},[h,E,j]);let K=(0,D.useMemo)(()=>H.map(t=>({message:t,event:R(t.content,{gameId:e,roomCode:p})})).filter(e=>e.event),[e,H,p]),J=(0,D.useMemo)(()=>{let e=new Map;return y.forEach(t=>{let n=c(t.address);!n||!t.online||e.set(n,t)}),e},[y]),Y=(0,D.useMemo)(()=>new Set(J.keys()),[J]),X=(0,D.useCallback)(()=>l?E?!0:(s(),!1):(f(),!1),[E,s,f,l]);(0,D.useEffect)(()=>{a===null&&o()},[o,a]);let Z=(0,D.useCallback)(async(i,a=!1)=>{if(!X()||!l)return!1;let o=a?F():N(i),s=I(e,o);if(!s)return t&&t(r(`game.room.error.invalidCode`)),!1;w(!0);try{let t=await _.createChannel(s,O,b(l)),r=t.channelKey||t.key||s;return await G(r,l,e,o,a?`room:create`:`player:join`,{player:q(l,n?.(l))}),m(o),v(r),B(),!0}catch(e){return await A(e,r(a?`game.room.error.createFailed`:`game.room.error.joinFailed`)),!1}finally{w(!1)}},[X,e,n,t,A,B,r,l]);return{channelName:h,channelPresence:y,connected:V,createRoom:(0,D.useCallback)(()=>Z(``,!0),[Z]),ensureReady:X,isBackendReady:E,joinRoom:(0,D.useCallback)(e=>Z(e),[Z]),joining:C,messages:H,onlineAddresses:Y,presenceByAddress:J,roomCode:p,roomEvents:K,sendRoomEvent:(0,D.useCallback)(async(t,n={})=>{if(!X()||!l||!h||!p)return!1;let i=L({gameId:e,roomCode:p,event:t,payload:n}),a=JSON.stringify(i);try{return await U({channelName:h,content:a,optimisticId:`${l.address}-${i.eventId}`}),!0}catch(e){return await A(e,r(`game.room.error.sendEventFailed`)),!1}},[h,X,e,A,p,U,r,l]),setRoomCode:m,syncMessages:W,userIdentity:l}}async function G(e,t,n,r,i,a){let o=L({gameId:n,roomCode:r,event:i,payload:a});await _.sendChannelMessage({channelName:e,content:JSON.stringify(o),...y(t)})}function K(e){return{address:e.address,name:v(e),avatar:e.avatar||``,publicKey:``,joinedAt:Date.now()}}function q(e,t={}){let n=K(e),r={...n,...t};return Object.prototype.hasOwnProperty.call(t,`avatar`)||(r.avatar=n.avatar),r}export{S as a,E as i,z as n,B as r,W as t};
1
+ import{n as e,o as t,t as n}from"./jsx-runtime-Bt-cYkS5.js";import{B as r,E as i,W as a,_ as o,b as s,g as c,h as l,o as u,t as d,v as f,x as p,y as m}from"./useAppStore-DOnk608w.js";import{t as h}from"./AppTop-Cy0ZOCxO.js";import{A as g}from"./index-D0Uk9-58.js";import{i as _,n as v,r as y,t as b}from"./userProfile-BZvkCuet.js";import{t as x}from"./useChannelMessages-CDvw-f_x.js";var S=r(`spade`,[[`path`,{d:`M12 18v4`,key:`jadmvz`}],[`path`,{d:`M2 14.499a5.5 5.5 0 0 0 9.591 3.675.6.6 0 0 1 .818.001A5.5 5.5 0 0 0 22 14.5c0-2.29-1.5-4-3-5.5l-5.492-5.312a2 2 0 0 0-3-.02L5 8.999c-1.5 1.5-3 3.2-3 5.5`,key:`1aw2pz`}]]),C=r(`swords`,[[`polyline`,{points:`14.5 17.5 3 6 3 3 6 3 17.5 14.5`,key:`1hfsw2`}],[`line`,{x1:`13`,x2:`19`,y1:`19`,y2:`13`,key:`1vrmhu`}],[`line`,{x1:`16`,x2:`20`,y1:`16`,y2:`20`,key:`1bron3`}],[`line`,{x1:`19`,x2:`21`,y1:`21`,y2:`19`,key:`13pww6`}],[`polyline`,{points:`14.5 6.5 18 3 21 3 21 6 17.5 9.5`,key:`hbey2j`}],[`line`,{x1:`5`,x2:`9`,y1:`14`,y2:`18`,key:`1hf58s`}],[`line`,{x1:`7`,x2:`4`,y1:`17`,y2:`20`,key:`pidxm4`}],[`line`,{x1:`3`,x2:`5`,y1:`19`,y2:`21`,key:`1pehsh`}]]),w=n(),T=[{id:`gandengyan`,labelKey:`game.gandengyan.title`,href:`/game/gandengyan/`,icon:(0,w.jsx)(C,{size:16})},{id:`zhajinhua`,labelKey:`game.zhajinhua.title`,href:`/game/zhajinhua/`,icon:(0,w.jsx)(S,{size:16})}];function E({activeGame:e,closeSidebar:t}){let{t:n}=g();return(0,w.jsxs)(w.Fragment,{children:[(0,w.jsx)(h,{onNavigate:t}),(0,w.jsx)(`nav`,{className:`sidebar-nav`,children:T.map(r=>(0,w.jsxs)(a,{to:r.href,className:`sidebar-nav-btn ${e===r.id?`active`:``}`,onClick:t,children:[r.icon,(0,w.jsx)(`span`,{children:n(r.labelKey)})]},r.id))})]})}var D=t(e(),1),O=`game`,k=`mostbox.game.event`,A=[`gandengyan`,`zhajinhua`],j=`ABCDEFGHJKLMNPQRSTUVWXYZ23456789`;function M(e){let t=String(e||``).trim().toLowerCase();return A.includes(t)?t:``}function N(e){return m(e)}function P(e){return/^[A-Z0-9]{4,8}$/.test(String(e||``))}function F(){let e=``;for(let t=0;t<6;t++)e+=j[s(32)];return e}function I(e,t){let n=M(e),r=N(t);return!n||!P(r)?``:`game.${n}.${r.toLowerCase()}`}function L({gameId:e,roomCode:t,event:n,payload:r}){let i=M(e);return{kind:k,version:1,gameId:i,roomCode:N(t),event:String(n||``),eventId:l(i||`game`),payload:r||{}}}function R(e,t={}){try{let n=JSON.parse(String(e||``));if(!n||n.kind!==`mostbox.game.event`||n.version!==1||typeof n.event!=`string`||typeof n.eventId!=`string`)return null;let r=M(n.gameId),i=N(n.roomCode);return!r||!P(i)||t.gameId&&r!==M(t.gameId)||t.roomCode&&i!==N(t.roomCode)?null:{...n,gameId:r,roomCode:i,payload:n.payload&&typeof n.payload==`object`?n.payload:{}}}catch{return null}}function z(e=[],t={}){let n=[],r=new Map,i=``;for(let a of U(e)){let e=R(a.content,t);if(e){if(e.event===`room:create`){let t=V(e.payload?.player,a);if(!t)continue;i||=t.address,H(n,r,t);continue}if(e.event===`player:join`){let t=V(e.payload?.player,a);t&&H(n,r,t);continue}if(e.event===`player:leave`){let t=c(e.payload?.player?.address||a.author);if(t){let e=n.findIndex(e=>e.address===t);e!==-1&&(n.splice(e,1),r.delete(t))}}}}return{gameId:M(t.gameId),roomCode:N(t.roomCode),hostAddress:i,players:n}}function B(e=[],t={}){let n=null;for(let r of U(e)){let e=R(r.content,t);if(!e||e.event!==`room:state`)continue;let i=Number(e.payload?.seq||0);(!n||i>=Number(n.payload?.seq||0))&&(n=e)}return n}function V(e,t){if(!e||typeof e!=`object`)return null;let n=t&&typeof t==`object`?t:{author:t},r=n.author,i=c(e.address||r);if(!i||c(r)!==i)return null;let a=f(n.authorName||e.name,p(i)),s=o(n.avatar||e.avatar),l={address:i,name:a,publicKey:String(e.publicKey||``).trim(),joinedAt:Number(e.joinedAt||Date.now())};return s&&(l.avatar=s),l}function H(e,t,n){let r=t.get(n.address);if(r){Object.assign(r,n);return}e.push(n),t.set(n.address,n)}function U(e){return[...e].sort((e,t)=>Number(e.timestamp||0)-Number(t.timestamp||0))}function W({gameId:e,onError:t,getPlayerPayload:n}){let{t:r}=g(),a=d(e=>e.hasBackend),o=d(e=>e.checkBackend),s=d(e=>e.openConnectModal),l=i(e=>e.identity),f=i(e=>e.openLoginModal),[p,m]=(0,D.useState)(``),[h,v]=(0,D.useState)(``),[y,S]=(0,D.useState)([]),[C,w]=(0,D.useState)(!1),T=(0,D.useRef)(h);T.current=h;let E=a===!0,k=(0,D.useMemo)(()=>l?{...b(l),profileUpdatedAt:l.profileUpdatedAt}:{},[l?.avatar,l?.displayName,l?.profileUpdatedAt,l?.username]),A=(0,D.useCallback)(async(e,n)=>{let r=await u(e,n);t&&t(r)},[t]),j=(0,D.useCallback)(async(e=T.current)=>{if(!e||!E)return S([]),[];try{let t=await _.getChannelPresence(e);return T.current===e?(S(t),t):[]}catch(e){return console.warn(`[Game] Failed to fetch channel presence:`,e instanceof Error?e.message:e),[]}},[E]),M=(0,D.useCallback)((e,t)=>{if(e!==`channel:presence`)return;let n=String(t?.channelKey||t?.channel||``).trim(),r=T.current;r&&(!n||n===r)&&j(r)},[j]),P=(0,D.useCallback)(t=>!!R(t.content,{gameId:e,roomCode:p}),[e,p]),z=(0,D.useCallback)(t=>{let n=R(t.content,{gameId:e,roomCode:p});return n?`${t.author}-${n.eventId}`:`${t.author}-${t.timestamp}-${t.content}`},[e,p]),{clearMessages:B,connected:V,messages:H,sendMessage:U,syncMessages:W}=x({isReady:E,enabled:!!l,channelName:h,limit:500,acceptMessage:P,getMessageKey:z,onSyncError:e=>A(e,r(`game.room.error.readLog`)),onSocketEvent:M,onReconnect:()=>{j()},presenceEnabled:!!(h&&l),presenceProfile:k});(0,D.useEffect)(()=>{if(!h||!E){S([]);return}j(h)},[h,E,j]);let K=(0,D.useMemo)(()=>H.map(t=>({message:t,event:R(t.content,{gameId:e,roomCode:p})})).filter(e=>e.event),[e,H,p]),J=(0,D.useMemo)(()=>{let e=new Map;return y.forEach(t=>{let n=c(t.address);!n||!t.online||e.set(n,t)}),e},[y]),Y=(0,D.useMemo)(()=>new Set(J.keys()),[J]),X=(0,D.useCallback)(()=>l?E?!0:(s(),!1):(f(),!1),[E,s,f,l]);(0,D.useEffect)(()=>{a===null&&o()},[o,a]);let Z=(0,D.useCallback)(async(i,a=!1)=>{if(!X()||!l)return!1;let o=a?F():N(i),s=I(e,o);if(!s)return t&&t(r(`game.room.error.invalidCode`)),!1;w(!0);try{let t=await _.createChannel(s,O,b(l)),r=t.channelKey||t.key||s;return await G(r,l,e,o,a?`room:create`:`player:join`,{player:q(l,n?.(l))}),m(o),v(r),B(),!0}catch(e){return await A(e,r(a?`game.room.error.createFailed`:`game.room.error.joinFailed`)),!1}finally{w(!1)}},[X,e,n,t,A,B,r,l]);return{channelName:h,channelPresence:y,connected:V,createRoom:(0,D.useCallback)(()=>Z(``,!0),[Z]),ensureReady:X,isBackendReady:E,joinRoom:(0,D.useCallback)(e=>Z(e),[Z]),joining:C,messages:H,onlineAddresses:Y,presenceByAddress:J,roomCode:p,roomEvents:K,sendRoomEvent:(0,D.useCallback)(async(t,n={})=>{if(!X()||!l||!h||!p)return!1;let i=L({gameId:e,roomCode:p,event:t,payload:n}),a=JSON.stringify(i);try{return await U({channelName:h,content:a,optimisticId:`${l.address}-${i.eventId}`}),!0}catch(e){return await A(e,r(`game.room.error.sendEventFailed`)),!1}},[h,X,e,A,p,U,r,l]),setRoomCode:m,syncMessages:W,userIdentity:l}}async function G(e,t,n,r,i,a){let o=L({gameId:n,roomCode:r,event:i,payload:a});await _.sendChannelMessage({channelName:e,content:JSON.stringify(o),...y(t)})}function K(e){return{address:e.address,name:v(e),avatar:e.avatar||``,publicKey:``,joinedAt:Date.now()}}function q(e,t={}){let n=K(e),r={...n,...t};return Object.prototype.hasOwnProperty.call(t,`avatar`)||(r.avatar=n.avatar),r}export{S as a,E as i,z as n,B as r,W as t};
Binary file
Binary file
Binary file
@@ -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-B6acG3-t.css" data-precedence="default"/><title>下载 MostBox 桌面客户端</title><meta name="theme-color" content="#5e6ad2"/><meta name="description" content="下载 MostBox 桌面客户端,获得完整的 P2P 文件分享、下载校验和持续做种能力"/><link rel="modulepreload" href="/assets/index-DjBN7bZV.js"/><link rel="modulepreload" href="/assets/jsx-runtime-Bt-cYkS5.js"/><link rel="modulepreload" href="/assets/useAppStore-DOnk608w.js"/><link rel="modulepreload" href="/assets/useNavigate-DWlBD_-b.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-FV6RZlVI.css" data-precedence="default"/><title>下载 MostBox 客户端</title><meta name="theme-color" content="#5e6ad2"/><meta name="description" content="下载 MostBox 桌面或 Android 客户端,获得 P2P 文件分享、下载校验和持续做种能力"/><link rel="modulepreload" href="/assets/index-D0Uk9-58.js"/><link rel="modulepreload" href="/assets/jsx-runtime-Bt-cYkS5.js"/><link rel="modulepreload" href="/assets/useAppStore-DOnk608w.js"/><link rel="modulepreload" href="/assets/useNavigate-DWlBD_-b.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="download-page"><nav class="mkt-nav"><div class="mkt-nav-inner"><button type="button" class="mkt-nav-logo"><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-arrow-left" aria-hidden="true"><path d="m12 19-7-7 7-7"></path><path d="M19 12H5"></path></svg><span>MOST PEOPLE</span></button><div class="mkt-nav-cta"><button type="button" class="header-tool-btn" title="切换主题" aria-label="切换主题" aria-pressed="false"><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 language-toggle"><button type="button" aria-haspopup="menu" aria-expanded="false" aria-controls="_R_a5r6_" class="header-tool-btn" title="选择语言" aria-label="选择语言"><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 title="个人资料" aria-label="个人资料" href="/profile/" class="account-profile-link"><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-user" aria-hidden="true"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg></a></div></div></nav><section class="download-hero"><div class="mkt-container"><div class="download-hero-icon"><svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" 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></div><h1 class="download-hero-title">下载客户端</h1><p class="download-hero-desc">桌面客户端是当前 MVP 的首选入口,内置本地 P2P 节点,提供发布、下载校验和持续做种的完整能力。Web 端只连接已有 MostBox 节点。</p></div></section><section class="download-platforms"><div class="mkt-container"><h2 class="download-section-title">选择你的平台</h2><div class="download-options"><div class="ui-segmented-control download-source-tabs" role="tablist" aria-label="下载来源"><button type="button" role="tab" aria-selected="false" disabled="" class="ui-segmented-option download-source-tab"><svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" 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>Cloudflare R2</button><button type="button" role="tab" aria-selected="true" class="ui-segmented-option download-source-tab is-active"><svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-code" aria-hidden="true"><path d="m16 18 6-6-6-6"></path><path d="m8 6-6 6 6 6"></path></svg>GitHub Releases</button></div><p class="download-source-note">正在获取 Cloudflare R2 高速镜像。</p><div class="download-current-platform" aria-label="当前系统"><article class="download-current-card"><div class="download-current-main"><div class="download-current-icon"><svg xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-monitor" aria-hidden="true"><rect width="20" height="14" x="2" y="3" rx="2"></rect><line x1="8" x2="16" y1="21" y2="21"></line><line x1="12" x2="12" y1="17" y2="21"></line></svg></div><div class="download-current-copy"><div class="download-current-labels"><span class="download-current-kicker"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-circle-check" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><path d="m9 12 2 2 4-4"></path></svg>当前系统</span><span class="download-current-recommended">推荐下载</span></div><div class="download-current-heading"><h3>Windows</h3><span>x64</span></div><p>Windows 10 或更高版本</p><dl class="download-current-meta"><div><dt>来源</dt><dd>GitHub Releases</dd></div></dl></div></div><div class="download-current-actions"><span>已匹配你的设备</span><a href="https://github.com/most-people/most/releases/latest" class="btn btn-primary"><svg xmlns="http://www.w3.org/2000/svg" width="17" height="17" 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>下载 .exe</a><p>GitHub Releases</p></div></article></div><div class="download-other-platforms"><p class="download-other-platforms-title">桌面端</p><div class="download-platform-grid"><article class="download-platform-card"><div class="download-platform-icon"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-monitor" aria-hidden="true"><rect width="20" height="14" x="2" y="3" rx="2"></rect><line x1="8" x2="16" y1="21" y2="21"></line><line x1="12" x2="12" y1="17" y2="21"></line></svg></div><div class="download-platform-content"><div class="download-platform-heading"><h3>Windows</h3><span>arm64</span></div><p>Windows 10 或更高版本</p><dl class="download-platform-meta"><div><dt>来源</dt><dd>GitHub Releases</dd></div></dl><div class="download-platform-actions"><a href="https://github.com/most-people/most/releases/latest" class="btn btn-primary"><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>下载 .exe</a></div></div></article><article class="download-platform-card"><div class="download-platform-icon"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-apple" aria-hidden="true"><path d="M12 6.528V3a1 1 0 0 1 1-1h0"></path><path d="M18.237 21A15 15 0 0 0 22 11a6 6 0 0 0-10-4.472A6 6 0 0 0 2 11a15.1 15.1 0 0 0 3.763 10 3 3 0 0 0 3.648.648 5.5 5.5 0 0 1 5.178 0A3 3 0 0 0 18.237 21"></path></svg></div><div class="download-platform-content"><div class="download-platform-heading"><h3>macOS</h3><span>x64</span></div><p>macOS 12 Monterey 或更高版本</p><dl class="download-platform-meta"><div><dt>来源</dt><dd>GitHub Releases</dd></div></dl><div class="download-platform-actions"><a href="https://github.com/most-people/most/releases/latest" class="btn btn-primary"><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>下载 .dmg</a></div></div></article><article class="download-platform-card"><div class="download-platform-icon"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-apple" aria-hidden="true"><path d="M12 6.528V3a1 1 0 0 1 1-1h0"></path><path d="M18.237 21A15 15 0 0 0 22 11a6 6 0 0 0-10-4.472A6 6 0 0 0 2 11a15.1 15.1 0 0 0 3.763 10 3 3 0 0 0 3.648.648 5.5 5.5 0 0 1 5.178 0A3 3 0 0 0 18.237 21"></path></svg></div><div class="download-platform-content"><div class="download-platform-heading"><h3>macOS</h3><span>arm64</span></div><p>macOS 12 Monterey 或更高版本</p><dl class="download-platform-meta"><div><dt>来源</dt><dd>GitHub Releases</dd></div></dl><div class="download-platform-actions"><a href="https://github.com/most-people/most/releases/latest" class="btn btn-primary"><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>下载 .dmg</a></div></div></article><article class="download-platform-card"><div class="download-platform-icon"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-laptop" aria-hidden="true"><path d="M18 5a2 2 0 0 1 2 2v8.526a2 2 0 0 0 .212.897l1.068 2.127a1 1 0 0 1-.9 1.45H3.62a1 1 0 0 1-.9-1.45l1.068-2.127A2 2 0 0 0 4 15.526V7a2 2 0 0 1 2-2z"></path><path d="M20.054 15.987H3.946"></path></svg></div><div class="download-platform-content"><div class="download-platform-heading"><h3>Linux</h3><span>x64</span></div><p>Ubuntu 20.04+ / Debian 11+ / 其他主流发行版</p><dl class="download-platform-meta"><div><dt>来源</dt><dd>GitHub Releases</dd></div></dl><div class="download-platform-actions"><a href="https://github.com/most-people/most/releases/latest" class="btn btn-primary"><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>下载 .AppImage</a></div></div></article><article class="download-platform-card"><div class="download-platform-icon"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-laptop" aria-hidden="true"><path d="M18 5a2 2 0 0 1 2 2v8.526a2 2 0 0 0 .212.897l1.068 2.127a1 1 0 0 1-.9 1.45H3.62a1 1 0 0 1-.9-1.45l1.068-2.127A2 2 0 0 0 4 15.526V7a2 2 0 0 1 2-2z"></path><path d="M20.054 15.987H3.946"></path></svg></div><div class="download-platform-content"><div class="download-platform-heading"><h3>Linux</h3><span>arm64</span></div><p>Ubuntu 20.04+ / Debian 11+ / 其他主流发行版</p><dl class="download-platform-meta"><div><dt>来源</dt><dd>GitHub Releases</dd></div></dl><div class="download-platform-actions"><a href="https://github.com/most-people/most/releases/latest" class="btn btn-primary"><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>下载 .AppImage</a></div></div></article></div><div class="download-coming-soon"><p class="download-coming-soon-title">移动端</p><div class="download-coming-soon-grid"><article class="download-coming-soon-card"><div class="download-platform-icon download-coming-soon-icon"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" 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></div><div class="download-platform-content"><div class="download-platform-heading"><h3>iOS</h3><span>敬请期待</span></div><p>iPhone / iPad 客户端规划中</p></div></article><article class="download-coming-soon-card"><div class="download-platform-icon download-coming-soon-icon"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tablet-smartphone" aria-hidden="true"><rect width="10" height="14" x="3" y="8" rx="2"></rect><path d="M5 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2h-2.4"></path><path d="M8 18h.01"></path></svg></div><div class="download-platform-content"><div class="download-platform-heading"><h3>安卓</h3><span>敬请期待</span></div><p>Android 手机和平板客户端规划中</p></div></article></div></div></div></div></div></section><section class="download-comparison"><div class="mkt-container"><h2 class="download-section-title">Web 端 vs 桌面端</h2><div class="download-table-wrap"><table class="download-table"><thead><tr><th>功能</th><th>Web 端</th><th>桌面端</th></tr></thead><tbody><tr><td>节点能力</td><td class="col-web">连接已有节点</td><td class="col-desktop">内置本地节点</td></tr><tr><td>P2P 文件分享</td><td class="col-web">依赖所连节点</td><td class="col-desktop">完整支持</td></tr><tr><td>下载校验</td><td class="col-web">依赖所连节点</td><td class="col-desktop">完整支持</td></tr><tr><td>持续做种</td><td class="col-web">依赖所连节点</td><td class="col-desktop">默认开启</td></tr><tr><td>大文件传输</td><td class="col-web">依赖所连节点</td><td class="col-desktop">10GB 上限内</td></tr></tbody></table></div></div></section><section class="download-cta"><div class="mkt-container"><p class="download-hero-desc">使用 npm 入口请先安装 Node.js &gt;= 22.12,然后运行 npx most-box@latest 启动本机完整节点。</p></div></section><section class="download-cta"><div class="mkt-container"><a href="/" class="btn btn-primary">回首页</a></div></section><footer class="mkt-footer"><div class="mkt-container"><div class="mkt-footer-inner"><p class="mkt-footer-copy">MostBox</p></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-DjBN7bZV.js","/assets/jsx-runtime-Bt-cYkS5.js","/assets/useAppStore-DOnk608w.js","/assets/useNavigate-DWlBD_-b.js"],scripts:$R[5]=[$R[6]={attrs:$R[7]={type:"module",async:!0,src:"/assets/index-DjBN7bZV.js"}}],css:$R[8]=["/assets/index-B6acG3-t.css"]}}},matches:$R[9]=[$R[10]={i:"__root__",u:1782724170866,s:"success",ssr:!0},$R[11]={i:"downloaddownload",u:1782724170869,s:"success",ssr:!0}],lastMatchId:"downloaddownload"})($R["tsr"]);$_TSR.e();document.currentScript.remove()</script><script type="module" async="" src="/assets/index-DjBN7bZV.js"></script></body></html>
20
+ </script><!--$--><div class="download-page"><nav class="mkt-nav"><div class="mkt-nav-inner"><button type="button" class="mkt-nav-logo"><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-arrow-left" aria-hidden="true"><path d="m12 19-7-7 7-7"></path><path d="M19 12H5"></path></svg><span>MOST PEOPLE</span></button><div class="mkt-nav-cta"><button type="button" class="header-tool-btn" title="切换主题" aria-label="切换主题" aria-pressed="false"><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 language-toggle"><button type="button" aria-haspopup="menu" aria-expanded="false" aria-controls="_R_a5r6_" class="header-tool-btn" title="选择语言" aria-label="选择语言"><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 title="个人资料" aria-label="个人资料" href="/profile/" class="account-profile-link"><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-user" aria-hidden="true"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg></a></div></div></nav><section class="download-hero"><div class="mkt-container"><div class="download-hero-icon"><svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" 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></div><h1 class="download-hero-title">下载客户端</h1><p class="download-hero-desc">桌面客户端内置本地 P2P 节点,提供发布、下载校验和持续做种的完整能力;Android Alpha 支持前台聊天附件、下载校验和做种。Web 端只连接已有 MostBox 节点。</p></div></section><section class="download-platforms"><div class="mkt-container"><h2 class="download-section-title">选择你的平台</h2><div class="download-options"><div class="ui-segmented-control download-source-tabs" role="tablist" aria-label="下载来源"><button type="button" role="tab" aria-selected="false" disabled="" class="ui-segmented-option download-source-tab"><svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" 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>Cloudflare R2</button><button type="button" role="tab" aria-selected="true" class="ui-segmented-option download-source-tab is-active"><svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-code" aria-hidden="true"><path d="m16 18 6-6-6-6"></path><path d="m8 6-6 6 6 6"></path></svg>GitHub Releases</button></div><p class="download-source-note">正在获取 Cloudflare R2 高速镜像。</p><div class="download-current-platform" aria-label="当前系统"><article class="download-current-card"><div class="download-current-main"><div class="download-current-icon"><svg xmlns="http://www.w3.org/2000/svg" width="34" height="34" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-monitor" aria-hidden="true"><rect width="20" height="14" x="2" y="3" rx="2"></rect><line x1="8" x2="16" y1="21" y2="21"></line><line x1="12" x2="12" y1="17" y2="21"></line></svg></div><div class="download-current-copy"><div class="download-current-labels"><span class="download-current-kicker"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-circle-check" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><path d="m9 12 2 2 4-4"></path></svg>当前系统</span><span class="download-current-recommended">推荐下载</span></div><div class="download-current-heading"><h3>Windows</h3><span>x64</span></div><p>Windows 10 或更高版本</p><dl class="download-current-meta"><div><dt>来源</dt><dd>GitHub Releases</dd></div></dl></div></div><div class="download-current-actions"><span>已匹配你的设备</span><a href="https://github.com/most-people/most/releases/latest" class="btn btn-primary"><svg xmlns="http://www.w3.org/2000/svg" width="17" height="17" 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>下载 .exe</a><p>GitHub Releases</p></div></article></div><div class="download-other-platforms"><p class="download-other-platforms-title">其他可下载客户端</p><div class="download-platform-grid"><article class="download-platform-card"><div class="download-platform-icon"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-monitor" aria-hidden="true"><rect width="20" height="14" x="2" y="3" rx="2"></rect><line x1="8" x2="16" y1="21" y2="21"></line><line x1="12" x2="12" y1="17" y2="21"></line></svg></div><div class="download-platform-content"><div class="download-platform-heading"><h3>Windows</h3><span>arm64</span></div><p>Windows 10 或更高版本</p><dl class="download-platform-meta"><div><dt>来源</dt><dd>GitHub Releases</dd></div></dl><div class="download-platform-actions"><a href="https://github.com/most-people/most/releases/latest" class="btn btn-primary"><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>下载 .exe</a></div></div></article><article class="download-platform-card"><div class="download-platform-icon"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-apple" aria-hidden="true"><path d="M12 6.528V3a1 1 0 0 1 1-1h0"></path><path d="M18.237 21A15 15 0 0 0 22 11a6 6 0 0 0-10-4.472A6 6 0 0 0 2 11a15.1 15.1 0 0 0 3.763 10 3 3 0 0 0 3.648.648 5.5 5.5 0 0 1 5.178 0A3 3 0 0 0 18.237 21"></path></svg></div><div class="download-platform-content"><div class="download-platform-heading"><h3>macOS</h3><span>x64</span></div><p>macOS 12 Monterey 或更高版本</p><dl class="download-platform-meta"><div><dt>来源</dt><dd>GitHub Releases</dd></div></dl><div class="download-platform-actions"><a href="https://github.com/most-people/most/releases/latest" class="btn btn-primary"><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>下载 .dmg</a></div></div></article><article class="download-platform-card"><div class="download-platform-icon"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-apple" aria-hidden="true"><path d="M12 6.528V3a1 1 0 0 1 1-1h0"></path><path d="M18.237 21A15 15 0 0 0 22 11a6 6 0 0 0-10-4.472A6 6 0 0 0 2 11a15.1 15.1 0 0 0 3.763 10 3 3 0 0 0 3.648.648 5.5 5.5 0 0 1 5.178 0A3 3 0 0 0 18.237 21"></path></svg></div><div class="download-platform-content"><div class="download-platform-heading"><h3>macOS</h3><span>arm64</span></div><p>macOS 12 Monterey 或更高版本</p><dl class="download-platform-meta"><div><dt>来源</dt><dd>GitHub Releases</dd></div></dl><div class="download-platform-actions"><a href="https://github.com/most-people/most/releases/latest" class="btn btn-primary"><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>下载 .dmg</a></div></div></article><article class="download-platform-card"><div class="download-platform-icon"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-laptop" aria-hidden="true"><path d="M18 5a2 2 0 0 1 2 2v8.526a2 2 0 0 0 .212.897l1.068 2.127a1 1 0 0 1-.9 1.45H3.62a1 1 0 0 1-.9-1.45l1.068-2.127A2 2 0 0 0 4 15.526V7a2 2 0 0 1 2-2z"></path><path d="M20.054 15.987H3.946"></path></svg></div><div class="download-platform-content"><div class="download-platform-heading"><h3>Linux</h3><span>x64</span></div><p>Ubuntu 20.04+ / Debian 11+ / 其他主流发行版</p><dl class="download-platform-meta"><div><dt>来源</dt><dd>GitHub Releases</dd></div></dl><div class="download-platform-actions"><a href="https://github.com/most-people/most/releases/latest" class="btn btn-primary"><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>下载 .AppImage</a></div></div></article><article class="download-platform-card"><div class="download-platform-icon"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-laptop" aria-hidden="true"><path d="M18 5a2 2 0 0 1 2 2v8.526a2 2 0 0 0 .212.897l1.068 2.127a1 1 0 0 1-.9 1.45H3.62a1 1 0 0 1-.9-1.45l1.068-2.127A2 2 0 0 0 4 15.526V7a2 2 0 0 1 2-2z"></path><path d="M20.054 15.987H3.946"></path></svg></div><div class="download-platform-content"><div class="download-platform-heading"><h3>Linux</h3><span>arm64</span></div><p>Ubuntu 20.04+ / Debian 11+ / 其他主流发行版</p><dl class="download-platform-meta"><div><dt>来源</dt><dd>GitHub Releases</dd></div></dl><div class="download-platform-actions"><a href="https://github.com/most-people/most/releases/latest" class="btn btn-primary"><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>下载 .AppImage</a></div></div></article><article class="download-platform-card"><div class="download-platform-icon"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tablet-smartphone" aria-hidden="true"><rect width="10" height="14" x="3" y="8" rx="2"></rect><path d="M5 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2h-2.4"></path><path d="M8 18h.01"></path></svg></div><div class="download-platform-content"><div class="download-platform-heading"><h3>Android</h3><span>universal</span></div><p>Android Alpha APK,支持前台聊天附件、下载校验和做种</p><dl class="download-platform-meta"><div><dt>来源</dt><dd>GitHub Releases</dd></div></dl><div class="download-platform-actions"><a href="https://github.com/most-people/most/releases/latest" class="btn btn-primary"><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>下载 .apk</a></div></div></article></div><div class="download-coming-soon"><p class="download-coming-soon-title">移动端</p><div class="download-coming-soon-grid"><article class="download-coming-soon-card"><div class="download-platform-icon download-coming-soon-icon"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" 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></div><div class="download-platform-content"><div class="download-platform-heading"><h3>iOS</h3><span>敬请期待</span></div><p>iPhone / iPad 客户端规划中</p></div></article></div></div></div></div></div></section><section class="download-comparison"><div class="mkt-container"><h2 class="download-section-title">Web 端 vs 桌面端</h2><div class="download-table-wrap"><table class="download-table"><thead><tr><th>功能</th><th>Web 端</th><th>桌面端</th></tr></thead><tbody><tr><td>节点能力</td><td class="col-web">连接已有节点</td><td class="col-desktop">内置本地节点</td></tr><tr><td>P2P 文件分享</td><td class="col-web">依赖所连节点</td><td class="col-desktop">完整支持</td></tr><tr><td>下载校验</td><td class="col-web">依赖所连节点</td><td class="col-desktop">完整支持</td></tr><tr><td>持续做种</td><td class="col-web">依赖所连节点</td><td class="col-desktop">默认开启</td></tr><tr><td>大文件传输</td><td class="col-web">依赖所连节点</td><td class="col-desktop">10GB 上限内</td></tr></tbody></table></div></div></section><section class="download-cta"><div class="mkt-container"><p class="download-hero-desc">使用 npm 入口请先安装 Node.js &gt;= 22.12,然后运行 npx most-box@latest 启动本机完整节点。</p></div></section><section class="download-cta"><div class="mkt-container"><a href="/" class="btn btn-primary">回首页</a></div></section><footer class="mkt-footer"><div class="mkt-container"><div class="mkt-footer-inner"><p class="mkt-footer-copy">MostBox</p></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-D0Uk9-58.js","/assets/jsx-runtime-Bt-cYkS5.js","/assets/useAppStore-DOnk608w.js","/assets/useNavigate-DWlBD_-b.js"],scripts:$R[5]=[$R[6]={attrs:$R[7]={type:"module",async:!0,src:"/assets/index-D0Uk9-58.js"}}],css:$R[8]=["/assets/index-FV6RZlVI.css"]}}},matches:$R[9]=[$R[10]={i:"__root__",u:1782868918527,s:"success",ssr:!0},$R[11]={i:"downloaddownload",u:1782868918530,s:"success",ssr:!0}],lastMatchId:"downloaddownload"})($R["tsr"]);$_TSR.e();document.currentScript.remove()</script><script type="module" async="" src="/assets/index-D0Uk9-58.js"></script></body></html>
Binary file
Binary file
Binary file
package/out/index.html CHANGED
@@ -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-B6acG3-t.css" data-precedence="default"/><title>MostBox</title><meta name="theme-color" content="#5e6ad2"/><meta name="description" content="MostBox 是用户之间直连的聊天优先 P2P 工具箱:从聊天开始,传文件、整理知识库。"/><link rel="modulepreload" href="/assets/index-DjBN7bZV.js"/><link rel="modulepreload" href="/assets/jsx-runtime-Bt-cYkS5.js"/><link rel="modulepreload" href="/assets/useAppStore-DOnk608w.js"/><link rel="modulepreload" href="/assets/useNavigate-DWlBD_-b.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-FV6RZlVI.css" data-precedence="default"/><title>MostBox</title><meta name="theme-color" content="#5e6ad2"/><meta name="description" content="MostBox 是用户之间直连的聊天优先 P2P 工具箱:从聊天开始,传文件、整理知识库。"/><link rel="modulepreload" href="/assets/index-D0Uk9-58.js"/><link rel="modulepreload" href="/assets/jsx-runtime-Bt-cYkS5.js"/><link rel="modulepreload" href="/assets/useAppStore-DOnk608w.js"/><link rel="modulepreload" href="/assets/useNavigate-DWlBD_-b.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 class="mkt-nav-logo active" href="/" data-status="active" aria-current="page"><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="header-tool-btn" title="切换主题" aria-label="切换主题" aria-pressed="false"><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 language-toggle"><button type="button" aria-haspopup="menu" aria-expanded="false" aria-controls="_R_55r6_" class="header-tool-btn" title="选择语言" aria-label="选择语言"><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><a title="个人资料" aria-label="个人资料" href="/profile/" class="account-profile-link"><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-user" aria-hidden="true"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg></a></div></div></nav><main class="mkt-layout-main"><div class="portal-page"><section class="portal-hero"><div class="mkt-container"><h1 class="portal-hero-title">MOST PEOPLE</h1><p class="portal-hero-subtitle">用户之间直接连接的 P2P 工具箱。从聊天开始,直连传文件,整理知识库。</p></div></section><section class="portal-cards-section"><div class="mkt-container"><div class="portal-cards"><button class="portal-card active"><a title="打开聊天" href="/chat/" class="btn btn-icon portal-card-open-btn"><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-arrow-up-right" aria-hidden="true"><path d="M7 7h10v10"></path><path d="M7 17 17 7"></path></svg></a><div class="portal-card-icon"><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-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></div><div class="portal-card-title">聊天</div><div class="portal-card-subtitle">用户之间直接连接</div><div class="ui-badge portal-card-status checking"><span class="status-dot checking"></span>检测中</div></button><button class="portal-card "><a title="打开文件" href="/app/" class="btn btn-icon portal-card-open-btn"><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-arrow-up-right" aria-hidden="true"><path d="M7 7h10v10"></path><path d="M7 17 17 7"></path></svg></a><div class="portal-card-icon"><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-folder-open" aria-hidden="true"><path d="m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2"></path></svg></div><div class="portal-card-title">文件</div><div class="portal-card-subtitle">聊天附件和传输管理</div><div class="ui-badge portal-card-status checking"><span class="status-dot checking"></span>检测中</div></button><button class="portal-card "><a title="打开知识库" href="/note/" class="btn btn-icon portal-card-open-btn"><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-arrow-up-right" aria-hidden="true"><path d="M7 7h10v10"></path><path d="M7 17 17 7"></path></svg></a><div class="portal-card-icon"><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-notebook-pen" aria-hidden="true"><path d="M13.4 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7.4"></path><path d="M2 6h4"></path><path d="M2 10h4"></path><path d="M2 14h4"></path><path d="M2 18h4"></path><path d="M21.378 5.626a1 1 0 1 0-3.004-3.004l-5.01 5.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z"></path></svg></div><div class="portal-card-title">知识库</div><div class="portal-card-subtitle">Markdown 知识库</div><div class="ui-badge portal-card-status ready"><span class="status-dot ready"></span>已就绪</div></button><button class="portal-card "><a title="打开游戏" href="/game/gandengyan/" class="btn btn-icon portal-card-open-btn"><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-arrow-up-right" aria-hidden="true"><path d="M7 7h10v10"></path><path d="M7 17 17 7"></path></svg></a><div class="portal-card-icon"><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-gamepad2 lucide-gamepad-2" aria-hidden="true"><line x1="6" x2="10" y1="11" y2="11"></line><line x1="8" x2="8" y1="9" y2="13"></line><line x1="15" x2="15.01" y1="12" y2="12"></line><line x1="18" x2="18.01" y1="10" y2="10"></line><path d="M17.32 5H6.68a4 4 0 0 0-3.978 3.59c-.006.052-.01.101-.017.152C2.604 9.416 2 14.456 2 16a3 3 0 0 0 3 3c1 0 1.5-.5 2-1l1.414-1.414A2 2 0 0 1 9.828 16h4.344a2 2 0 0 1 1.414.586L17 18c.5.5 1 1 2 1a3 3 0 0 0 3-3c0-1.545-.604-6.584-.685-7.258-.007-.05-.011-.1-.017-.151A4 4 0 0 0 17.32 5z"></path></svg></div><div class="portal-card-title">游戏</div><div class="portal-card-subtitle">独立房间游戏</div><div class="ui-badge portal-card-status checking"><span class="status-dot checking"></span>检测中</div></button><button class="portal-card "><a title="打开Web3" href="/web3/" class="btn btn-icon portal-card-open-btn"><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-arrow-up-right" aria-hidden="true"><path d="M7 7h10v10"></path><path d="M7 17 17 7"></path></svg></a><div class="portal-card-icon"><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-wallet" aria-hidden="true"><path d="M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1"></path><path d="M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4"></path></svg></div><div class="portal-card-title">Web3</div><div class="portal-card-subtitle">独立账户工具箱</div><div class="ui-badge portal-card-status ready"><span class="status-dot ready"></span>已就绪</div></button></div><div class="portal-node-actions" aria-label="节点入口"><button class="btn btn-secondary"><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-server" aria-hidden="true"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"></rect><rect width="20" height="8" x="2" y="14" rx="2" ry="2"></rect><line x1="6" x2="6.01" y1="6" y2="6"></line><line x1="6" x2="6.01" y1="18" y2="18"></line></svg>Web 连接节点</button><a href="/admin/" class="btn btn-secondary"><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-hard-drive" aria-hidden="true"><path d="M10 16h.01"></path><path d="M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path><path d="M21.946 12.013H2.054"></path><path d="M6 16h.01"></path></svg>节点管理</a></div></div></section><section class="portal-marketing"><div class="mkt-container"><div class="portal-marketing-inner"><div class="portal-marketing-header"><h2>从聊天开始</h2><p>创建聊天或房间,把房间 ID 发给朋友;消息、文件和知识库整理都从这里开始。</p></div><div class="portal-marketing-features"><div class="portal-feature-item"><span class="portal-feature-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check" aria-hidden="true"><path d="M20 6 9 17l-5-5"></path></svg></span><span>私域聊天和房间消息</span></div><div class="portal-feature-item"><span class="portal-feature-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check" aria-hidden="true"><path d="M20 6 9 17l-5-5"></path></svg></span><span>本地登录身份保护消息署名</span></div><div class="portal-feature-item"><span class="portal-feature-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check" aria-hidden="true"><path d="M20 6 9 17l-5-5"></path></svg></span><span>消息通过 P2P Channel 同步</span></div><div class="portal-feature-item"><span class="portal-feature-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check" aria-hidden="true"><path d="M20 6 9 17l-5-5"></path></svg></span><span>文件和知识库自然接入聊天流程</span></div><div class="portal-feature-item"><span class="portal-feature-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check" aria-hidden="true"><path d="M20 6 9 17l-5-5"></path></svg></span><span>无需中心化账号注册</span></div></div><div class="portal-marketing-steps"><div class="portal-step"><span class="portal-step-num">1</span><div class="portal-step-content"><strong>下载客户端</strong><p>支持 Windows、macOS 和 Linux。</p><p class="portal-step-link"><a href="/download/">前往下载页<!-- --> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link" aria-hidden="true"><path d="M15 3h6v6"></path><path d="M10 14 21 3"></path><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path></svg></a></p></div></div><div class="portal-step"><span class="portal-step-num">2</span><div class="portal-step-content"><strong>创建聊天</strong><p>输入房间名即可加入或创建,并把房间 ID 发给朋友。</p></div></div><div class="portal-step"><span class="portal-step-num">3</span><div class="portal-step-content"><strong>开始聊天</strong><p>先发消息,再发送附件或保存到知识库。</p></div></div></div><div class="portal-actions"><a href="/chat/" class="btn btn-primary">进入 聊天<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-arrow-right" aria-hidden="true"><path d="M5 12h14"></path><path d="m12 5 7 7-7 7"></path></svg></a></div></div></div></section></div></main><footer class="mkt-footer"><div class="mkt-container"><div class="mkt-footer-inner"><div class="mkt-footer-links"><a class="active" href="/" data-status="active" aria-current="page">关于</a><a href="/ping/">网络</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.2</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-DjBN7bZV.js","/assets/jsx-runtime-Bt-cYkS5.js","/assets/useAppStore-DOnk608w.js","/assets/useNavigate-DWlBD_-b.js"],scripts:$R[5]=[$R[6]={attrs:$R[7]={type:"module",async:!0,src:"/assets/index-DjBN7bZV.js"}}],css:$R[8]=["/assets/index-B6acG3-t.css"]}}},matches:$R[9]=[$R[10]={i:"__root__",u:1782724170712,s:"success",ssr:!0},$R[11]={i:"",u:1782724170786,s:"success",ssr:!0}],lastMatchId:""})($R["tsr"]);$_TSR.e();document.currentScript.remove()</script><script type="module" async="" src="/assets/index-DjBN7bZV.js"></script></body></html>
20
+ </script><!--$--><div class="mkt-layout"><nav class="mkt-nav"><div class="mkt-nav-inner"><a class="mkt-nav-logo active" href="/" data-status="active" aria-current="page"><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="header-tool-btn" title="切换主题" aria-label="切换主题" aria-pressed="false"><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 language-toggle"><button type="button" aria-haspopup="menu" aria-expanded="false" aria-controls="_R_55r6_" class="header-tool-btn" title="选择语言" aria-label="选择语言"><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><a title="个人资料" aria-label="个人资料" href="/profile/" class="account-profile-link"><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-user" aria-hidden="true"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg></a></div></div></nav><main class="mkt-layout-main"><div class="portal-page"><section class="portal-hero"><div class="mkt-container"><h1 class="portal-hero-title">MOST PEOPLE</h1><p class="portal-hero-subtitle">用户之间直接连接的 P2P 工具箱。从聊天开始,直连传文件,整理知识库。</p></div></section><section class="portal-cards-section"><div class="mkt-container"><div class="portal-cards"><button class="portal-card active"><a title="打开聊天" href="/chat/" class="btn btn-icon portal-card-open-btn"><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-arrow-up-right" aria-hidden="true"><path d="M7 7h10v10"></path><path d="M7 17 17 7"></path></svg></a><div class="portal-card-icon"><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-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></div><div class="portal-card-title">聊天</div><div class="portal-card-subtitle">用户之间直接连接</div><div class="ui-badge portal-card-status checking"><span class="status-dot checking"></span>检测中</div></button><button class="portal-card "><a title="打开文件" href="/app/" class="btn btn-icon portal-card-open-btn"><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-arrow-up-right" aria-hidden="true"><path d="M7 7h10v10"></path><path d="M7 17 17 7"></path></svg></a><div class="portal-card-icon"><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-folder-open" aria-hidden="true"><path d="m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2"></path></svg></div><div class="portal-card-title">文件</div><div class="portal-card-subtitle">聊天附件和传输管理</div><div class="ui-badge portal-card-status checking"><span class="status-dot checking"></span>检测中</div></button><button class="portal-card "><a title="打开知识库" href="/note/" class="btn btn-icon portal-card-open-btn"><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-arrow-up-right" aria-hidden="true"><path d="M7 7h10v10"></path><path d="M7 17 17 7"></path></svg></a><div class="portal-card-icon"><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-notebook-pen" aria-hidden="true"><path d="M13.4 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7.4"></path><path d="M2 6h4"></path><path d="M2 10h4"></path><path d="M2 14h4"></path><path d="M2 18h4"></path><path d="M21.378 5.626a1 1 0 1 0-3.004-3.004l-5.01 5.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z"></path></svg></div><div class="portal-card-title">知识库</div><div class="portal-card-subtitle">Markdown 知识库</div><div class="ui-badge portal-card-status ready"><span class="status-dot ready"></span>已就绪</div></button><button class="portal-card "><a title="打开游戏" href="/game/gandengyan/" class="btn btn-icon portal-card-open-btn"><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-arrow-up-right" aria-hidden="true"><path d="M7 7h10v10"></path><path d="M7 17 17 7"></path></svg></a><div class="portal-card-icon"><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-gamepad2 lucide-gamepad-2" aria-hidden="true"><line x1="6" x2="10" y1="11" y2="11"></line><line x1="8" x2="8" y1="9" y2="13"></line><line x1="15" x2="15.01" y1="12" y2="12"></line><line x1="18" x2="18.01" y1="10" y2="10"></line><path d="M17.32 5H6.68a4 4 0 0 0-3.978 3.59c-.006.052-.01.101-.017.152C2.604 9.416 2 14.456 2 16a3 3 0 0 0 3 3c1 0 1.5-.5 2-1l1.414-1.414A2 2 0 0 1 9.828 16h4.344a2 2 0 0 1 1.414.586L17 18c.5.5 1 1 2 1a3 3 0 0 0 3-3c0-1.545-.604-6.584-.685-7.258-.007-.05-.011-.1-.017-.151A4 4 0 0 0 17.32 5z"></path></svg></div><div class="portal-card-title">游戏</div><div class="portal-card-subtitle">独立房间游戏</div><div class="ui-badge portal-card-status checking"><span class="status-dot checking"></span>检测中</div></button><button class="portal-card "><a title="打开Web3" href="/web3/" class="btn btn-icon portal-card-open-btn"><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-arrow-up-right" aria-hidden="true"><path d="M7 7h10v10"></path><path d="M7 17 17 7"></path></svg></a><div class="portal-card-icon"><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-wallet" aria-hidden="true"><path d="M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1"></path><path d="M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4"></path></svg></div><div class="portal-card-title">Web3</div><div class="portal-card-subtitle">独立账户工具箱</div><div class="ui-badge portal-card-status ready"><span class="status-dot ready"></span>已就绪</div></button></div><div class="portal-node-actions" aria-label="节点入口"><button class="btn btn-secondary"><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-server" aria-hidden="true"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"></rect><rect width="20" height="8" x="2" y="14" rx="2" ry="2"></rect><line x1="6" x2="6.01" y1="6" y2="6"></line><line x1="6" x2="6.01" y1="18" y2="18"></line></svg>Web 连接节点</button><a href="/admin/" class="btn btn-secondary"><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-hard-drive" aria-hidden="true"><path d="M10 16h.01"></path><path d="M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path><path d="M21.946 12.013H2.054"></path><path d="M6 16h.01"></path></svg>节点管理</a></div></div></section><section class="portal-marketing"><div class="mkt-container"><div class="portal-marketing-inner"><div class="portal-marketing-header"><h2>从聊天开始</h2><p>创建聊天或房间,把房间 ID 发给朋友;消息、文件和知识库整理都从这里开始。</p></div><div class="portal-marketing-features"><div class="portal-feature-item"><span class="portal-feature-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check" aria-hidden="true"><path d="M20 6 9 17l-5-5"></path></svg></span><span>私域聊天和房间消息</span></div><div class="portal-feature-item"><span class="portal-feature-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check" aria-hidden="true"><path d="M20 6 9 17l-5-5"></path></svg></span><span>本地登录身份保护消息署名</span></div><div class="portal-feature-item"><span class="portal-feature-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check" aria-hidden="true"><path d="M20 6 9 17l-5-5"></path></svg></span><span>消息通过 P2P Channel 同步</span></div><div class="portal-feature-item"><span class="portal-feature-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check" aria-hidden="true"><path d="M20 6 9 17l-5-5"></path></svg></span><span>文件和知识库自然接入聊天流程</span></div><div class="portal-feature-item"><span class="portal-feature-icon"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check" aria-hidden="true"><path d="M20 6 9 17l-5-5"></path></svg></span><span>无需中心化账号注册</span></div></div><div class="portal-marketing-steps"><div class="portal-step"><span class="portal-step-num">1</span><div class="portal-step-content"><strong>下载客户端</strong><p>支持 Windows、macOS 和 Linux。</p><p class="portal-step-link"><a href="/download/">前往下载页<!-- --> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link" aria-hidden="true"><path d="M15 3h6v6"></path><path d="M10 14 21 3"></path><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path></svg></a></p></div></div><div class="portal-step"><span class="portal-step-num">2</span><div class="portal-step-content"><strong>创建聊天</strong><p>输入房间名即可加入或创建,并把房间 ID 发给朋友。</p></div></div><div class="portal-step"><span class="portal-step-num">3</span><div class="portal-step-content"><strong>开始聊天</strong><p>先发消息,再发送附件或保存到知识库。</p></div></div></div><div class="portal-actions"><a href="/chat/" class="btn btn-primary">进入 聊天<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-arrow-right" aria-hidden="true"><path d="M5 12h14"></path><path d="m12 5 7 7-7 7"></path></svg></a></div></div></div></section></div></main><footer class="mkt-footer"><div class="mkt-container"><div class="mkt-footer-inner"><div class="mkt-footer-links"><a class="active" href="/" data-status="active" aria-current="page">关于</a><a href="/ping/">网络</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.4</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-D0Uk9-58.js","/assets/jsx-runtime-Bt-cYkS5.js","/assets/useAppStore-DOnk608w.js","/assets/useNavigate-DWlBD_-b.js"],scripts:$R[5]=[$R[6]={attrs:$R[7]={type:"module",async:!0,src:"/assets/index-D0Uk9-58.js"}}],css:$R[8]=["/assets/index-FV6RZlVI.css"]}}},matches:$R[9]=[$R[10]={i:"__root__",u:1782868918380,s:"success",ssr:!0},$R[11]={i:"",u:1782868918456,s:"success",ssr:!0}],lastMatchId:""})($R["tsr"]);$_TSR.e();document.currentScript.remove()</script><script type="module" async="" src="/assets/index-D0Uk9-58.js"></script></body></html>
Binary file