From 2258a8aef7fcb790adc511820d16ab4eb4815ad8 Mon Sep 17 00:00:00 2001 From: Warexpor Date: Fri, 21 Aug 2026 23:03:16 +0300 Subject: [PATCH 1/4] Add DESIGN.md and PRODUCT.md for the connected Operate shell. These files pin path-first B&W chrome so the rebuild can follow a contract instead of the old CRT costume. --- DESIGN.md | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++ PRODUCT.md | 48 +++++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 DESIGN.md create mode 100644 PRODUCT.md diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 0000000..557fb6c --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,124 @@ +--- +name: Entangled VPN — Connected Shell +description: Calm signal-bench Operate UI — matte B&W, path-first chroma, dense peer channels. +colors: + bg: "#0a0a0a" + surface: "#111111" + raised: "#181818" + border: "#2a2a2a" + hairline: "#3a3a3a" + muted: "#8a8a8a" + text: "#f0f0f0" + dim: "#5c5c5c" + cta: "#ffffff" + cta-ink: "#0a0a0a" + live: "#2fbf62" + fault: "#e23d3d" + bg-light: "#f5f5f5" + surface-light: "#ececec" + live-light: "#1a8f45" + fault-light: "#c41e1e" +typography: + sans: + fontFamily: "ui-sans-serif, 'Segoe UI', system-ui, sans-serif" + fontSize: "13px" + fontWeight: 400 + lineHeight: 1.45 + mono: + fontFamily: "ui-monospace, 'Cascadia Code', Consolas, monospace" + fontSize: "12px" + fontWeight: 500 + lineHeight: 1.35 + label: + fontFamily: "ui-sans-serif, 'Segoe UI', system-ui, sans-serif" + fontSize: "10px" + fontWeight: 600 + lineHeight: 1.2 + letterSpacing: "0.08em" +rounded: + sm: "4px" + md: "6px" +spacing: + xs: "4px" + sm: "8px" + md: "12px" + lg: "16px" + xl: "24px" +components: + btn: + backgroundColor: "transparent" + textColor: "{colors.text}" + rounded: "{rounded.md}" + padding: "6px 12px" + height: "32px" + btn-cta: + backgroundColor: "{colors.cta}" + textColor: "{colors.cta-ink}" + rounded: "{rounded.md}" + padding: "6px 12px" + height: "32px" +--- + +# Design System: Entangled VPN — Connected Shell + +## Overview + +Connected mode is an Operate surface for a friend LAN. It borrows the *idea* of a signal bench — path quality as the primary instrument — without dressing up as a CRT or Discord clone. Intro (`ConnectView` + starfield) is a separate surface and is not restyled here. + +## Thesis + +Room + VIP + path are the first things you see. Peers are a dense channel list. Chat is available without becoming the product. Green and red are scarce and meaningful. + +## Colors + +Neutrals only for structure. Two chroma roles: + +| Token | Use | +|---|---| +| `--live` | Direct / p2p path only | +| `--fault` | Relay, reconnecting, unread, errors | + +Everything else is black, white, or grey. Light theme inverts neutrals and keeps the same two chroma roles. + +Connected tokens live under `html[data-app="connected"]` so intro keeps `:root` / Bungee / starfield unchanged. + +## Typography + +Connected shell uses system sans for chrome and mono for VIP, IPs, ping, and path. Do not load a second display face for connected mode (intro keeps Bungee). Labels are small uppercase with modest tracking — used as field captions in the header, not as kickers above every pane title. + +## Layout (first viewport) + +1. **Header band** — Entangled wordmark (quiet), active room, copyable VIP, path status (dot + short label), peers count, settings, disconnect +2. **Left rail** — saved networks, create / join +3. **Main** — peers as home (`network`); chat and settings as alternate main panes (keep existing view routing) +4. **Footer** — slim status strip for server / version only (facts already in the header are not repeated loudly) + +No starfield behind the connected shell. Opaque bench surfaces only. + +## Components + +- Ghost / quiet / CTA buttons with 4–6px radius +- 8px path dots (`live` / `fault` / idle grey) +- Peer rows: nick, mono IP, path, ping, ping + chat actions +- Confirm dialogs for destructive actions +- Theme control in settings (and optional header) +- SVG icons only (no Unicode `⋯` / `▼` as chrome) + +## Motion + +Short opacity / border transitions. Honor `prefers-reduced-motion`. No view-transition gimmicks, grain, or glow. + +## Do + +- Derive one `pathAggregate`: `direct` | `relay` | `reconnecting` | `disconnected` +- Ship disconnect in connected chrome +- Keep ConnectView markup and `space.css` frozen +- Add Vite `sim.js` + `?connected=1` for preview +- Prefer deletion of ASCII chrome (`[~]`, `[>]`) in connected views + +## Don't + +- Invent crypto / throughput / engine footers +- Paint green or red for decoration +- Port the previous over-instrumented LED/graticule costume wholesale +- Change intro brand, tagline, or starfield diff --git a/PRODUCT.md b/PRODUCT.md new file mode 100644 index 0000000..79e61f5 --- /dev/null +++ b/PRODUCT.md @@ -0,0 +1,48 @@ +# Product + + + +## Platform + +web + +## Users + +Small friend group on Windows. Admin Wintun client. Join a named room for a session of games, files, chat. + +## Product Purpose + +Private virtual LAN (`10.242.0.0/24`). Success: in a room, have a VIP, peers reachable (P2P or relay), chat works. + +## Positioning + +Mesh for a handful of people, not a consumer VPN. Rooms, pipe invites, owner delete, in-mesh chat. + +## Operating Context + +Wails v2 desktop. Connect screen first (frozen). After connect: networks, peers, chat, settings. Path: P2P, UDP relay, or WebSocket. Languages: en, ru, zh. Vite sim for frontend preview. + +## Capabilities and Constraints + +- Connected: networks rail, peers home, chat, settings, disconnect, theme, copy VIP, ping, DMs. +- Intro / ConnectView + space.css are out of scope and must keep current look. +- Do not invent crypto claims, server hosts, or fake telemetry. +- Preview: Vite DEV sim with `?connected=1` when `window.go` is absent. + +## Brand Commitments + +- Name: Entangled. Intro stays as-is. +- Connected palette: high-contrast black-and-white. Subtle green only for Direct/p2p. Subtle red only for relay/fault/unread/error. No other chroma. +- Direction: signal-bench Operate shell — path quality first, dense desktop craft, not Discord neon or CRT costume. +- Connected may look different from intro; both must feel like the same product. + +## Product Principles + +- Room and virtual IP are the facts that matter. +- Path quality is the primary chrome signal. +- Density for a desktop window. +- Prefer real status over decorative instruments. + +## Accessibility & Inclusion + +Keyboard focus, `prefers-reduced-motion`, existing i18n keys. No English-only new copy without locale keys. From 62b10c44ddcb2047fd1e4dd035b6f4249b760f5b Mon Sep 17 00:00:00 2001 From: Warexpor Date: Fri, 21 Aug 2026 23:03:26 +0300 Subject: [PATCH 2/4] Rebuild the connected shell as a path-first Operate UI. Derive one pathAggregate in App, scope tokens to html[data-app], and put disconnect in the header so connected mode can leave the server. Vite sim supports ?connected=1. --- client/frontend/dist/assets/index-5j6ZJn19.js | 2 - .../frontend/dist/assets/index-Ciw-gyve.css | 1 + .../frontend/dist/assets/index-coA7a2P7.css | 1 - client/frontend/dist/assets/index-nNWLt_UA.js | 1 + client/frontend/dist/index.html | 4 +- client/frontend/src/App.svelte | 31 ++- client/frontend/src/app.css | 1 + client/frontend/src/connected.css | 158 ++++++++++++++ .../src/lib/components/ChatView.svelte | 16 +- .../src/lib/components/ConnectedHeader.svelte | 150 +++++++++++++ .../src/lib/components/PeerList.svelte | 92 ++++---- .../src/lib/components/SettingsView.svelte | 32 +-- .../src/lib/components/Sidebar.svelte | 51 +++-- .../src/lib/components/StatusBar.svelte | 50 +---- client/frontend/src/lib/locales/en.js | 4 + client/frontend/src/lib/locales/ru.js | 4 + client/frontend/src/lib/locales/zh.js | 4 + client/frontend/src/lib/path.js | 21 ++ client/frontend/src/lib/sim.js | 201 ++++++++++++++++++ client/frontend/src/main.js | 1 + 20 files changed, 690 insertions(+), 135 deletions(-) delete mode 100644 client/frontend/dist/assets/index-5j6ZJn19.js create mode 100644 client/frontend/dist/assets/index-Ciw-gyve.css delete mode 100644 client/frontend/dist/assets/index-coA7a2P7.css create mode 100644 client/frontend/dist/assets/index-nNWLt_UA.js create mode 100644 client/frontend/src/connected.css create mode 100644 client/frontend/src/lib/components/ConnectedHeader.svelte create mode 100644 client/frontend/src/lib/path.js create mode 100644 client/frontend/src/lib/sim.js diff --git a/client/frontend/dist/assets/index-5j6ZJn19.js b/client/frontend/dist/assets/index-5j6ZJn19.js deleted file mode 100644 index dae65e4..0000000 --- a/client/frontend/dist/assets/index-5j6ZJn19.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))i(o);new MutationObserver(o=>{for(const a of o)if(a.type==="childList")for(const r of a.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&i(r)}).observe(document,{childList:!0,subtree:!0});function n(o){const a={};return o.integrity&&(a.integrity=o.integrity),o.referrerPolicy&&(a.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?a.credentials="include":o.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function i(o){if(o.ep)return;o.ep=!0;const a=n(o);fetch(o.href,a)}})();function de(){}function Ti(t){return t()}function Gs(){return Object.create(null)}function Le(t){t.forEach(Ti)}function Gl(t){return typeof t=="function"}function dt(t,e){return t!=t?e==e:t!==e||t&&typeof t=="object"||typeof t=="function"}function Wi(t){return Object.keys(t).length===0}function Vl(t,...e){if(t==null){for(const i of e)i(void 0);return de}const n=t.subscribe(...e);return n.unsubscribe?()=>n.unsubscribe():n}function on(t){let e;return Vl(t,n=>e=n)(),e}function ve(t,e,n){t.$$.on_destroy.push(Vl(e,n))}function Ze(t,e,n){return t.set(n),e}function l(t,e){t.appendChild(e)}function K(t,e,n){t.insertBefore(e,n||null)}function F(t){t.parentNode&&t.parentNode.removeChild(t)}function c(t){return document.createElement(t)}function g(t){return document.createTextNode(t)}function h(){return g(" ")}function Ul(){return g("")}function W(t,e,n,i){return t.addEventListener(e,n,i),()=>t.removeEventListener(e,n,i)}function Gt(t){return function(e){return e.stopPropagation(),t.call(this,e)}}function s(t,e,n){n==null?t.removeAttribute(e):t.getAttribute(e)!==n&&t.setAttribute(e,n)}function Fi(t){let e;return{p(...n){e=n,e.forEach(i=>t.push(i))},r(){e.forEach(n=>t.splice(t.indexOf(n),1))}}}function Oi(t){return t===""?null:+t}function Ki(t){return Array.from(t.childNodes)}function b(t,e){e=""+e,t.data!==e&&(t.data=e)}function ie(t,e){t.value=e??""}function Vs(t,e,n,i){n==null?t.style.removeProperty(e):t.style.setProperty(e,n,"")}function xn(t,e,n){for(let i=0;ii.call(this,e))}const Kt=[],Vt=[];let Jt=[];const Bs=[],Vi=Promise.resolve();let zl=!1;function Bi(){zl||(zl=!0,Vi.then(qi))}function tl(t){Jt.push(t)}const ql=new Set;let Wt=0;function qi(){if(Wt!==0)return;const t=rn;do{try{for(;Wtt.indexOf(i)===-1?e.push(i):n.push(i)),n.forEach(i=>i()),Jt=e}const el=new Set;let vt;function Ui(){vt={r:0,c:[],p:vt}}function zi(){vt.r||Le(vt.c),vt=vt.p}function Ye(t,e){t&&t.i&&(el.delete(t),t.i(e))}function lt(t,e,n,i){if(t&&t.o){if(el.has(t))return;el.add(t),vt.c.push(()=>{el.delete(t),i&&(n&&t.d(1),i())}),t.o(e)}else i&&i()}function ft(t){return t?.length!==void 0?t:Array.from(t)}function ll(t,e){t.d(1),e.delete(t.key)}function sl(t,e,n,i,o,a,r,_,d,u,v,f){let m=t.length,j=a.length,w=m;const A={};for(;w--;)A[t[w].key]=w;const p=[],C=new Map,D=new Map,P=[];for(w=j;w--;){const I=f(o,a,w),J=n(I);let B=r.get(J);B?P.push(()=>B.p(I,e)):(B=u(J,I),B.c()),C.set(J,p[w]=B),J in A&&D.set(J,Math.abs(w-A[J]))}const k=new Set,N=new Set;function y(I){Ye(I,1),I.m(_,v),r.set(I.key,I),v=I.first,j--}for(;m&&j;){const I=p[j-1],J=t[m-1],B=I.key,S=J.key;I===J?(v=I.first,m--,j--):C.has(S)?!r.has(B)||k.has(B)?y(I):N.has(S)?m--:D.get(B)>D.get(S)?(N.add(B),y(I)):(k.add(S),m--):(d(J,r),m--)}for(;m--;){const I=t[m];C.has(I.key)||d(I,r)}for(;j;)y(p[j-1]);return Le(P),p}function Bt(t){t&&t.c()}function mt(t,e,n){const{fragment:i,after_update:o}=t.$$;i&&i.m(e,n),tl(()=>{const a=t.$$.on_mount.map(Ti).filter(Gl);t.$$.on_destroy?t.$$.on_destroy.push(...a):Le(a),t.$$.on_mount=[]}),o.forEach(tl)}function ht(t,e){const n=t.$$;n.fragment!==null&&(Hi(n.after_update),Le(n.on_destroy),n.fragment&&n.fragment.d(e),n.on_destroy=n.fragment=null,n.ctx=[])}function Xi(t,e){t.$$.dirty[0]===-1&&(Kt.push(t),Bi(),t.$$.dirty.fill(0)),t.$$.dirty[e/31|0]|=1<{const w=j.length?j[0]:m;return u.ctx&&o(u.ctx[f],u.ctx[f]=w)&&(!u.skip_bound&&u.bound[f]&&u.bound[f](w),v&&Xi(t,f)),m}):[],u.update(),v=!0,Le(u.before_update),u.fragment=i?i(u.ctx):!1,e.target){if(e.hydrate){const f=Ki(e.target);u.fragment&&u.fragment.l(f),f.forEach(F)}else u.fragment&&u.fragment.c();e.intro&&Ye(t.$$.fragment),mt(t,e.target,e.anchor),qi()}an(d)}class wt{$$=void 0;$$set=void 0;$destroy(){ht(this,1),this.$destroy=de}$on(e,n){if(!Gl(n))return de;const i=this.$$.callbacks[e]||(this.$$.callbacks[e]=[]);return i.push(n),()=>{const o=i.indexOf(n);o!==-1&&i.splice(o,1)}}$set(e){this.$$set&&!Wi(e)&&(this.$$.skip_bound=!0,this.$$set(e),this.$$.skip_bound=!1)}}const Qi="4";typeof window<"u"&&(window.__svelte||(window.__svelte={v:new Set})).v.add(Qi);const Ft=[];function Zi(t,e){return{subscribe:$e(t,e).subscribe}}function $e(t,e=de){let n;const i=new Set;function o(_){if(dt(t,_)&&(t=_,n)){const d=!Ft.length;for(const u of i)u[1](),Ft.push(u,t);if(d){for(let u=0;u{i.delete(u),i.size===0&&n&&(n(),n=null)}}return{set:o,update:a,subscribe:r}}function $i(t,e,n){const i=!Array.isArray(t),o=i?[t]:t;if(!o.every(Boolean))throw new Error("derived() expects stores as input, got a falsy value");const a=e.length<2;return Zi(n,(r,_)=>{let d=!1;const u=[];let v=0,f=de;const m=()=>{if(v)return;f();const w=e(i?u[0]:u,r,_);a?r(w):f=Gl(w)?w:de},j=o.map((w,A)=>Vl(w,p=>{u[A]=p,v&=~(1<{v|=1<[...i,{id:n,msg:t,type:e}]),setTimeout(()=>{Wl.update(i=>i.filter(o=>o.id!==n))},4e3),e==="error"&&no(t)}function no(t){if(!t){nl.set(null);return}nl.set({id:++to,msg:String(t)})}function un(){nl.set(null)}function Fl(t,e){return t&&t.id?"peer:"+t.id:"room:"+(e||"network")}function _n(){return Fl(on(cn),on(ze).room)}function Ql(t,e,n,i=!1,o="sent",a=!1,r=!1){const _=++eo;let d;a?d=Fl(null,on(ze).room):i?d=_n():r?d="peer:"+t:d=Fl(null,on(ze).room),Hl.update(f=>{const m=f[d]?[...f[d]]:[];return m.push({id:i&&t.startsWith("local_")?t:_,fromID:t,nickname:e,message:n,timestamp:Date.now(),isSelf:i,status:o,system:a}),{...f,[d]:m.length>Ys?m.slice(-Ys):m}});const u=on(Ce),v=_n();!i&&!(u==="chat"&&d===v)&&Xl.update(f=>({...f,[d]:(f[d]||0)+1}))}function lo(t){Ql("system","",t,!1,"sent",!0)}function Kl(t){Xl.update(e=>{const n={...e};return delete n[t],n})}function ln(t,e){const n=_n();Hl.update(i=>{const o=i[n];return o?{...i,[n]:o.map(a=>a.id===t?{...a,status:e}:a)}:i})}const so={subscribe(t){return Hl.subscribe(e=>{t(e[_n()]||[])})}},Jl={brand:"Entangled",tagline:"Private LAN for friends — anywhere.",networks:"Networks",network_count:"{n} network(s)",create_network:"Create Network",join_network:"Join Network",connecting:"Connecting...",peer_count:"{n} peer(s)",offline_click:"Offline — click to connect",saved:"Saved",no_networks:"No saved networks",no_networks_desc:"Create or join a network to get started",settings:"Settings",network_name:"Network name",password_opt:"Password (optional)",cancel:"Cancel",create:"Create",join:"Join",leave:"Leave network",remove:"Remove saved",delete_room:"Delete network",more_actions:"More actions",copy_invite:"Copy invite",paste_invite:"Have an invite?",invite_copied:"Invite copied",invite_placeholder:"server|room|password",server_addr:"Server Address",nickname:"Nickname",server_token:"Server token",server_token_desc:"optional shared secret (ENTANGLED_TOKEN)",connect:"Connect",disconnect:"Disconnect",connected:"Connected",server:"Server",virtual_ip:"Virtual IP",na:"N/A",reconnecting:"Reconnecting...",disconnected:"Disconnected",phase_dialing:"Dialing server…",phase_auth:"Authenticating…",phase_ready:"Ready",phase_error:"Error",room_chat:"Room Chat",chat:"Chat",col_nickname:"Nickname",col_ip:"Virtual IP",col_ping:"Ping",ping_peer:"Ping",ping_sent:"Pinging {name}…",error_ping:"Ping failed: {err}",col_path:"Path",col_status:"Status",status_online:"Online",status_offline:"Offline",path_p2p:"Direct",path_relay:"Relay",path_ws:"Fallback",path_unknown:"—",path_p2p_tip:"Peer-to-peer direct connection",path_relay_tip:"Traffic routed through the server relay",path_ws_tip:"WebSocket fallback path",you:"You",me:"me",no_peers:"No peers connected",no_peers_desc:"Create or join a network, then wait for friends",network:"Network",chat_with:"Chat with {name}",room_chat_title:"Room Chat — {room}",back:"Back",no_messages:"No messages yet",no_messages_desc:"Send a message to start the conversation",type_message:"Type a message...",send:"Send",send_disabled_no_room:"Join a network to chat",msg_truncated:"Message truncated to 1000 characters",retry:"Retry",today:"Today",yesterday:"Yesterday",you_self:"You",status_connected:"Connected",status_disconnected:"Disconnected",status_reconnecting:"Reconnecting…",status_relay_degraded:"Some peers on relay",status_server:"Server: {s}",status_ip:"IP: {ip}",status_network:"Network: {room}",status_peers:"Peers: {n}",version:"Entangled v{v}",settings_title:"Settings",section_connection:"CONNECTION",section_network:"ADVANCED NETWORK",section_system:"SYSTEM",section_appearance:"APPEARANCE",advanced_warn:"Only change these if you know what they do.",reconnect_apply:"Reconnect to apply",auto_connect:"Auto Connect",auto_connect_desc:"connect to last server on startup",auto_join:"Auto Join Last Room",auto_join_desc:"join last open room after connect (password rooms need a manual join after restart)",connection_mode:"Connection",connection_direct:"Direct (P2P)",connection_relay:"Relay (server)",connection_mode_desc:"Direct prefers peer-to-peer and uses relay only when needed. Relay forces all traffic through the server.",mtu:"MTU",mtu_desc:"Packet size. Wrong values can break games or cause lag.",dns_server:"DNS Server",dns_desc:"Optional DNS for the virtual network. Leave blank for system default.",socks5:"SOCKS5 Proxy",socks5_placeholder:"e.g. 127.0.0.1:10808",socks5_desc:"Proxies signaling (WebSocket) only — not peer/relay UDP. Reconnect to apply.",stun_server:"STUN Server",stun_desc:"Helps find your public address for direct links. Reconnect to apply.",start_windows:"Start with Windows",updates:"Updates",check_updates:"Check for updates",apply_update:"Update",update_checking:"Checking for updates…",update_latest:"You are up to date.",update_available:"Update available: v{v}",update_downloading:"Downloading update… the app will restart.",update_failed:"Update failed",confirm_update:"Download and install the update? The app will restart.",error_update_check:"Update check failed: ",error_update:"Update failed: ",notif_updating:"Installing update…",ui_scale:"UI Scale",ui_scale_desc:"Scales the whole interface. Use with window resize or F11 fullscreen.",theme:"Theme",theme_dark:"Dark",theme_light:"Light",language:"Language",save:"SAVE",reset:"RESET TO DEFAULTS",language_en:"English",language_ru:"Russian",language_zh:"Chinese",copied:"Copied",dismiss_error:"Dismiss",field_required:"Required",notif_created:"Network created: {name}",notif_joined:"Joined network: {name}",notif_left:"Left network",notif_removed:"Removed: {name}",notif_deleted:"Network deleted: {name}",notif_connected:"Connected to {addr}",notif_disconnected:"Disconnected",notif_settings_saved:"Settings saved",notif_reconnect_required:"Reconnect to apply proxy / STUN / token changes",notif_auto_join_skipped:'Auto-join skipped for "{name}" — enter the password to join',notif_need_config:"Set server & nickname in Connect page first",notif_room_deleted:"Network was deleted by owner",invite_no_password:"Invite copied without password (not stored). Add it before sharing.",error_create:"Failed to create network: {err}",error_join:"Failed to join: {err}",error_leave:"Failed to leave: {err}",error_remove:"Failed to remove: {err}",error_connect:"Connection failed: {err}",error_disconnect:"Error: {err}",error_send:"Failed to send: {err}",error_not_connected:"Not connected — cannot send message",error_invalid_invite:"Invalid invite: server and room are required",error_save:"Failed to save settings: {err}",confirm_disconnect:"Disconnect from server?",confirm_leave:"Leave the current network? It stays in your saved list.",confirm_leave_remove:"Leave and remove this network from your saved list?",confirm_remove:'Remove "{name}" from saved networks? (does not delete the network for others)',confirm_delete:'Permanently delete network "{name}" for everyone?',confirm_reset:"Reset all settings to defaults?"},io={brand:"Entangled",tagline:"Частная LAN для друзей — где угодно.",networks:"Сети",network_count:"{n} сет(ь/и/ей)",create_network:"Создать сеть",join_network:"Подключиться",connecting:"Подключение...",peer_count:"{n} участник(ов)",offline_click:"Не в сети — нажмите для подключения",saved:"Сохранено",no_networks:"Нет сохранённых сетей",no_networks_desc:"Создайте или войдите в сеть, чтобы начать",settings:"Настройки",network_name:"Название сети",password_opt:"Пароль (опционально)",cancel:"Отмена",create:"Создать",join:"Войти",leave:"Покинуть сеть",remove:"Убрать из списка",delete_room:"Удалить сеть",more_actions:"Ещё действия",copy_invite:"Копировать инвайт",paste_invite:"Есть инвайт?",invite_copied:"Инвайт скопирован",invite_placeholder:"сервер|комната|пароль",server_addr:"Адрес сервера",nickname:"Псевдоним",server_token:"Токен сервера",server_token_desc:"опциональный секрет (ENTANGLED_TOKEN)",connect:"Подключиться",disconnect:"Отключиться",connected:"Подключено",server:"Сервер",virtual_ip:"Виртуальный IP",na:"Н/Д",reconnecting:"Переподключение...",disconnected:"Отключено",phase_dialing:"Подключение к серверу…",phase_auth:"Аутентификация…",phase_ready:"Готово",phase_error:"Ошибка",room_chat:"Чат комнаты",chat:"Чат",col_nickname:"Псевдоним",col_ip:"Виртуальный IP",col_ping:"Пинг",ping_peer:"Пинг",ping_sent:"Пинг {name}…",error_ping:"Пинг не удался: {err}",col_path:"Путь",col_status:"Статус",status_online:"В сети",status_offline:"Не в сети",path_p2p:"Прямой",path_relay:"Релей",path_ws:"Запасной",path_unknown:"—",path_p2p_tip:"Прямое соединение peer-to-peer",path_relay_tip:"Трафик через серверный релей",path_ws_tip:"Запасной путь через WebSocket",you:"Вы",me:"я",no_peers:"Нет подключённых участников",no_peers_desc:"Создайте или войдите в сеть и дождитесь друзей",network:"Сеть",chat_with:"Чат с {name}",room_chat_title:"Чат комнаты — {room}",back:"Назад",no_messages:"Сообщений пока нет",no_messages_desc:"Отправьте сообщение, чтобы начать разговор",type_message:"Введите сообщение...",send:"Отправить",send_disabled_no_room:"Войдите в сеть, чтобы писать",msg_truncated:"Сообщение обрезано до 1000 символов",retry:"Повторить",today:"Сегодня",yesterday:"Вчера",you_self:"Вы",status_connected:"Подключено",status_disconnected:"Отключено",status_reconnecting:"Переподключение…",status_relay_degraded:"Часть пиров через релей",status_server:"Сервер: {s}",status_ip:"IP: {ip}",status_network:"Сеть: {room}",status_peers:"Участники: {n}",version:"Entangled v{v}",settings_title:"Настройки",section_connection:"ПОДКЛЮЧЕНИЕ",section_network:"ДОП. СЕТЬ",section_system:"СИСТЕМА",section_appearance:"ВНЕШНИЙ ВИД",advanced_warn:"Меняйте только если понимаете, что делаете.",reconnect_apply:"Переподключитесь, чтобы применить",auto_connect:"Автоподключение",auto_connect_desc:"подключаться к последнему серверу при запуске",auto_join:"Автовход в комнату",auto_join_desc:"входить в последнюю открытую комнату (с паролем — вручную после перезапуска)",connection_mode:"Соединение",connection_direct:"Прямое (P2P)",connection_relay:"Релей (сервер)",connection_mode_desc:"Прямое предпочитает P2P и использует релей только при необходимости. Релей гонит весь трафик через сервер.",mtu:"MTU",mtu_desc:"Размер пакета. Неверное значение ломает игры или даёт лаги.",dns_server:"DNS-сервер",dns_desc:"Опциональный DNS виртуальной сети. Пусто — системный по умолчанию.",socks5:"SOCKS5-прокси",socks5_placeholder:"напр. 127.0.0.1:10808",socks5_desc:"Только сигнальный WebSocket, не UDP пиров/релея. Переподключитесь, чтобы применить.",stun_server:"STUN-сервер",stun_desc:"Помогает найти публичный адрес. Переподключитесь, чтобы применить.",start_windows:"Запуск с Windows",updates:"Обновления",check_updates:"Проверить обновления",apply_update:"Обновить",update_checking:"Проверка обновлений…",update_latest:"У вас актуальная версия.",update_available:"Доступно обновление: v{v}",update_downloading:"Загрузка обновления… приложение перезапустится.",update_failed:"Ошибка обновления",confirm_update:"Скачать и установить обновление? Приложение перезапустится.",error_update_check:"Не удалось проверить обновления: ",error_update:"Не удалось обновить: ",notif_updating:"Установка обновления…",ui_scale:"Масштаб UI",ui_scale_desc:"Масштабирует весь интерфейс. Вместе с изменением размера окна или F11.",theme:"Тема",theme_dark:"Тёмная",theme_light:"Светлая",language:"Язык",save:"СОХРАНИТЬ",reset:"СБРОСИТЬ",language_en:"Английский",language_ru:"Русский",language_zh:"Китайский",copied:"Скопировано",dismiss_error:"Закрыть",field_required:"Обязательно",notif_created:"Сеть создана: {name}",notif_joined:"Подключились к сети: {name}",notif_left:"Покинули сеть",notif_removed:"Удалено: {name}",notif_deleted:"Сеть удалена: {name}",notif_connected:"Подключились к {addr}",notif_disconnected:"Отключились",notif_settings_saved:"Настройки сохранены",notif_reconnect_required:"Переподключитесь, чтобы применить прокси / STUN / токен",notif_auto_join_skipped:"Автовход пропущен для «{name}» — введите пароль вручную",notif_need_config:"Укажите сервер и псевдоним на странице подключения",notif_room_deleted:"Сеть удалена владельцем",invite_no_password:"Инвайт скопирован без пароля (он не хранится). Добавьте перед отправкой.",error_create:"Не удалось создать сеть: {err}",error_join:"Не удалось подключиться: {err}",error_leave:"Не удалось покинуть: {err}",error_remove:"Не удалось удалить: {err}",error_connect:"Ошибка подключения: {err}",error_disconnect:"Ошибка: {err}",error_send:"Не удалось отправить: {err}",error_not_connected:"Нет подключения — невозможно отправить сообщение",error_invalid_invite:"Неверный инвайт: нужны сервер и комната",error_save:"Не удалось сохранить настройки: {err}",confirm_disconnect:"Отключиться от сервера?",confirm_leave:"Покинуть текущую сеть? Она останется в сохранённых.",confirm_leave_remove:"Покинуть и убрать сеть из сохранённых?",confirm_remove:'Убрать "{name}" из сохранённых? (сеть для других не удалится)',confirm_delete:'Навсегда удалить сеть "{name}" для всех?',confirm_reset:"Сбросить все настройки?"},oo={brand:"Entangled",tagline:"朋友的私人局域网 — 随时随地。",networks:"网络",network_count:"{n} 个网络",create_network:"创建网络",join_network:"加入网络",connecting:"连接中...",peer_count:"{n} 个节点",offline_click:"离线 — 点击连接",saved:"已保存",no_networks:"暂无保存的网络",no_networks_desc:"创建或加入网络以开始",settings:"设置",network_name:"网络名称",password_opt:"密码(可选)",cancel:"取消",create:"创建",join:"加入",leave:"离开网络",remove:"移除已保存",delete_room:"删除网络",more_actions:"更多操作",copy_invite:"复制邀请",paste_invite:"有邀请码?",invite_copied:"邀请已复制",invite_placeholder:"服务器|房间|密码",server_addr:"服务器地址",nickname:"昵称",server_token:"服务器令牌",server_token_desc:"可选共享密钥(ENTANGLED_TOKEN)",connect:"连接",disconnect:"断开",connected:"已连接",server:"服务器",virtual_ip:"虚拟 IP",na:"无",reconnecting:"重新连接...",disconnected:"已断开",phase_dialing:"正在连接服务器…",phase_auth:"正在验证…",phase_ready:"就绪",phase_error:"错误",room_chat:"房间聊天",chat:"聊天",col_nickname:"昵称",col_ip:"虚拟 IP",col_ping:"延迟",ping_peer:"测速",ping_sent:"正在测速 {name}…",error_ping:"测速失败: {err}",col_path:"路径",col_status:"状态",status_online:"在线",status_offline:"离线",path_p2p:"直连",path_relay:"中继",path_ws:"备用",path_unknown:"—",path_p2p_tip:"点对点直连",path_relay_tip:"经服务器中继转发",path_ws_tip:"WebSocket 备用路径",you:"你",me:"我",no_peers:"暂无连接的节点",no_peers_desc:"创建或加入网络,然后等待好友",network:"网络",chat_with:"与 {name} 聊天",room_chat_title:"房间聊天 — {room}",back:"返回",no_messages:"暂无消息",no_messages_desc:"发送一条消息开始对话",type_message:"输入消息...",send:"发送",send_disabled_no_room:"加入网络后才能聊天",msg_truncated:"消息已截断至 1000 个字符",retry:"重试",today:"今天",yesterday:"昨天",you_self:"你",status_connected:"已连接",status_disconnected:"已断开",status_reconnecting:"重新连接…",status_relay_degraded:"部分节点经中继",status_server:"服务器: {s}",status_ip:"IP: {ip}",status_network:"网络: {room}",status_peers:"节点: {n}",version:"Entangled v{v}",settings_title:"设置",section_connection:"连接",section_network:"高级网络",section_system:"系统",section_appearance:"外观",advanced_warn:"仅在了解作用时更改这些选项。",reconnect_apply:"重新连接以生效",auto_connect:"自动连接",auto_connect_desc:"启动时自动连接到上次的服务器",auto_join:"自动加入房间",auto_join_desc:"连接后自动加入上次的开放房间(有密码的房间重启后需手动加入)",connection_mode:"连接方式",connection_direct:"直连 (P2P)",connection_relay:"中继 (服务器)",connection_mode_desc:"直连优先点对点,必要时才用中继。中继模式强制全部流量经服务器。",mtu:"MTU",mtu_desc:"数据包大小。错误值可能导致游戏异常或卡顿。",dns_server:"DNS 服务器",dns_desc:"虚拟网络可选 DNS。留空则使用系统默认。",socks5:"SOCKS5 代理",socks5_placeholder:"例如 127.0.0.1:10808",socks5_desc:"仅代理信令 WebSocket,不含节点/中继 UDP。重新连接以生效。",stun_server:"STUN 服务器",stun_desc:"用于发现公网地址以便直连。重新连接以生效。",start_windows:"开机自启",updates:"更新",check_updates:"检查更新",apply_update:"更新",update_checking:"正在检查更新…",update_latest:"已是最新版本。",update_available:"有可用更新:v{v}",update_downloading:"正在下载更新…应用将重启。",update_failed:"更新失败",confirm_update:"下载并安装更新?应用将重启。",error_update_check:"检查更新失败:",error_update:"更新失败:",notif_updating:"正在安装更新…",ui_scale:"界面缩放",ui_scale_desc:"缩放整个界面。可配合窗口调整大小或 F11 全屏使用。",theme:"主题",theme_dark:"深色",theme_light:"浅色",language:"语言",save:"保存",reset:"重置为默认",language_en:"英语",language_ru:"俄语",language_zh:"中文",copied:"已复制",dismiss_error:"关闭",field_required:"必填",notif_created:"网络已创建: {name}",notif_joined:"已加入网络: {name}",notif_left:"已离开网络",notif_removed:"已删除: {name}",notif_deleted:"网络已删除: {name}",notif_connected:"已连接到 {addr}",notif_disconnected:"已断开连接",notif_settings_saved:"设置已保存",notif_reconnect_required:"请重新连接以使代理 / STUN / 令牌生效",notif_auto_join_skipped:"已跳过自动加入「{name}」— 请输入密码后手动加入",notif_need_config:"请先在连接页面设置服务器和昵称",notif_room_deleted:"网络已被所有者删除",invite_no_password:"邀请已复制但无密码(密码不存储)。分享前请自行添加。",error_create:"创建网络失败: {err}",error_join:"加入失败: {err}",error_leave:"离开失败: {err}",error_remove:"删除失败: {err}",error_connect:"连接失败: {err}",error_disconnect:"错误: {err}",error_send:"发送失败: {err}",error_not_connected:"未连接 — 无法发送消息",error_invalid_invite:"无效邀请:需要服务器和房间名",error_save:"保存设置失败: {err}",confirm_disconnect:"确定断开服务器连接?",confirm_leave:"离开当前网络?仍保留在已保存列表中。",confirm_leave_remove:"离开并从已保存列表中移除?",confirm_remove:'从已保存网络中移除 "{name}"?(不会删除他人的网络)',confirm_delete:'永久删除网络 "{name}"(对所有人)?',confirm_reset:"确定重置所有设置?"},Zl={en:Jl,ru:io,zh:oo};function ao(){const t=localStorage.getItem("entangled_locale");if(t&&Zl[t])return t;const e=navigator.language?.slice(0,2);return e==="ru"?"ru":e==="zh"?"zh":"en"}const $l=$e(ao()),kt=$i($l,t=>{const e=Zl[t]||Jl;return new Proxy(e,{get(n,i){if(typeof i=="string")return n[i]??Jl[i]??i}})});function sn(t){Zl[t]&&(localStorage.setItem("entangled_locale",t),$l.set(t))}function ne(t,e){return t?String(t).replace(/\{(\w+)\}/g,(n,i)=>e&&e[i]!=null?e[i]:`{${i}}`):""}function Hs(t,e,n){const i=t.slice();return i[62]=e[n],i}function Xs(t){let e,n,i=t[16].no_networks+"",o,a,r,_=t[16].no_networks_desc+"",d,u;return{c(){e=c("div"),n=c("div"),o=g(i),a=h(),r=c("div"),d=g(_),u=h(),s(r,"class","empty-desc svelte-1oaanap"),s(e,"class","empty-state svelte-1oaanap")},m(v,f){K(v,e,f),l(e,n),l(n,o),l(e,a),l(e,r),l(r,d),l(e,u)},p(v,f){f[0]&65536&&i!==(i=v[16].no_networks+"")&&b(o,i),f[0]&65536&&_!==(_=v[16].no_networks_desc+"")&&b(d,_)},d(v){v&&F(e)}}}function ro(t){let e=t[16].saved+"",n;return{c(){n=g(e)},m(i,o){K(i,n,o)},p(i,o){o[0]&65536&&e!==(e=i[16].saved+"")&&b(n,e)},d(i){i&&F(n)}}}function co(t){let e=t[16].offline_click+"",n;return{c(){n=g(e)},m(i,o){K(i,n,o)},p(i,o){o[0]&65536&&e!==(e=i[16].offline_click+"")&&b(n,e)},d(i){i&&F(n)}}}function uo(t){let e=ne(t[16].peer_count,{n:t[18].peerCount})+"",n;return{c(){n=g(e)},m(i,o){K(i,n,o)},p(i,o){o[0]&327680&&e!==(e=ne(i[16].peer_count,{n:i[18].peerCount})+"")&&b(n,e)},d(i){i&&F(n)}}}function _o(t){let e=t[16].connecting+"",n;return{c(){n=g(e)},m(i,o){K(i,n,o)},p(i,o){o[0]&65536&&e!==(e=i[16].connecting+"")&&b(n,e)},d(i){i&&F(n)}}}function Qs(t){let e,n,i=t[16].copy_invite+"",o,a,r,_,d=t[16].remove+"",u,v,f,m;function j(...C){return t[40](t[62],...C)}let w=t[18].room===t[62].name&&Zs(t);function A(...C){return t[42](t[62],...C)}let p=t[18].room===t[62].name&&t[18].isOwner&&$s(t);return{c(){e=c("div"),n=c("button"),o=g(i),a=h(),w&&w.c(),r=h(),_=c("button"),u=g(d),v=h(),p&&p.c(),s(n,"type","button"),s(n,"role","menuitem"),s(n,"class","menu-item svelte-1oaanap"),s(_,"type","button"),s(_,"role","menuitem"),s(_,"class","menu-item danger svelte-1oaanap"),s(e,"class","overflow-menu svelte-1oaanap"),s(e,"role","menu"),s(e,"tabindex","-1")},m(C,D){K(C,e,D),l(e,n),l(n,o),l(e,a),w&&w.m(e,null),l(e,r),l(e,_),l(_,u),l(e,v),p&&p.m(e,null),f||(m=[W(n,"click",j),W(_,"click",A),W(e,"click",Gt(t[37])),W(e,"keydown",Gt(t[38]))],f=!0)},p(C,D){t=C,D[0]&65536&&i!==(i=t[16].copy_invite+"")&&b(o,i),t[18].room===t[62].name?w?w.p(t,D):(w=Zs(t),w.c(),w.m(e,r)):w&&(w.d(1),w=null),D[0]&65536&&d!==(d=t[16].remove+"")&&b(u,d),t[18].room===t[62].name&&t[18].isOwner?p?p.p(t,D):(p=$s(t),p.c(),p.m(e,null)):p&&(p.d(1),p=null)},d(C){C&&F(e),w&&w.d(),p&&p.d(),f=!1,Le(m)}}}function Zs(t){let e,n=t[16].leave+"",i,o,a;return{c(){e=c("button"),i=g(n),s(e,"type","button"),s(e,"role","menuitem"),s(e,"class","menu-item svelte-1oaanap")},m(r,_){K(r,e,_),l(e,i),o||(a=W(e,"click",t[41]),o=!0)},p(r,_){_[0]&65536&&n!==(n=r[16].leave+"")&&b(i,n)},d(r){r&&F(e),o=!1,a()}}}function $s(t){let e,n=t[16].delete_room+"",i,o,a;function r(..._){return t[43](t[62],..._)}return{c(){e=c("button"),i=g(n),s(e,"type","button"),s(e,"role","menuitem"),s(e,"class","menu-item danger svelte-1oaanap")},m(_,d){K(_,e,d),l(e,i),o||(a=W(e,"click",r),o=!0)},p(_,d){t=_,d[0]&65536&&n!==(n=t[16].delete_room+"")&&b(i,n)},d(_){_&&F(e),o=!1,a()}}}function xs(t,e){let n,i,o,a,r,_=e[62].name+"",d,u,v,f,m,j,w,A,p,C,D,P,k,N,y,I;function J(V,Q){return V[11]===V[62].name?_o:V[18].room===V[62].name?uo:V[18].connected?ro:co}let B=J(e),S=B(e);function E(...V){return e[39](e[62],...V)}let M=e[13]===e[62].name&&Qs(e);function L(){return e[44](e[62])}function q(...V){return e[45](e[62],...V)}return{key:t,first:null,c(){n=c("div"),i=c("div"),o=h(),a=c("div"),r=c("div"),d=g(_),u=h(),v=c("div"),S.c(),f=h(),m=c("div"),j=c("button"),w=g("⋯"),D=h(),M&&M.c(),P=h(),s(i,"class","network-indicator svelte-1oaanap"),s(i,"aria-hidden","true"),ke(i,"active-dot",e[18].room===e[62].name),s(r,"class","network-name svelte-1oaanap"),s(v,"class","network-meta svelte-1oaanap"),s(a,"class","network-info svelte-1oaanap"),s(j,"type","button"),s(j,"class","menu-btn svelte-1oaanap"),s(j,"aria-haspopup","menu"),s(j,"aria-expanded",A=e[13]===e[62].name),s(j,"aria-label",p=e[16].more_actions),s(j,"title",C=e[16].more_actions),s(m,"class","row-actions svelte-1oaanap"),s(n,"class","network-item svelte-1oaanap"),s(n,"role","button"),s(n,"tabindex","0"),s(n,"aria-current",k=e[18].room===e[62].name?"true":void 0),s(n,"aria-label",N=e[62].name),ke(n,"active",e[18].room===e[62].name),ke(n,"disabled",!e[18].connected&&!e[11]),this.first=n},m(V,Q){K(V,n,Q),l(n,i),l(n,o),l(n,a),l(a,r),l(r,d),l(a,u),l(a,v),S.m(v,null),l(n,f),l(n,m),l(m,j),l(j,w),l(m,D),M&&M.m(m,null),l(n,P),y||(I=[W(j,"click",E),W(n,"click",L),W(n,"keydown",q)],y=!0)},p(V,Q){e=V,Q[0]&262145&&ke(i,"active-dot",e[18].room===e[62].name),Q[0]&1&&_!==(_=e[62].name+"")&&b(d,_),B===(B=J(e))&&S?S.p(e,Q):(S.d(1),S=B(e),S&&(S.c(),S.m(v,null))),Q[0]&8193&&A!==(A=e[13]===e[62].name)&&s(j,"aria-expanded",A),Q[0]&65536&&p!==(p=e[16].more_actions)&&s(j,"aria-label",p),Q[0]&65536&&C!==(C=e[16].more_actions)&&s(j,"title",C),e[13]===e[62].name?M?M.p(e,Q):(M=Qs(e),M.c(),M.m(m,null)):M&&(M.d(1),M=null),Q[0]&262145&&k!==(k=e[18].room===e[62].name?"true":void 0)&&s(n,"aria-current",k),Q[0]&1&&N!==(N=e[62].name)&&s(n,"aria-label",N),Q[0]&262145&&ke(n,"active",e[18].room===e[62].name),Q[0]&264192&&ke(n,"disabled",!e[18].connected&&!e[11])},d(V){V&&F(n),S.d(),M&&M.d(),y=!1,Le(I)}}}function ei(t){let e,n,i,o=t[16].create_network+"",a,r,_,d=t[16].network_name+"",u,v,f,m,j,w,A,p,C=t[16].password_opt+"",D,P,k,N,y,I,J,B,S=t[16].cancel+"",E,M,L,q=t[16].create+"",V,Q,ce,O=t[9]&&ti(t),Y=t[7]&&ni(t);return{c(){e=c("div"),n=c("div"),i=c("h3"),a=g(o),r=h(),_=c("label"),u=g(d),v=h(),f=c("input"),w=h(),O&&O.c(),A=h(),p=c("label"),D=g(C),P=h(),k=c("input"),y=h(),Y&&Y.c(),I=h(),J=c("div"),B=c("button"),E=g(S),M=h(),L=c("button"),V=g(q),s(i,"id","create-title"),s(i,"class","svelte-1oaanap"),s(_,"class","sr-only svelte-1oaanap"),s(_,"for","create-name"),s(f,"id","create-name"),s(f,"type","text"),s(f,"placeholder",m=t[16].network_name),s(f,"aria-invalid",j=!!t[9]),s(f,"class","svelte-1oaanap"),ke(f,"invalid",t[9]),s(p,"class","sr-only svelte-1oaanap"),s(p,"for","create-pass"),s(k,"id","create-pass"),s(k,"type","password"),s(k,"placeholder",N=t[16].password_opt),s(k,"class","svelte-1oaanap"),s(B,"class","btn svelte-1oaanap"),s(L,"class","btn primary svelte-1oaanap"),s(J,"class","modal-actions svelte-1oaanap"),s(n,"class","modal svelte-1oaanap"),s(n,"role","dialog"),s(n,"aria-modal","true"),s(n,"aria-labelledby","create-title"),s(e,"class","modal-overlay svelte-1oaanap"),s(e,"role","presentation")},m(U,z){K(U,e,z),l(e,n),l(n,i),l(i,a),l(n,r),l(n,_),l(_,u),l(n,v),l(n,f),ie(f,t[3]),l(n,w),O&&O.m(n,null),l(n,A),l(n,p),l(p,D),l(n,P),l(n,k),ie(k,t[4]),l(n,y),Y&&Y.m(n,null),l(n,I),l(n,J),l(J,B),l(B,E),l(J,M),l(J,L),l(L,V),t[49](n),Q||(ce=[W(f,"input",t[47]),W(k,"input",t[48]),W(B,"click",t[20]),W(L,"click",t[23]),W(n,"click",Gt(t[35])),W(n,"keydown",Gt(t[36])),W(e,"click",t[20]),W(e,"keydown",t[50])],Q=!0)},p(U,z){z[0]&65536&&o!==(o=U[16].create_network+"")&&b(a,o),z[0]&65536&&d!==(d=U[16].network_name+"")&&b(u,d),z[0]&65536&&m!==(m=U[16].network_name)&&s(f,"placeholder",m),z[0]&512&&j!==(j=!!U[9])&&s(f,"aria-invalid",j),z[0]&8&&f.value!==U[3]&&ie(f,U[3]),z[0]&512&&ke(f,"invalid",U[9]),U[9]?O?O.p(U,z):(O=ti(U),O.c(),O.m(n,A)):O&&(O.d(1),O=null),z[0]&65536&&C!==(C=U[16].password_opt+"")&&b(D,C),z[0]&65536&&N!==(N=U[16].password_opt)&&s(k,"placeholder",N),z[0]&16&&k.value!==U[4]&&ie(k,U[4]),U[7]?Y?Y.p(U,z):(Y=ni(U),Y.c(),Y.m(n,I)):Y&&(Y.d(1),Y=null),z[0]&65536&&S!==(S=U[16].cancel+"")&&b(E,S),z[0]&65536&&q!==(q=U[16].create+"")&&b(V,q)},d(U){U&&F(e),O&&O.d(),Y&&Y.d(),t[49](null),Q=!1,Le(ce)}}}function ti(t){let e,n;return{c(){e=c("span"),n=g(t[9]),s(e,"class","field-error svelte-1oaanap"),s(e,"role","alert")},m(i,o){K(i,e,o),l(e,n)},p(i,o){o[0]&512&&b(n,i[9])},d(i){i&&F(e)}}}function ni(t){let e,n;return{c(){e=c("div"),n=g(t[7]),s(e,"class","modal-error svelte-1oaanap"),s(e,"role","alert")},m(i,o){K(i,e,o),l(e,n)},p(i,o){o[0]&128&&b(n,i[7])},d(i){i&&F(e)}}}function li(t){let e,n,i,o=t[16].join_network+"",a,r,_,d=t[16].network_name+"",u,v,f,m,j,w,A,p,C=t[16].password_opt+"",D,P,k,N,y,I,J,B,S=t[16].cancel+"",E,M,L,q=t[16].join+"",V,Q,ce,O=t[10]&&si(t),Y=t[8]&&ii(t);return{c(){e=c("div"),n=c("div"),i=c("h3"),a=g(o),r=h(),_=c("label"),u=g(d),v=h(),f=c("input"),w=h(),O&&O.c(),A=h(),p=c("label"),D=g(C),P=h(),k=c("input"),y=h(),Y&&Y.c(),I=h(),J=c("div"),B=c("button"),E=g(S),M=h(),L=c("button"),V=g(q),s(i,"id","join-title"),s(i,"class","svelte-1oaanap"),s(_,"class","sr-only svelte-1oaanap"),s(_,"for","join-name"),s(f,"id","join-name"),s(f,"type","text"),s(f,"placeholder",m=t[16].network_name),s(f,"aria-invalid",j=!!t[10]),s(f,"class","svelte-1oaanap"),ke(f,"invalid",t[10]),s(p,"class","sr-only svelte-1oaanap"),s(p,"for","join-pass"),s(k,"id","join-pass"),s(k,"type","password"),s(k,"placeholder",N=t[16].password_opt),s(k,"class","svelte-1oaanap"),s(B,"class","btn svelte-1oaanap"),s(L,"class","btn primary svelte-1oaanap"),s(J,"class","modal-actions svelte-1oaanap"),s(n,"class","modal svelte-1oaanap"),s(n,"role","dialog"),s(n,"aria-modal","true"),s(n,"aria-labelledby","join-title"),s(e,"class","modal-overlay svelte-1oaanap"),s(e,"role","presentation")},m(U,z){K(U,e,z),l(e,n),l(n,i),l(i,a),l(n,r),l(n,_),l(_,u),l(n,v),l(n,f),ie(f,t[5]),l(n,w),O&&O.m(n,null),l(n,A),l(n,p),l(p,D),l(n,P),l(n,k),ie(k,t[6]),l(n,y),Y&&Y.m(n,null),l(n,I),l(n,J),l(J,B),l(B,E),l(J,M),l(J,L),l(L,V),t[54](n),Q||(ce=[W(f,"input",t[51]),W(k,"input",t[52]),W(B,"click",t[22]),W(L,"click",t[53]),W(n,"click",Gt(t[33])),W(n,"keydown",Gt(t[34])),W(e,"click",t[22]),W(e,"keydown",t[55])],Q=!0)},p(U,z){z[0]&65536&&o!==(o=U[16].join_network+"")&&b(a,o),z[0]&65536&&d!==(d=U[16].network_name+"")&&b(u,d),z[0]&65536&&m!==(m=U[16].network_name)&&s(f,"placeholder",m),z[0]&1024&&j!==(j=!!U[10])&&s(f,"aria-invalid",j),z[0]&32&&f.value!==U[5]&&ie(f,U[5]),z[0]&1024&&ke(f,"invalid",U[10]),U[10]?O?O.p(U,z):(O=si(U),O.c(),O.m(n,A)):O&&(O.d(1),O=null),z[0]&65536&&C!==(C=U[16].password_opt+"")&&b(D,C),z[0]&65536&&N!==(N=U[16].password_opt)&&s(k,"placeholder",N),z[0]&64&&k.value!==U[6]&&ie(k,U[6]),U[8]?Y?Y.p(U,z):(Y=ii(U),Y.c(),Y.m(n,I)):Y&&(Y.d(1),Y=null),z[0]&65536&&S!==(S=U[16].cancel+"")&&b(E,S),z[0]&65536&&q!==(q=U[16].join+"")&&b(V,q)},d(U){U&&F(e),O&&O.d(),Y&&Y.d(),t[54](null),Q=!1,Le(ce)}}}function si(t){let e,n;return{c(){e=c("span"),n=g(t[10]),s(e,"class","field-error svelte-1oaanap"),s(e,"role","alert")},m(i,o){K(i,e,o),l(e,n)},p(i,o){o[0]&1024&&b(n,i[10])},d(i){i&&F(e)}}}function ii(t){let e,n;return{c(){e=c("div"),n=g(t[8]),s(e,"class","modal-error svelte-1oaanap"),s(e,"role","alert")},m(i,o){K(i,e,o),l(e,n)},p(i,o){o[0]&256&&b(n,i[8])},d(i){i&&F(e)}}}function fo(t){let e,n,i,o=t[16].networks+"",a,r,_,d=ne(t[16].network_count,{n:t[0].length})+"",u,v,f,m,j=t[16].create_network+"",w,A,p,C,D=t[16].join_network+"",P,k,N,y,I=[],J=new Map,B,S,E,M=t[16].settings+"",L,q,V,Q,ce,O,Y=ft(t[0]);const U=Z=>Z[62].name;for(let Z=0;Zn(16,i=R)),ve(t,Ce,R=>n(17,o=R)),ve(t,ze,R=>n(18,a=R));let r=[],_=!1,d=!1,u="",v="",f="",m="",j="",w="",A="",p="",C="",D="",P="",k="network",N=null,y,I;fn(async()=>{n(0,r=await window.go.main.App.GetSavedRooms());const R=await window.go.main.App.LoadConfig();R.serverAddr&&(C=R.serverAddr),R.nickname&&(D=R.nickname),window.addEventListener("keydown",J),window.addEventListener("click",B)}),Mi(()=>{window.removeEventListener("keydown",J),window.removeEventListener("click",B)});function J(R){if(R.key==="Escape"){if(N){n(13,N=null);return}if(_){M();return}if(d){q();return}}}function B(){n(13,N=null)}async function S(){n(0,r=await window.go.main.App.GetSavedRooms())}function E(){n(7,j=""),n(9,A=""),n(1,_=!0),un()}function M(){n(1,_=!1),n(7,j=""),n(9,A="")}function L(){n(8,w=""),n(10,p=""),n(2,d=!0),un()}function q(){n(2,d=!1),n(8,w=""),n(10,p="")}async function V(){if(n(9,A=""),n(7,j=""),!u.trim()){n(9,A=i.field_required);return}try{await window.go.main.App.CreateRoom(u,v),ee(ne(i.notif_created,{name:u})),Ze(Ce,o="network",o),M(),n(3,u=""),n(4,v=""),await S()}catch(R){n(7,j=ne(i.error_create,{err:R})),ee(j,"error")}}async function Q(R,x){n(10,p=""),n(8,w="");const Se=R||f,Re=x!==void 0?x:m;if(!Se.trim()){n(10,p=i.field_required);return}try{await window.go.main.App.JoinRoom(Se,Re),ee(ne(i.notif_joined,{name:Se})),Ze(Ce,o="network",o),q(),n(5,f=""),n(6,m=""),await S()}catch(we){n(8,w=ne(i.error_join,{err:we})),ee(w,"error"),d||(n(5,f=Se),n(6,m=""),n(2,d=!0))}}async function ce(){if(confirm(i.confirm_leave))try{await window.go.main.App.LeaveRoom(),ee(i.notif_left),await S()}catch(R){ee(ne(i.error_leave,{err:R}),"error")}}async function O(R){const x=a.room===R;if(x){if(!confirm(i.confirm_leave_remove))return}else if(!confirm(ne(i.confirm_remove,{name:R})))return;try{x&&await window.go.main.App.LeaveRoom(),await window.go.main.App.RemoveSavedRoom(R),ee(ne(i.notif_removed,{name:R})),await S()}catch(Se){ee(ne(i.error_remove,{err:Se}),"error")}}async function Y(R){if(confirm(ne(i.confirm_delete,{name:R})))try{await window.go.main.App.DeleteRoom(R),await window.go.main.App.RemoveSavedRoom(R),ee(ne(i.notif_deleted,{name:R})),await S()}catch(x){ee(String(x),"error")}}async function U(R){try{const x=await window.go.main.App.FormatInvite(R.name,R.password||"");await window.go.main.App.CopyText(x);const Se=String(x).split("|"),Re=Se.length>=3&&Se[2]!=="";R.locked&&!Re?ee(i.invite_no_password,"info"):ee(i.invite_copied)}catch(x){ee(String(x),"error")}}async function z(){try{const R=await window.go.main.App.LoadConfig();R.serverAddr&&(C=R.serverAddr),R.nickname&&(D=R.nickname)}catch{}}async function te(R,x,Se){if(!P){n(11,P=R),n(13,N=null);try{await z();const Re=Se||C;if(!a.connected){if(!Re||!D){ee(i.notif_need_config,"error"),Ze(Ce,o="connect",o);return}const we=await window.go.main.App.Connect(Re,D);ze.set(we),await S()}await window.go.main.App.JoinRoom(R,x||""),Ze(Ce,o="network",o),await S()}catch(Re){const we=ne(i.error_join,{err:Re});ee(we,"error"),n(5,f=R),n(6,m=""),n(8,w=we),n(2,d=!0)}finally{n(11,P="")}}}function oe(R,x){(R.key==="Enter"||R.key===" ")&&(R.preventDefault(),te(x.name,x.password,x.server))}function Z(R,x){R.stopPropagation(),n(13,N=N===x?null:x)}function H(R,x){R.stopPropagation(),n(13,N=null),x()}function pe(R){zt.call(this,t,R)}function ue(R){zt.call(this,t,R)}function Ie(R){zt.call(this,t,R)}function Ne(R){zt.call(this,t,R)}function fe(R){zt.call(this,t,R)}function ye(R){zt.call(this,t,R)}const ge=(R,x)=>Z(x,R.name),je=(R,x)=>H(x,()=>U(R)),De=R=>H(R,ce),me=(R,x)=>H(x,()=>O(R.name)),le=(R,x)=>H(x,()=>Y(R.name)),We=R=>te(R.name,R.password,R.server),_e=(R,x)=>oe(x,R),he=()=>{o==="settings"?Ze(Ce,o=k,o):(n(12,k=o),Ze(Ce,o="settings",o))};function be(){u=this.value,n(3,u)}function X(){v=this.value,n(4,v)}function se(R){Vt[R?"unshift":"push"](()=>{y=R,n(14,y)})}const st=R=>R.key==="Escape"&&M();function Fe(){f=this.value,n(5,f)}function rt(){m=this.value,n(6,m)}const it=()=>Q();function re(R){Vt[R?"unshift":"push"](()=>{I=R,n(15,I)})}return[r,_,d,u,v,f,m,j,w,A,p,P,k,N,y,I,i,o,a,E,M,L,q,V,Q,ce,O,Y,U,te,oe,Z,H,pe,ue,Ie,Ne,fe,ye,ge,je,De,me,le,We,_e,he,be,X,se,st,Fe,rt,it,re,R=>R.key==="Escape"&&q()]}class vo extends wt{constructor(e){super(),gt(this,e,po,fo,dt,{},null,[-1,-1,-1])}}function oi(t,e,n){const i=t.slice();return i[24]=e[n],i}function ai(t){let e,n,i=t[5].chat+"",o,a,r,_,d,u=t[3]>0&&ri(t);return{c(){e=c("button"),n=g("[ "),o=g(i),a=g(` ] - `),u&&u.c(),s(e,"class","room-chat-btn svelte-mpjrp9"),s(e,"title",r=t[5].room_chat)},m(v,f){K(v,e,f),l(e,n),l(e,o),l(e,a),u&&u.m(e,null),_||(d=W(e,"click",t[8]),_=!0)},p(v,f){f&32&&i!==(i=v[5].chat+"")&&b(o,i),v[3]>0?u?u.p(v,f):(u=ri(v),u.c(),u.m(e,null)):u&&(u.d(1),u=null),f&32&&r!==(r=v[5].room_chat)&&s(e,"title",r)},d(v){v&&F(e),u&&u.d(),_=!1,d()}}}function ri(t){let e,n;return{c(){e=c("span"),n=g(t[3]),s(e,"class","badge svelte-mpjrp9")},m(i,o){K(i,e,o),l(e,n)},p(i,o){o&8&&b(n,i[3])},d(i){i&&F(e)}}}function ci(t){let e,n=t[5].status_relay_degraded+"",i;return{c(){e=c("span"),i=g(n),s(e,"class","relay-hint svelte-mpjrp9")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&32&&n!==(n=o[5].status_relay_degraded+"")&&b(i,n)},d(o){o&&F(e)}}}function ui(t){let e,n,i,o,a=t[5].no_peers+"",r,_,d,u=t[5].no_peers_desc+"",v,f;return{c(){e=c("div"),n=c("div"),n.textContent="[ . . . ]",i=h(),o=c("div"),r=g(a),_=h(),d=c("div"),v=g(u),f=h(),s(n,"class","empty-icon"),s(o,"class","empty-label svelte-mpjrp9"),s(d,"class","empty-desc svelte-mpjrp9"),s(e,"class","empty-peers svelte-mpjrp9")},m(m,j){K(m,e,j),l(e,n),l(e,i),l(e,o),l(o,r),l(e,_),l(e,d),l(d,v),l(e,f)},p(m,j){j&32&&a!==(a=m[5].no_peers+"")&&b(r,a),j&32&&u!==(u=m[5].no_peers_desc+"")&&b(v,u)},d(m){m&&F(e)}}}function _i(t){let e,n=t[11](t[24].id)+"",i;return{c(){e=c("span"),i=g(n),s(e,"class","badge svelte-mpjrp9")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&16&&n!==(n=o[11](o[24].id)+"")&&b(i,n)},d(o){o&&F(e)}}}function mo(t){let e;return{c(){e=g("...")},m(n,i){K(n,e,i)},p:de,d(n){n&&F(e)}}}function ho(t){let e=t[24].ping+"",n,i;return{c(){n=g(e),i=g("ms")},m(o,a){K(o,n,a),K(o,i,a)},p(o,a){a&16&&e!==(e=o[24].ping+"")&&b(n,e)},d(o){o&&(F(n),F(i))}}}function go(t){let e;return{c(){e=g("-")},m(n,i){K(n,e,i)},p:de,d(n){n&&F(e)}}}function fi(t,e){let n,i,o,a,r,_,d=(e[24].connected?e[5].status_online:e[5].status_offline)+"",u,v,f,m,j=(e[24].nickname||e[24].id)+"",w,A,p=e[11](e[24].id)>0,C,D,P=(e[24].virtualIP||e[5].na)+"",k,N,y,I,J,B=(e[24].path?e[12](e[24].path):e[5].path_unknown)+"",S,E,M,L,q,V,Q,ce,O,Y,U,z,te,oe,Z,H,pe,ue=p&&_i(e);function Ie(){return e[20](e[24])}function Ne(...me){return e[21](e[24],...me)}function fe(me,le){return me[24].connected?me[24].ping>=0&&!me[1][me[24].id]?ho:mo:go}let ye=fe(e),ge=ye(e);function je(){return e[22](e[24])}function De(){return e[23](e[24])}return{key:t,first:null,c(){n=c("div"),i=c("span"),o=c("span"),r=h(),_=c("span"),u=g(d),v=h(),f=c("span"),m=c("span"),w=g(j),A=h(),ue&&ue.c(),C=h(),D=c("span"),k=g(P),N=h(),y=c("span"),ge.c(),I=h(),J=c("span"),S=g(B),M=h(),L=c("span"),q=c("button"),V=g("[~]"),Y=h(),U=c("button"),z=g("[>]"),Z=h(),s(o,"class",a="sq "+(e[24].connected?"sq-online":"sq-offline")+" svelte-mpjrp9"),s(o,"aria-hidden","true"),s(_,"class","status-text svelte-mpjrp9"),s(i,"class","status-cell svelte-mpjrp9"),s(i,"role","cell"),s(m,"class","nickname svelte-mpjrp9"),s(f,"class","col-name"),s(f,"role","cell"),s(D,"class","col-ip clickable svelte-mpjrp9"),s(D,"role","button"),s(D,"tabindex","0"),s(y,"class","col-ping svelte-mpjrp9"),s(y,"role","cell"),ke(y,"probing",e[24].connected&&(e[24].ping<0||e[1][e[24].id])),s(J,"class","col-path svelte-mpjrp9"),s(J,"role","cell"),s(J,"title",E=e[13](e[24].path)),s(q,"class","row-btn svelte-mpjrp9"),q.disabled=Q=!e[24].connected||!!e[1][e[24].id],s(q,"title",ce=e[5].ping_peer),s(q,"aria-label",O=e[5].ping_peer),s(U,"class","row-btn svelte-mpjrp9"),s(U,"title",te=e[5].chat+" "+(e[24].nickname||e[24].id)),s(U,"aria-label",oe=e[5].chat+" "+(e[24].nickname||e[24].id)),s(L,"class","col-action svelte-mpjrp9"),s(L,"role","cell"),s(n,"class","table-row svelte-mpjrp9"),s(n,"role","row"),this.first=n},m(me,le){K(me,n,le),l(n,i),l(i,o),l(i,r),l(i,_),l(_,u),l(n,v),l(n,f),l(f,m),l(m,w),l(f,A),ue&&ue.m(f,null),l(n,C),l(n,D),l(D,k),l(n,N),l(n,y),ge.m(y,null),l(n,I),l(n,J),l(J,S),l(n,M),l(n,L),l(L,q),l(q,V),l(L,Y),l(L,U),l(U,z),l(n,Z),H||(pe=[W(D,"click",Ie),W(D,"keydown",Ne),W(q,"click",je),W(U,"click",De)],H=!0)},p(me,le){e=me,le&16&&a!==(a="sq "+(e[24].connected?"sq-online":"sq-offline")+" svelte-mpjrp9")&&s(o,"class",a),le&48&&d!==(d=(e[24].connected?e[5].status_online:e[5].status_offline)+"")&&b(u,d),le&16&&j!==(j=(e[24].nickname||e[24].id)+"")&&b(w,j),le&16&&(p=e[11](e[24].id)>0),p?ue?ue.p(e,le):(ue=_i(e),ue.c(),ue.m(f,null)):ue&&(ue.d(1),ue=null),le&48&&P!==(P=(e[24].virtualIP||e[5].na)+"")&&b(k,P),ye===(ye=fe(e))&&ge?ge.p(e,le):(ge.d(1),ge=ye(e),ge&&(ge.c(),ge.m(y,null))),le&18&&ke(y,"probing",e[24].connected&&(e[24].ping<0||e[1][e[24].id])),le&48&&B!==(B=(e[24].path?e[12](e[24].path):e[5].path_unknown)+"")&&b(S,B),le&16&&E!==(E=e[13](e[24].path))&&s(J,"title",E),le&18&&Q!==(Q=!e[24].connected||!!e[1][e[24].id])&&(q.disabled=Q),le&32&&ce!==(ce=e[5].ping_peer)&&s(q,"title",ce),le&32&&O!==(O=e[5].ping_peer)&&s(q,"aria-label",O),le&48&&te!==(te=e[5].chat+" "+(e[24].nickname||e[24].id))&&s(U,"title",te),le&48&&oe!==(oe=e[5].chat+" "+(e[24].nickname||e[24].id))&&s(U,"aria-label",oe)},d(me){me&&F(n),ue&&ue.d(),ge.d(),H=!1,Le(pe)}}}function wo(t){let e,n,i,o=(t[0].room||t[5].network)+"",a,r,_,d=(t[0].virtualIP||t[5].na)+"",u,v,f,m,j,w,A,p,C,D,P,k=t[5].col_nickname+"",N,y,I,J=t[5].col_ip+"",B,S,E,M=t[5].col_ping+"",L,q,V,Q=t[5].col_path+"",ce,O,Y,U,z,te,oe,Z,H,pe=t[5].status_online+"",ue,Ie,Ne,fe,ye=(t[6].nickname||t[5].you)+"",ge,je,De,me=t[5].me+"",le,We,_e,he=(t[0].virtualIP||t[5].na)+"",be,X,se,st,Fe,rt,it,re,Ae=[],R=new Map,x,Se,Re,we=t[0].room&&ai(t),Ee=t[2]&&ci(t),Ke=ft(t[4]);const bt=$=>$[24].id;for(let $=0;$n(5,r=E)),ve(t,Xl,E=>n(15,_=E)),ve(t,ze,E=>n(0,d=E)),ve(t,Yl,E=>n(16,u=E)),ve(t,Be,E=>n(6,v=E));let f={};function m(E){cn.set({id:E.id,nickname:E.nickname||E.id}),Kl("peer:"+E.id),Ce.set("chat")}function j(){cn.set(null),Kl("room:"+(d.room||"network")),Ce.set("chat")}async function w(E){if(E)try{await window.go.main.App.CopyText(E),ee(r.copied)}catch{}}async function A(E){if(!(!E?.id||!E.connected||f[E.id])){n(1,f={...f,[E.id]:!0});try{await window.go.main.App.PingPeer(E.id),ee(ne(r.ping_sent,{name:E.nickname||E.id}))}catch(M){ee(ne(r.error_ping,{err:M}),"error")}finally{setTimeout(()=>{const M={...f};delete M[E.id],n(1,f=M)},800)}}}function p(E){return _["peer:"+E]||0}function C(E){return E==="p2p"?r.path_p2p:E==="relay"?r.path_relay:E==="ws"?r.path_ws:r.path_unknown}function D(E){return E==="p2p"?r.path_p2p_tip:E==="relay"?r.path_relay_tip:E==="ws"?r.path_ws_tip:""}function P(E,M){(E.key==="Enter"||E.key===" ")&&(E.preventDefault(),w(M))}const k=()=>w(d.virtualIP),N=()=>w(d.virtualIP),y=E=>P(E,d.virtualIP),I=E=>w(E.virtualIP),J=(E,M)=>P(M,E.virtualIP),B=E=>A(E),S=E=>m(E);return t.$$.update=()=>{t.$$.dirty&65536&&n(4,i=[...u].sort((E,M)=>(E.nickname||"").localeCompare(M.nickname||""))),t.$$.dirty&32769&&n(3,o=_["room:"+(d.room||"network")]||0),t.$$.dirty&65536&&n(2,a=u.some(E=>E.path==="relay"||E.path==="ws"))},[d,f,a,o,i,r,v,m,j,w,A,p,C,D,P,_,u,k,N,y,I,J,B,S]}class bo extends wt{constructor(e){super(),gt(this,e,ko,wo,dt,{})}}function di(t){let e,n=t[2].status_relay_degraded+"",i,o;return{c(){e=c("span"),i=g(n),s(e,"class","degraded status-item svelte-1pzfkl"),s(e,"title",o=t[2].path_relay_tip)},m(a,r){K(a,e,r),l(e,i)},p(a,r){r&4&&n!==(n=a[2].status_relay_degraded+"")&&b(i,n),r&4&&o!==(o=a[2].path_relay_tip)&&s(e,"title",o)},d(a){a&&F(e)}}}function pi(t){let e,n=ne(t[2].status_server,{s:t[3].server})+"",i,o;return{c(){e=c("span"),i=g(n),s(e,"class","status-item status-server svelte-1pzfkl"),s(e,"title",o=t[3].server)},m(a,r){K(a,e,r),l(e,i)},p(a,r){r&12&&n!==(n=ne(a[2].status_server,{s:a[3].server})+"")&&b(i,n),r&8&&o!==(o=a[3].server)&&s(e,"title",o)},d(a){a&&F(e)}}}function vi(t){let e,n=ne(t[2].status_ip,{ip:t[3].virtualIP})+"",i,o;return{c(){e=c("span"),i=g(n),s(e,"class","status-item svelte-1pzfkl"),s(e,"title",o=t[3].virtualIP)},m(a,r){K(a,e,r),l(e,i)},p(a,r){r&12&&n!==(n=ne(a[2].status_ip,{ip:a[3].virtualIP})+"")&&b(i,n),r&8&&o!==(o=a[3].virtualIP)&&s(e,"title",o)},d(a){a&&F(e)}}}function mi(t){let e,n=ne(t[2].status_network,{room:t[3].room})+"",i,o;return{c(){e=c("span"),i=g(n),s(e,"class","status-item status-room svelte-1pzfkl"),s(e,"title",o=t[3].room)},m(a,r){K(a,e,r),l(e,i)},p(a,r){r&12&&n!==(n=ne(a[2].status_network,{room:a[3].room})+"")&&b(i,n),r&8&&o!==(o=a[3].room)&&s(e,"title",o)},d(a){a&&F(e)}}}function hi(t){let e,n=ne(t[2].status_peers,{n:t[3].peerCount})+"",i;return{c(){e=c("span"),i=g(n),s(e,"class","status-item svelte-1pzfkl")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&12&&n!==(n=ne(o[2].status_peers,{n:o[3].peerCount})+"")&&b(i,n)},d(o){o&&F(e)}}}function yo(t){let e,n,i,o,a,r,_,d,u,v,f,m,j,w,A=ne(t[2].version,{v:t[4]})+"",p,C=t[1]&&t[3].connected&&di(t),D=t[3].server&&pi(t),P=t[3].virtualIP&&vi(t),k=t[3].room&&mi(t),N=t[3].peerCount!==void 0&&hi(t);return{c(){e=c("footer"),n=c("div"),i=c("span"),o=h(),a=c("span"),r=g(t[0]),_=h(),C&&C.c(),d=h(),u=c("div"),D&&D.c(),v=h(),P&&P.c(),f=h(),k&&k.c(),m=h(),N&&N.c(),j=h(),w=c("span"),p=g(A),s(i,"class","sq svelte-1pzfkl"),s(i,"aria-hidden","true"),ke(i,"sq-connected",t[3].connected&&!t[3].reconnecting),ke(i,"sq-warn",t[3].reconnecting),s(a,"class","status-item svelte-1pzfkl"),s(a,"title",t[5]),s(n,"class","status-left svelte-1pzfkl"),s(w,"class","status-item status-ver svelte-1pzfkl"),s(u,"class","status-right svelte-1pzfkl"),s(e,"class","statusbar svelte-1pzfkl"),s(e,"role","status"),s(e,"aria-live","polite")},m(y,I){K(y,e,I),l(e,n),l(n,i),l(n,o),l(n,a),l(a,r),l(n,_),C&&C.m(n,null),l(e,d),l(e,u),D&&D.m(u,null),l(u,v),P&&P.m(u,null),l(u,f),k&&k.m(u,null),l(u,m),N&&N.m(u,null),l(u,j),l(u,w),l(w,p)},p(y,[I]){I&8&&ke(i,"sq-connected",y[3].connected&&!y[3].reconnecting),I&8&&ke(i,"sq-warn",y[3].reconnecting),I&1&&b(r,y[0]),I&32&&s(a,"title",y[5]),y[1]&&y[3].connected?C?C.p(y,I):(C=di(y),C.c(),C.m(n,null)):C&&(C.d(1),C=null),y[3].server?D?D.p(y,I):(D=pi(y),D.c(),D.m(u,v)):D&&(D.d(1),D=null),y[3].virtualIP?P?P.p(y,I):(P=vi(y),P.c(),P.m(u,f)):P&&(P.d(1),P=null),y[3].room?k?k.p(y,I):(k=mi(y),k.c(),k.m(u,m)):k&&(k.d(1),k=null),y[3].peerCount!==void 0?N?N.p(y,I):(N=hi(y),N.c(),N.m(u,j)):N&&(N.d(1),N=null),I&20&&A!==(A=ne(y[2].version,{v:y[4]})+"")&&b(p,A)},i:de,o:de,d(y){y&&F(e),C&&C.d(),D&&D.d(),P&&P.d(),k&&k.d(),N&&N.d()}}}function jo(t,e,n){let i,o,a,r,_,d;ve(t,kt,v=>n(2,r=v)),ve(t,ze,v=>n(3,_=v)),ve(t,Yl,v=>n(6,d=v));let u="1.0.0";return fn(async()=>{try{window.go?.main?.App?.GetVersion&&n(4,u=await window.go.main.App.GetVersion())}catch{}}),t.$$.update=()=>{t.$$.dirty&64&&n(1,i=(d||[]).some(v=>v.path==="relay"||v.path==="ws")),t.$$.dirty&12&&n(0,o=_.reconnecting?r.status_reconnecting:_.connected?r.status_connected:r.status_disconnected),t.$$.dirty&15&&n(5,a=i&&_.connected?r.status_relay_degraded:o)},[o,i,r,_,u,a,d]}class So extends wt{constructor(e){super(),gt(this,e,jo,yo,dt,{})}}function Eo(t){let e,n,i,o,a=t[0].server+"",r,_,d,u=t[1].server+"",v,f,m,j,w=t[0].virtual_ip+"",A,p,C,D=(t[1].virtualIP||t[0].na)+"",P,k,N,y=t[0].disconnect+"",I,J,B;function S(L,q){return L[1].reconnecting?Co:Po}let E=S(t),M=E(t);return{c(){e=c("div"),M.c(),n=h(),i=c("div"),o=c("span"),r=g(a),_=h(),d=c("span"),v=g(u),f=h(),m=c("div"),j=c("span"),A=g(w),p=h(),C=c("span"),P=g(D),k=h(),N=c("button"),I=g(y),s(d,"class","info-value svelte-1br9j49"),s(i,"class","info-line svelte-1br9j49"),s(C,"class","info-value svelte-1br9j49"),s(m,"class","info-line svelte-1br9j49"),s(N,"class","disconnect-btn svelte-1br9j49"),s(e,"class","connected-info svelte-1br9j49")},m(L,q){K(L,e,q),M.m(e,null),l(e,n),l(e,i),l(i,o),l(o,r),l(i,_),l(i,d),l(d,v),l(e,f),l(e,m),l(m,j),l(j,A),l(m,p),l(m,C),l(C,P),l(e,k),l(e,N),l(N,I),J||(B=W(N,"click",t[12]),J=!0)},p(L,q){E===(E=S(L))&&M?M.p(L,q):(M.d(1),M=E(L),M&&(M.c(),M.m(e,n))),q&1&&a!==(a=L[0].server+"")&&b(r,a),q&2&&u!==(u=L[1].server+"")&&b(v,u),q&1&&w!==(w=L[0].virtual_ip+"")&&b(A,w),q&3&&D!==(D=(L[1].virtualIP||L[0].na)+"")&&b(P,D),q&1&&y!==(y=L[0].disconnect+"")&&b(I,y)},d(L){L&&F(e),M.d(),J=!1,B()}}}function Ao(t){let e,n,i,o=t[0].brand+"",a,r,_,d=t[0].tagline+"",u,v,f,m,j=t[0].server_addr+"",w,A,p,C,D,P,k,N,y,I=t[0].nickname+"",J,B,S,E,M,L,q,V,Q=(t[5]?t[0].connecting:t[0].connect)+"",ce,O,Y,U,z,te=t[0].paste_invite+"",oe,Z,H,pe,ue=t[0].paste_invite+"",Ie,Ne,fe,ye,ge,je,De=t[0].join+"",me,le,We,_e=t[7].serverAddr&&gi(t),he=t[7].nickname&&wi(t),be=(t[5]||t[1].phase==="dialing"||t[1].phase==="auth")&&ki(t);return{c(){e=c("div"),n=c("div"),i=c("h1"),a=g(o),r=h(),_=c("p"),u=g(d),v=h(),f=c("div"),m=c("label"),w=g(j),A=h(),p=c("input"),P=h(),_e&&_e.c(),k=h(),N=c("div"),y=c("label"),J=g(I),B=h(),S=c("input"),L=h(),he&&he.c(),q=h(),V=c("button"),ce=g(Q),O=h(),be&&be.c(),Y=h(),U=c("details"),z=c("summary"),oe=g(te),Z=h(),H=c("div"),pe=c("label"),Ie=g(ue),Ne=h(),fe=c("input"),ge=h(),je=c("button"),me=g(De),s(i,"class","brand svelte-1br9j49"),s(_,"class","tagline svelte-1br9j49"),s(n,"class","brand-block svelte-1br9j49"),s(m,"for","server-input"),s(m,"class","svelte-1br9j49"),s(p,"id","server-input"),s(p,"type","text"),s(p,"placeholder","host:8080"),s(p,"aria-invalid",C=!!t[7].serverAddr),s(p,"aria-describedby",D=t[7].serverAddr?"server-err":void 0),s(p,"class","svelte-1br9j49"),ke(p,"invalid",t[7].serverAddr),s(f,"class","field svelte-1br9j49"),s(y,"for","nick-input"),s(y,"class","svelte-1br9j49"),s(S,"id","nick-input"),s(S,"type","text"),s(S,"placeholder","Player"),s(S,"aria-invalid",E=!!t[7].nickname),s(S,"aria-describedby",M=t[7].nickname?"nick-err":void 0),s(S,"class","svelte-1br9j49"),ke(S,"invalid",t[7].nickname),s(N,"class","field svelte-1br9j49"),s(V,"class","connect-btn svelte-1br9j49"),V.disabled=t[5],s(z,"class","svelte-1br9j49"),s(pe,"for","invite-input"),s(pe,"class","sr-only svelte-1br9j49"),s(fe,"id","invite-input"),s(fe,"type","text"),s(fe,"placeholder",ye=t[0].invite_placeholder),s(fe,"class","svelte-1br9j49"),s(je,"class","secondary-btn svelte-1br9j49"),je.disabled=t[5],s(H,"class","invite-block svelte-1br9j49"),s(U,"class","invite-disclosure svelte-1br9j49"),s(e,"class","connect-form svelte-1br9j49")},m(X,se){K(X,e,se),l(e,n),l(n,i),l(i,a),l(n,r),l(n,_),l(_,u),l(e,v),l(e,f),l(f,m),l(m,w),l(f,A),l(f,p),ie(p,t[2]),l(f,P),_e&&_e.m(f,null),l(e,k),l(e,N),l(N,y),l(y,J),l(N,B),l(N,S),ie(S,t[3]),l(N,L),he&&he.m(N,null),l(e,q),l(e,V),l(V,ce),l(e,O),be&&be.m(e,null),l(e,Y),l(e,U),l(U,z),l(z,oe),l(U,Z),l(U,H),l(H,pe),l(pe,Ie),l(H,Ne),l(H,fe),ie(fe,t[4]),l(H,ge),l(H,je),l(je,me),U.open=t[6],le||(We=[W(p,"input",t[13]),W(S,"input",t[14]),W(S,"keydown",t[11]),W(V,"click",t[9]),W(fe,"input",t[15]),W(je,"click",t[10]),W(U,"toggle",t[16])],le=!0)},p(X,se){se&1&&o!==(o=X[0].brand+"")&&b(a,o),se&1&&d!==(d=X[0].tagline+"")&&b(u,d),se&1&&j!==(j=X[0].server_addr+"")&&b(w,j),se&128&&C!==(C=!!X[7].serverAddr)&&s(p,"aria-invalid",C),se&128&&D!==(D=X[7].serverAddr?"server-err":void 0)&&s(p,"aria-describedby",D),se&4&&p.value!==X[2]&&ie(p,X[2]),se&128&&ke(p,"invalid",X[7].serverAddr),X[7].serverAddr?_e?_e.p(X,se):(_e=gi(X),_e.c(),_e.m(f,null)):_e&&(_e.d(1),_e=null),se&1&&I!==(I=X[0].nickname+"")&&b(J,I),se&128&&E!==(E=!!X[7].nickname)&&s(S,"aria-invalid",E),se&128&&M!==(M=X[7].nickname?"nick-err":void 0)&&s(S,"aria-describedby",M),se&8&&S.value!==X[3]&&ie(S,X[3]),se&128&&ke(S,"invalid",X[7].nickname),X[7].nickname?he?he.p(X,se):(he=wi(X),he.c(),he.m(N,null)):he&&(he.d(1),he=null),se&33&&Q!==(Q=(X[5]?X[0].connecting:X[0].connect)+"")&&b(ce,Q),se&32&&(V.disabled=X[5]),X[5]||X[1].phase==="dialing"||X[1].phase==="auth"?be?be.p(X,se):(be=ki(X),be.c(),be.m(e,Y)):be&&(be.d(1),be=null),se&1&&te!==(te=X[0].paste_invite+"")&&b(oe,te),se&1&&ue!==(ue=X[0].paste_invite+"")&&b(Ie,ue),se&1&&ye!==(ye=X[0].invite_placeholder)&&s(fe,"placeholder",ye),se&16&&fe.value!==X[4]&&ie(fe,X[4]),se&1&&De!==(De=X[0].join+"")&&b(me,De),se&32&&(je.disabled=X[5]),se&64&&(U.open=X[6])},d(X){X&&F(e),_e&&_e.d(),he&&he.d(),be&&be.d(),le=!1,Le(We)}}}function Po(t){let e,n,i,o,a=t[0].connected+"",r;return{c(){e=c("div"),n=c("span"),i=h(),o=c("span"),r=g(a),s(n,"class","sq sq-green svelte-1br9j49"),s(n,"aria-hidden","true"),s(e,"class","connected-line svelte-1br9j49"),s(e,"role","status")},m(_,d){K(_,e,d),l(e,n),l(e,i),l(e,o),l(o,r)},p(_,d){d&1&&a!==(a=_[0].connected+"")&&b(r,a)},d(_){_&&F(e)}}}function Co(t){let e,n,i,o,a=t[0].reconnecting+"",r;return{c(){e=c("div"),n=c("span"),i=h(),o=c("span"),r=g(a),s(n,"class","sq sq-warn svelte-1br9j49"),s(n,"aria-hidden","true"),s(e,"class","connected-line svelte-1br9j49"),s(e,"role","status")},m(_,d){K(_,e,d),l(e,n),l(e,i),l(e,o),l(o,r)},p(_,d){d&1&&a!==(a=_[0].reconnecting+"")&&b(r,a)},d(_){_&&F(e)}}}function gi(t){let e,n=t[7].serverAddr+"",i;return{c(){e=c("span"),i=g(n),s(e,"id","server-err"),s(e,"class","field-error svelte-1br9j49"),s(e,"role","alert")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].serverAddr+"")&&b(i,n)},d(o){o&&F(e)}}}function wi(t){let e,n=t[7].nickname+"",i;return{c(){e=c("span"),i=g(n),s(e,"id","nick-err"),s(e,"class","field-error svelte-1br9j49"),s(e,"role","alert")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].nickname+"")&&b(i,n)},d(o){o&&F(e)}}}function ki(t){let e,n=(t[8]||t[0].connecting)+"",i;return{c(){e=c("div"),i=g(n),s(e,"class","phase svelte-1br9j49"),s(e,"role","status")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&257&&n!==(n=(o[8]||o[0].connecting)+"")&&b(i,n)},d(o){o&&F(e)}}}function No(t){let e;function n(a,r){return a[1].connected?Eo:Ao}let i=n(t),o=i(t);return{c(){e=c("div"),o.c(),s(e,"class","connect-view svelte-1br9j49")},m(a,r){K(a,e,r),o.m(e,null)},p(a,[r]){i===(i=n(a))&&o?o.p(a,r):(o.d(1),o=i(a),o&&(o.c(),o.m(e,null)))},i:de,o:de,d(a){a&&F(e),o.d()}}}function Do(t,e,n){let i,o,a,r;ve(t,kt,y=>n(0,o=y)),ve(t,ze,y=>n(1,a=y)),ve(t,Be,y=>n(17,r=y));let _="",d="",u="",v=!1,f=!1,m={};fn(async()=>{const y=await window.go.main.App.LoadConfig();y.serverAddr&&n(2,_=y.serverAddr),y.nickname&&n(3,d=y.nickname),y&&Be.set({...r,...y}),y.autoConnect&&y.serverAddr&&y.nickname&&w()});function j(){const y={};return _.trim()||(y.serverAddr=o.field_required),d.trim()||(y.nickname=o.field_required),n(7,m=y),Object.keys(y).length===0}async function w(){if(!v&&j()){n(5,v=!0),un();try{const y=await window.go.main.App.Connect(_,d);ze.set(y),Ce.set("network"),ee(ne(o.notif_connected,{addr:_})),n(7,m={})}catch(y){ee(ne(o.error_connect,{err:y}),"error")}finally{n(5,v=!1)}}}async function A(){if(u.trim()){un();try{const y=await window.go.main.App.ParseInvite(u.trim());if(!y.server||!y.room){ee(o.error_invalid_invite,"error");return}if(n(2,_=y.server),!a.connected){if(!d.trim()){n(7,m={...m,nickname:o.field_required}),ee(o.notif_need_config,"error");return}n(5,v=!0);const I=await window.go.main.App.Connect(_,d);ze.set(I),n(5,v=!1)}await window.go.main.App.JoinRoom(y.room,y.password||""),ee(ne(o.notif_joined,{name:y.room})),Ce.set("network")}catch(y){ee(ne(o.error_join,{err:y}),"error"),n(5,v=!1)}}}function p(y){y.key==="Enter"&&(y.preventDefault(),w())}async function C(){if(confirm(o.confirm_disconnect))try{await window.go.main.App.Disconnect(),ze.set({connected:!1,reconnecting:!1,server:"",room:"",virtualIP:"",peerCount:0,isOwner:!1,phase:"idle"}),Ce.set("connect"),ee(o.notif_disconnected)}catch(y){ee(ne(o.error_disconnect,{err:y}),"error")}}function D(){_=this.value,n(2,_)}function P(){d=this.value,n(3,d)}function k(){u=this.value,n(4,u)}function N(){f=this.open,n(6,f)}return t.$$.update=()=>{t.$$.dirty&3&&n(8,i=a.phase==="dialing"?o.phase_dialing:a.phase==="auth"?o.phase_auth:a.phase==="ready"?o.phase_ready:a.phase==="error"?o.phase_error:"")},[o,a,_,d,u,v,f,m,i,w,A,p,C,D,P,k,N]}class Lo extends wt{constructor(e){super(),gt(this,e,Do,No,dt,{})}}function bi(t,e,n){const i=t.slice();return i[23]=e[n],i[25]=n,i}function yi(t){let e,n,i,o,a=t[0].no_messages+"",r,_,d,u=t[0].no_messages_desc+"",v;return{c(){e=c("div"),n=c("div"),n.textContent="[ . . . ]",i=h(),o=c("div"),r=g(a),_=h(),d=c("div"),v=g(u),s(n,"class","empty-chat-icon"),s(o,"class","empty-chat-label svelte-11c1d7e"),s(d,"class","empty-chat-desc svelte-11c1d7e"),s(e,"class","empty-chat svelte-11c1d7e")},m(f,m){K(f,e,m),l(e,n),l(e,i),l(e,o),l(o,r),l(e,_),l(e,d),l(d,v)},p(f,m){m&1&&a!==(a=f[0].no_messages+"")&&b(r,a),m&1&&u!==(u=f[0].no_messages_desc+"")&&b(v,u)},d(f){f&&F(e)}}}function ji(t){let e,n=t[12](t[23].timestamp)+"",i;return{c(){e=c("div"),i=g(n),s(e,"class","date-sep svelte-11c1d7e")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[12](o[23].timestamp)+"")&&b(i,n)},d(o){o&&F(e)}}}function Io(t){let e,n,i,o=(t[23].isSelf?t[6].nickname||t[0].you_self:t[23].nickname)+"",a,r,_,d,u,v=t[23].message+"",f,m,j=t[23].status==="pending"&&Si(),w=t[23].status==="failed"&&Ei(t);return{c(){e=c("div"),n=c("div"),i=c("span"),a=g(o),r=h(),j&&j.c(),_=h(),w&&w.c(),d=h(),u=c("div"),f=g(v),m=h(),s(i,"class","msg-nick"),s(n,"class","msg-meta svelte-11c1d7e"),s(u,"class","msg-body svelte-11c1d7e"),s(e,"class","msg svelte-11c1d7e"),ke(e,"self",t[23].isSelf)},m(A,p){K(A,e,p),l(e,n),l(n,i),l(i,a),l(n,r),j&&j.m(n,null),l(n,_),w&&w.m(n,null),l(e,d),l(e,u),l(u,f),l(e,m)},p(A,p){p&193&&o!==(o=(A[23].isSelf?A[6].nickname||A[0].you_self:A[23].nickname)+"")&&b(a,o),A[23].status==="pending"?j||(j=Si(),j.c(),j.m(n,_)):j&&(j.d(1),j=null),A[23].status==="failed"?w?w.p(A,p):(w=Ei(A),w.c(),w.m(n,null)):w&&(w.d(1),w=null),p&128&&v!==(v=A[23].message+"")&&b(f,v),p&128&&ke(e,"self",A[23].isSelf)},d(A){A&&F(e),j&&j.d(),w&&w.d()}}}function Ro(t){let e,n=t[23].message+"",i;return{c(){e=c("div"),i=g(n),s(e,"class","system-line svelte-11c1d7e")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[23].message+"")&&b(i,n)},d(o){o&&F(e)}}}function Si(t){let e;return{c(){e=c("span"),e.textContent="…",s(e,"class","msg-status")},m(n,i){K(n,e,i)},d(n){n&&F(e)}}}function Ei(t){let e,n=t[0].retry+"",i,o,a;function r(){return t[18](t[23])}return{c(){e=c("button"),i=g(n),s(e,"class","retry-btn svelte-11c1d7e")},m(_,d){K(_,e,d),l(e,i),o||(a=W(e,"click",r),o=!0)},p(_,d){t=_,d&1&&n!==(n=t[0].retry+"")&&b(i,n)},d(_){_&&F(e),o=!1,a()}}}function Ai(t,e){let n,i=Pi(e[23],e[25],e[7]),o,a,r=i&&ji(e);function _(v,f){return v[23].system?Ro:Io}let d=_(e),u=d(e);return{key:t,first:null,c(){n=Ul(),r&&r.c(),o=h(),u.c(),a=Ul(),this.first=n},m(v,f){K(v,n,f),r&&r.m(v,f),K(v,o,f),u.m(v,f),K(v,a,f)},p(v,f){e=v,f&128&&(i=Pi(e[23],e[25],e[7])),i?r?r.p(e,f):(r=ji(e),r.c(),r.m(o.parentNode,o)):r&&(r.d(1),r=null),d===(d=_(e))&&u?u.p(e,f):(u.d(1),u=d(e),u&&(u.c(),u.m(a.parentNode,a)))},d(v){v&&(F(n),F(o),F(a)),r&&r.d(v),u.d(v)}}}function To(t){let e,n,i,o,a,r,_,d,u,v,f,m=[],j=new Map,w,A,p,C,D,P,k,N=t[0].send+"",y,I,J,B,S=t[7].length===0&&yi(t),E=ft(t[7]);const M=L=>L[23].id;for(let L=0;Ln(15,a=S)),ve(t,kt,S=>n(0,r=S)),ve(t,cn,S=>n(16,_=S)),ve(t,Be,S=>n(6,d=S)),ve(t,Ce,S=>n(17,u=S)),ve(t,so,S=>n(7,v=S));let f="",m,j,w=!0;Gi(()=>{m&&w&&n(2,m.scrollTop=m.scrollHeight,m)});function A(){if(!m)return;w=m.scrollHeight-m.scrollTop-m.clientHeight<60}async function p(){const S=f.trim();if(!S)return;if(!a.connected){ee(r.error_not_connected,"error");return}if(!a.room){ee(r.send_disabled_no_room,"error");return}let E=S;const M=[...S];M.length>1e3&&(E=M.slice(0,1e3).join(""),ee(r.msg_truncated,"info")),n(1,f=""),j&&n(3,j.style.height="auto",j);const L="local_"+Date.now()+"_"+Math.random().toString(36).slice(2,7);Ql(L,d.nickname||r.you_self,E,!0,"pending");try{_&&_.id?await window.go.main.App.SendChat(_.id,E):await window.go.main.App.BroadcastChat(E),ln(L,"sent")}catch(q){ln(L,"failed"),ee(ne(r.error_send,{err:q}),"error")}}async function C(S){ln(S.id,"pending");try{_&&_.id?await window.go.main.App.SendChat(_.id,S.message):await window.go.main.App.BroadcastChat(S.message),ln(S.id,"sent")}catch(E){ln(S.id,"failed"),ee(ne(r.error_send,{err:E}),"error")}}function D(S){S.key==="Enter"&&!S.shiftKey&&(S.preventDefault(),p())}function P(S){const E=new Date(S),M=new Date,L=new Date(M.getFullYear(),M.getMonth(),M.getDate()),q=new Date(L-864e5),V=new Date(E.getFullYear(),E.getMonth(),E.getDate());return V.getTime()===L.getTime()?r.today:V.getTime()===q.getTime()?r.yesterday:E.toLocaleDateString([],{weekday:"long",month:"short",day:"numeric"})}function k(){j&&(n(3,j.style.height="auto",j),n(3,j.style.height=Math.min(j.scrollHeight,120)+"px",j))}function N(){cn.set(null),Ce.set("network")}const y=S=>C(S);function I(S){Vt[S?"unshift":"push"](()=>{m=S,n(2,m)})}function J(S){Vt[S?"unshift":"push"](()=>{j=S,n(3,j)})}function B(){f=this.value,n(1,f)}return t.$$.update=()=>{t.$$.dirty&131072&&u==="chat"&&Kl(_n()),t.$$.dirty&98305&&n(5,i=_?ne(r.chat_with,{name:_.nickname}):ne(r.room_chat_title,{room:a.room||r.network})),t.$$.dirty&32768&&n(4,o=a.connected&&!!a.room)},[r,f,m,j,o,i,d,v,A,p,C,D,P,k,N,a,_,u,y,I,J,B]}class Mo extends wt{constructor(e){super(),gt(this,e,Oo,To,dt,{})}}function Ci(t){let e,n=t[7].notif_reconnect_required+"",i;return{c(){e=c("p"),i=g(n),s(e,"class","reconnect-banner svelte-1pfl9w0"),s(e,"role","status")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].notif_reconnect_required+"")&&b(i,n)},d(o){o&&F(e)}}}function Ni(t){let e,n=t[7].apply_update+"",i,o,a;return{c(){e=c("button"),i=g(n),s(e,"class","btn btn-update svelte-1pfl9w0"),s(e,"type","button"),e.disabled=t[3]},m(r,_){K(r,e,_),l(e,i),o||(a=W(e,"click",t[10]),o=!0)},p(r,_){_&128&&n!==(n=r[7].apply_update+"")&&b(i,n),_&8&&(e.disabled=r[3])},d(r){r&&F(e),o=!1,a()}}}function qo(t){let e,n=t[7].update_failed+"",i,o,a;return{c(){e=c("p"),i=g(n),o=g(": "),a=g(t[6]),s(e,"class","hint reconnect-hint svelte-1pfl9w0")},m(r,_){K(r,e,_),l(e,i),l(e,o),l(e,a)},p(r,_){_&128&&n!==(n=r[7].update_failed+"")&&b(i,n),_&64&&b(a,r[6])},d(r){r&&F(e)}}}function Uo(t){let e,n=t[7].update_downloading+"",i;return{c(){e=c("p"),i=g(n),s(e,"class","hint svelte-1pfl9w0")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].update_downloading+"")&&b(i,n)},d(o){o&&F(e)}}}function zo(t){let e,n=ne(t[7].update_available,{v:t[5]})+"",i;return{c(){e=c("p"),i=g(n),s(e,"class","hint svelte-1pfl9w0")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&160&&n!==(n=ne(o[7].update_available,{v:o[5]})+"")&&b(i,n)},d(o){o&&F(e)}}}function Wo(t){let e,n=t[7].update_latest+"",i;return{c(){e=c("p"),i=g(n),s(e,"class","hint svelte-1pfl9w0")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].update_latest+"")&&b(i,n)},d(o){o&&F(e)}}}function Fo(t){let e,n=t[7].update_checking+"",i;return{c(){e=c("p"),i=g(n),s(e,"class","hint svelte-1pfl9w0")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].update_checking+"")&&b(i,n)},d(o){o&&F(e)}}}function Ko(t){let e,n,i=t[7].settings_title+"",o,a,r,_,d,u,v,f=t[7].section_connection+"",m,j,w,A,p,C=t[7].server_addr+"",D,P,k,N,y,I,J=t[7].nickname+"",B,S,E,M,L,q,V=t[7].server_token+"",Q,ce,O,Y,U,z,te=t[7].reconnect_apply+"",oe,Z,H,pe,ue=t[7].auto_connect+"",Ie,Ne,fe,ye,ge,je=t[7].auto_connect_desc+"",De,me,le,We,_e=t[7].auto_join+"",he,be,X,se,st,Fe=t[7].auto_join_desc+"",rt,it,re,Ae,R,x=t[7].section_network+"",Se,Re,we,Ee,Ke=t[7].advanced_warn+"",bt,Pe,$,ae,Je=t[7].connection_mode+"",il,xl,xe,yt,dn=t[7].connection_direct+"",ol,jt,pn=t[7].connection_relay+"",al,es,vn,mn=t[7].connection_mode_desc+"",rl,ts,St,Yt,hn=t[7].mtu+"",cl,ns,Ge,ls,gn,wn=t[7].mtu_desc+"",ul,ss,Et,Ht,kn=t[7].dns_server+"",_l,is,et,os,bn,yn=t[7].dns_desc+"",fl,as,At,Xt,jn=t[7].socks5+"",dl,rs,He,Sn,cs,En,An=t[7].socks5_desc+"",pl,us,Pt,Qt,Pn=t[7].stun_server+"",vl,_s,tt,fs,Cn,Nn=t[7].stun_desc+"",ml,ds,Xe,Ct,ps,Dn=t[7].section_system+"",hl,vs,ms,Nt,Ln,In=t[7].start_windows+"",gl,hs,pt,gs,ot,Rn,Tn=t[7].updates+"",wl,ws,ct,On=t[7].check_updates+"",kl,ks,bs,ys,Ve,Dt,js,Mn=t[7].section_appearance+"",bl,Ss,Es,ut,Zt,qn=t[7].ui_scale+"",yl,As,Qe,Un,Ps,$t,zn=(t[0].uiScale??100)+"",jl,Cs,Ns,Wn,Fn=t[7].ui_scale_desc+"",Sl,Ds,Lt,Kn,Jn=t[7].theme+"",El,Ls,at,It,qe,Is,Gn=t[7].theme_dark+"",Al,Rs,Rt,Ue,Ts,Vn=t[7].theme_light+"",Pl,Bn,Os,Tt,xt,Yn=t[7].language+"",Cl,Ms,nt,Ot,Hn=t[7].language_en+"",Nl,Mt,Xn=t[7].language_ru+"",Dl,qt,Qn=t[7].language_zh+"",Ll,qs,Us,_t,en,Zn=t[7].save+"",Il,zs,tn,$n=t[7].reset+"",Rl,Ws,nn,Fs,Tl,Ol,Ml,Ks,Te=t[2]&&Ci(t),Oe=t[4]==="available"&&Ni(t);function Js(T,G){if(T[4]==="checking")return Fo;if(T[4]==="latest")return Wo;if(T[4]==="available")return zo;if(T[4]==="downloading")return Uo;if(T[4]==="error"&&T[6])return qo}let Ut=Js(t),Me=Ut&&Ut(t);return Ol=Fi(t[28][0]),{c(){e=c("div"),n=c("h2"),o=g(i),a=h(),r=c("div"),Te&&Te.c(),_=h(),d=c("div"),u=c("div"),v=g("─── "),m=g(f),j=g(" ───"),w=h(),A=c("div"),p=c("label"),D=g(C),P=h(),k=c("input"),N=h(),y=c("div"),I=c("label"),B=g(J),S=h(),E=c("input"),M=h(),L=c("div"),q=c("label"),Q=g(V),ce=h(),O=c("input"),U=h(),z=c("p"),oe=g(te),Z=h(),H=c("label"),pe=c("span"),Ie=g(ue),Ne=h(),fe=c("input"),ye=h(),ge=c("span"),De=g(je),me=h(),le=c("label"),We=c("span"),he=g(_e),be=h(),X=c("input"),se=h(),st=c("span"),rt=g(Fe),it=h(),re=c("div"),Ae=c("div"),R=g("─── "),Se=g(x),Re=g(" ───"),we=h(),Ee=c("p"),bt=g(Ke),Pe=h(),$=c("div"),ae=c("label"),il=g(Je),xl=h(),xe=c("select"),yt=c("option"),ol=g(dn),jt=c("option"),al=g(pn),es=h(),vn=c("p"),rl=g(mn),ts=h(),St=c("div"),Yt=c("label"),cl=g(hn),ns=h(),Ge=c("input"),ls=h(),gn=c("p"),ul=g(wn),ss=h(),Et=c("div"),Ht=c("label"),_l=g(kn),is=h(),et=c("input"),os=h(),bn=c("p"),fl=g(yn),as=h(),At=c("div"),Xt=c("label"),dl=g(jn),rs=h(),He=c("input"),cs=h(),En=c("p"),pl=g(An),us=h(),Pt=c("div"),Qt=c("label"),vl=g(Pn),_s=h(),tt=c("input"),fs=h(),Cn=c("p"),ml=g(Nn),ds=h(),Xe=c("div"),Ct=c("div"),ps=g("─── "),hl=g(Dn),vs=g(" ───"),ms=h(),Nt=c("label"),Ln=c("span"),gl=g(In),hs=h(),pt=c("input"),gs=h(),ot=c("div"),Rn=c("span"),wl=g(Tn),ws=h(),ct=c("button"),kl=g(On),ks=h(),Oe&&Oe.c(),bs=h(),Me&&Me.c(),ys=h(),Ve=c("div"),Dt=c("div"),js=g("─── "),bl=g(Mn),Ss=g(" ───"),Es=h(),ut=c("div"),Zt=c("label"),yl=g(qn),As=h(),Qe=c("input"),Ps=h(),$t=c("span"),jl=g(zn),Cs=g("%"),Ns=h(),Wn=c("p"),Sl=g(Fn),Ds=h(),Lt=c("div"),Kn=c("span"),El=g(Jn),Ls=h(),at=c("div"),It=c("label"),qe=c("input"),Is=h(),Al=g(Gn),Rs=h(),Rt=c("label"),Ue=c("input"),Ts=h(),Pl=g(Vn),Os=h(),Tt=c("div"),xt=c("label"),Cl=g(Yn),Ms=h(),nt=c("select"),Ot=c("option"),Nl=g(Hn),Mt=c("option"),Dl=g(Xn),qt=c("option"),Ll=g(Qn),Us=h(),_t=c("div"),en=c("button"),Il=g(Zn),zs=h(),tn=c("button"),Rl=g($n),Ws=h(),nn=c("div"),Fs=g("v"),Tl=g(t[1]),s(n,"class","settings-title svelte-1pfl9w0"),s(u,"class","section-title svelte-1pfl9w0"),s(p,"class","setting-label svelte-1pfl9w0"),s(p,"for","cfg-server"),s(k,"id","cfg-server"),s(k,"type","text"),s(k,"placeholder","vps.example.com:8080"),s(k,"class","svelte-1pfl9w0"),s(A,"class","setting-row svelte-1pfl9w0"),s(I,"class","setting-label svelte-1pfl9w0"),s(I,"for","cfg-nick"),s(E,"id","cfg-nick"),s(E,"type","text"),s(E,"placeholder","Your nickname"),s(E,"class","svelte-1pfl9w0"),s(y,"class","setting-row svelte-1pfl9w0"),s(q,"class","setting-label svelte-1pfl9w0"),s(q,"for","cfg-token"),s(O,"id","cfg-token"),s(O,"type","password"),s(O,"placeholder",Y=t[7].server_token_desc),s(O,"class","svelte-1pfl9w0"),s(L,"class","setting-row svelte-1pfl9w0"),s(z,"class","hint reconnect-hint svelte-1pfl9w0"),s(pe,"class","setting-label svelte-1pfl9w0"),s(fe,"type","checkbox"),s(fe,"class","svelte-1pfl9w0"),s(ge,"class","toggle-label svelte-1pfl9w0"),s(H,"class","setting-row toggle-row svelte-1pfl9w0"),s(We,"class","setting-label svelte-1pfl9w0"),s(X,"type","checkbox"),s(X,"class","svelte-1pfl9w0"),s(st,"class","toggle-label svelte-1pfl9w0"),s(le,"class","setting-row toggle-row svelte-1pfl9w0"),s(d,"class","section svelte-1pfl9w0"),s(Ae,"class","section-title svelte-1pfl9w0"),s(Ee,"class","hint svelte-1pfl9w0"),s(ae,"class","setting-label svelte-1pfl9w0"),s(ae,"for","cfg-conn"),yt.__value="direct",ie(yt,yt.__value),jt.__value="relay",ie(jt,jt.__value),s(xe,"id","cfg-conn"),s(xe,"class","svelte-1pfl9w0"),t[0].connectionMode===void 0&&tl(()=>t[21].call(xe)),s($,"class","setting-row svelte-1pfl9w0"),s(vn,"class","hint svelte-1pfl9w0"),s(Yt,"class","setting-label svelte-1pfl9w0"),s(Yt,"for","cfg-mtu"),s(Ge,"id","cfg-mtu"),s(Ge,"type","number"),s(Ge,"min","576"),s(Ge,"max","9000"),s(Ge,"placeholder","1500"),s(Ge,"class","svelte-1pfl9w0"),s(St,"class","setting-row svelte-1pfl9w0"),s(gn,"class","hint svelte-1pfl9w0"),s(Ht,"class","setting-label svelte-1pfl9w0"),s(Ht,"for","cfg-dns"),s(et,"id","cfg-dns"),s(et,"type","text"),s(et,"placeholder","system default"),s(et,"class","svelte-1pfl9w0"),s(Et,"class","setting-row svelte-1pfl9w0"),s(bn,"class","hint svelte-1pfl9w0"),s(Xt,"class","setting-label svelte-1pfl9w0"),s(Xt,"for","cfg-socks"),s(He,"id","cfg-socks"),s(He,"type","text"),s(He,"placeholder",Sn=t[7].socks5_placeholder),s(He,"class","svelte-1pfl9w0"),s(At,"class","setting-row svelte-1pfl9w0"),s(En,"class","hint reconnect-hint svelte-1pfl9w0"),s(Qt,"class","setting-label svelte-1pfl9w0"),s(Qt,"for","cfg-stun"),s(tt,"id","cfg-stun"),s(tt,"type","text"),s(tt,"placeholder","stun.l.google.com:19302"),s(tt,"class","svelte-1pfl9w0"),s(Pt,"class","setting-row svelte-1pfl9w0"),s(Cn,"class","hint reconnect-hint svelte-1pfl9w0"),s(re,"class","section svelte-1pfl9w0"),s(Ct,"class","section-title svelte-1pfl9w0"),s(Ln,"class","setting-label svelte-1pfl9w0"),s(pt,"type","checkbox"),s(pt,"class","svelte-1pfl9w0"),s(Nt,"class","setting-row toggle-row svelte-1pfl9w0"),s(Rn,"class","setting-label svelte-1pfl9w0"),s(ct,"class","btn btn-check svelte-1pfl9w0"),s(ct,"type","button"),ct.disabled=t[3],s(ot,"class","setting-row update-row svelte-1pfl9w0"),s(Xe,"class","section svelte-1pfl9w0"),s(Dt,"class","section-title svelte-1pfl9w0"),s(Zt,"class","setting-label svelte-1pfl9w0"),s(Zt,"for","cfg-scale"),s(Qe,"id","cfg-scale"),s(Qe,"type","range"),s(Qe,"min","75"),s(Qe,"max","150"),s(Qe,"step","5"),Qe.value=Un=t[0].uiScale??100,s(Qe,"class","svelte-1pfl9w0"),s($t,"class","scale-value svelte-1pfl9w0"),s(ut,"class","setting-row scale-row svelte-1pfl9w0"),s(Wn,"class","hint svelte-1pfl9w0"),s(Kn,"class","setting-label svelte-1pfl9w0"),s(qe,"type","radio"),qe.__value="dark",ie(qe,qe.__value),s(It,"class","radio-option svelte-1pfl9w0"),s(Ue,"type","radio"),Ue.__value="light",ie(Ue,Ue.__value),s(Rt,"class","radio-option svelte-1pfl9w0"),s(at,"class","radio-group svelte-1pfl9w0"),s(at,"role","radiogroup"),s(at,"aria-label",Bn=t[7].theme),s(Lt,"class","setting-row radio-row svelte-1pfl9w0"),s(xt,"class","setting-label svelte-1pfl9w0"),s(xt,"for","cfg-lang"),Ot.__value="en",ie(Ot,Ot.__value),Mt.__value="ru",ie(Mt,Mt.__value),qt.__value="zh",ie(qt,qt.__value),s(nt,"id","cfg-lang"),s(nt,"class","svelte-1pfl9w0"),s(Tt,"class","setting-row svelte-1pfl9w0"),s(Ve,"class","section svelte-1pfl9w0"),s(en,"class","btn btn-save svelte-1pfl9w0"),s(tn,"class","btn btn-reset svelte-1pfl9w0"),s(nn,"class","ver svelte-1pfl9w0"),s(_t,"class","section actions-section svelte-1pfl9w0"),s(r,"class","settings-content svelte-1pfl9w0"),s(e,"class","settings-view svelte-1pfl9w0"),Ol.p(qe,Ue)},m(T,G){K(T,e,G),l(e,n),l(n,o),l(e,a),l(e,r),Te&&Te.m(r,null),l(r,_),l(r,d),l(d,u),l(u,v),l(u,m),l(u,j),l(d,w),l(d,A),l(A,p),l(p,D),l(A,P),l(A,k),ie(k,t[0].serverAddr),l(d,N),l(d,y),l(y,I),l(I,B),l(y,S),l(y,E),ie(E,t[0].nickname),l(d,M),l(d,L),l(L,q),l(q,Q),l(L,ce),l(L,O),ie(O,t[0].serverToken),l(d,U),l(d,z),l(z,oe),l(d,Z),l(d,H),l(H,pe),l(pe,Ie),l(H,Ne),l(H,fe),fe.checked=t[0].autoConnect,l(H,ye),l(H,ge),l(ge,De),l(d,me),l(d,le),l(le,We),l(We,he),l(le,be),l(le,X),X.checked=t[0].autoJoinLastRoom,l(le,se),l(le,st),l(st,rt),l(r,it),l(r,re),l(re,Ae),l(Ae,R),l(Ae,Se),l(Ae,Re),l(re,we),l(re,Ee),l(Ee,bt),l(re,Pe),l(re,$),l($,ae),l(ae,il),l($,xl),l($,xe),l(xe,yt),l(yt,ol),l(xe,jt),l(jt,al),xn(xe,t[0].connectionMode,!0),l(re,es),l(re,vn),l(vn,rl),l(re,ts),l(re,St),l(St,Yt),l(Yt,cl),l(St,ns),l(St,Ge),ie(Ge,t[0].mtu),l(re,ls),l(re,gn),l(gn,ul),l(re,ss),l(re,Et),l(Et,Ht),l(Ht,_l),l(Et,is),l(Et,et),ie(et,t[0].dnsServer),l(re,os),l(re,bn),l(bn,fl),l(re,as),l(re,At),l(At,Xt),l(Xt,dl),l(At,rs),l(At,He),ie(He,t[0].socks5Proxy),l(re,cs),l(re,En),l(En,pl),l(re,us),l(re,Pt),l(Pt,Qt),l(Qt,vl),l(Pt,_s),l(Pt,tt),ie(tt,t[0].stunServer),l(re,fs),l(re,Cn),l(Cn,ml),l(r,ds),l(r,Xe),l(Xe,Ct),l(Ct,ps),l(Ct,hl),l(Ct,vs),l(Xe,ms),l(Xe,Nt),l(Nt,Ln),l(Ln,gl),l(Nt,hs),l(Nt,pt),pt.checked=t[0].startWithWindows,l(Xe,gs),l(Xe,ot),l(ot,Rn),l(Rn,wl),l(ot,ws),l(ot,ct),l(ct,kl),l(ot,ks),Oe&&Oe.m(ot,null),l(Xe,bs),Me&&Me.m(Xe,null),l(r,ys),l(r,Ve),l(Ve,Dt),l(Dt,js),l(Dt,bl),l(Dt,Ss),l(Ve,Es),l(Ve,ut),l(ut,Zt),l(Zt,yl),l(ut,As),l(ut,Qe),l(ut,Ps),l(ut,$t),l($t,jl),l($t,Cs),l(Ve,Ns),l(Ve,Wn),l(Wn,Sl),l(Ve,Ds),l(Ve,Lt),l(Lt,Kn),l(Kn,El),l(Lt,Ls),l(Lt,at),l(at,It),l(It,qe),qe.checked=qe.__value===t[0].theme,l(It,Is),l(It,Al),l(at,Rs),l(at,Rt),l(Rt,Ue),Ue.checked=Ue.__value===t[0].theme,l(Rt,Ts),l(Rt,Pl),l(Ve,Os),l(Ve,Tt),l(Tt,xt),l(xt,Cl),l(Tt,Ms),l(Tt,nt),l(nt,Ot),l(Ot,Nl),l(nt,Mt),l(Mt,Dl),l(nt,qt),l(qt,Ll),xn(nt,t[0].lang||t[8]),l(r,Us),l(r,_t),l(_t,en),l(en,Il),l(_t,zs),l(_t,tn),l(tn,Rl),l(_t,Ws),l(_t,nn),l(nn,Fs),l(nn,Tl),Ml||(Ks=[W(k,"input",t[16]),W(E,"input",t[17]),W(O,"input",t[18]),W(fe,"change",t[19]),W(X,"change",t[20]),W(xe,"change",t[21]),W(Ge,"input",t[22]),W(et,"input",t[23]),W(He,"input",t[24]),W(tt,"input",t[25]),W(pt,"change",t[26]),W(ct,"click",t[9]),W(Qe,"input",t[13]),W(qe,"change",t[27]),W(qe,"change",t[15]),W(Ue,"change",t[29]),W(Ue,"change",t[15]),W(nt,"change",t[14]),W(en,"click",t[11]),W(tn,"click",t[12])],Ml=!0)},p(T,[G]){G&128&&i!==(i=T[7].settings_title+"")&&b(o,i),T[2]?Te?Te.p(T,G):(Te=Ci(T),Te.c(),Te.m(r,_)):Te&&(Te.d(1),Te=null),G&128&&f!==(f=T[7].section_connection+"")&&b(m,f),G&128&&C!==(C=T[7].server_addr+"")&&b(D,C),G&1&&k.value!==T[0].serverAddr&&ie(k,T[0].serverAddr),G&128&&J!==(J=T[7].nickname+"")&&b(B,J),G&1&&E.value!==T[0].nickname&&ie(E,T[0].nickname),G&128&&V!==(V=T[7].server_token+"")&&b(Q,V),G&128&&Y!==(Y=T[7].server_token_desc)&&s(O,"placeholder",Y),G&1&&O.value!==T[0].serverToken&&ie(O,T[0].serverToken),G&128&&te!==(te=T[7].reconnect_apply+"")&&b(oe,te),G&128&&ue!==(ue=T[7].auto_connect+"")&&b(Ie,ue),G&1&&(fe.checked=T[0].autoConnect),G&128&&je!==(je=T[7].auto_connect_desc+"")&&b(De,je),G&128&&_e!==(_e=T[7].auto_join+"")&&b(he,_e),G&1&&(X.checked=T[0].autoJoinLastRoom),G&128&&Fe!==(Fe=T[7].auto_join_desc+"")&&b(rt,Fe),G&128&&x!==(x=T[7].section_network+"")&&b(Se,x),G&128&&Ke!==(Ke=T[7].advanced_warn+"")&&b(bt,Ke),G&128&&Je!==(Je=T[7].connection_mode+"")&&b(il,Je),G&128&&dn!==(dn=T[7].connection_direct+"")&&b(ol,dn),G&128&&pn!==(pn=T[7].connection_relay+"")&&b(al,pn),G&1&&xn(xe,T[0].connectionMode),G&128&&mn!==(mn=T[7].connection_mode_desc+"")&&b(rl,mn),G&128&&hn!==(hn=T[7].mtu+"")&&b(cl,hn),G&1&&Oi(Ge.value)!==T[0].mtu&&ie(Ge,T[0].mtu),G&128&&wn!==(wn=T[7].mtu_desc+"")&&b(ul,wn),G&128&&kn!==(kn=T[7].dns_server+"")&&b(_l,kn),G&1&&et.value!==T[0].dnsServer&&ie(et,T[0].dnsServer),G&128&&yn!==(yn=T[7].dns_desc+"")&&b(fl,yn),G&128&&jn!==(jn=T[7].socks5+"")&&b(dl,jn),G&128&&Sn!==(Sn=T[7].socks5_placeholder)&&s(He,"placeholder",Sn),G&1&&He.value!==T[0].socks5Proxy&&ie(He,T[0].socks5Proxy),G&128&&An!==(An=T[7].socks5_desc+"")&&b(pl,An),G&128&&Pn!==(Pn=T[7].stun_server+"")&&b(vl,Pn),G&1&&tt.value!==T[0].stunServer&&ie(tt,T[0].stunServer),G&128&&Nn!==(Nn=T[7].stun_desc+"")&&b(ml,Nn),G&128&&Dn!==(Dn=T[7].section_system+"")&&b(hl,Dn),G&128&&In!==(In=T[7].start_windows+"")&&b(gl,In),G&1&&(pt.checked=T[0].startWithWindows),G&128&&Tn!==(Tn=T[7].updates+"")&&b(wl,Tn),G&128&&On!==(On=T[7].check_updates+"")&&b(kl,On),G&8&&(ct.disabled=T[3]),T[4]==="available"?Oe?Oe.p(T,G):(Oe=Ni(T),Oe.c(),Oe.m(ot,null)):Oe&&(Oe.d(1),Oe=null),Ut===(Ut=Js(T))&&Me?Me.p(T,G):(Me&&Me.d(1),Me=Ut&&Ut(T),Me&&(Me.c(),Me.m(Xe,null))),G&128&&Mn!==(Mn=T[7].section_appearance+"")&&b(bl,Mn),G&128&&qn!==(qn=T[7].ui_scale+"")&&b(yl,qn),G&1&&Un!==(Un=T[0].uiScale??100)&&(Qe.value=Un),G&1&&zn!==(zn=(T[0].uiScale??100)+"")&&b(jl,zn),G&128&&Fn!==(Fn=T[7].ui_scale_desc+"")&&b(Sl,Fn),G&128&&Jn!==(Jn=T[7].theme+"")&&b(El,Jn),G&1&&(qe.checked=qe.__value===T[0].theme),G&128&&Gn!==(Gn=T[7].theme_dark+"")&&b(Al,Gn),G&1&&(Ue.checked=Ue.__value===T[0].theme),G&128&&Vn!==(Vn=T[7].theme_light+"")&&b(Pl,Vn),G&128&&Bn!==(Bn=T[7].theme)&&s(at,"aria-label",Bn),G&128&&Yn!==(Yn=T[7].language+"")&&b(Cl,Yn),G&128&&Hn!==(Hn=T[7].language_en+"")&&b(Nl,Hn),G&128&&Xn!==(Xn=T[7].language_ru+"")&&b(Dl,Xn),G&128&&Qn!==(Qn=T[7].language_zh+"")&&b(Ll,Qn),G&257&&qs!==(qs=T[0].lang||T[8])&&xn(nt,T[0].lang||T[8]),G&128&&Zn!==(Zn=T[7].save+"")&&b(Il,Zn),G&128&&$n!==($n=T[7].reset+"")&&b(Rl,$n),G&2&&b(Tl,T[1])},i:de,o:de,d(T){T&&F(e),Te&&Te.d(),Oe&&Oe.d(),Me&&Me.d(),Ol.r(),Ml=!1,Le(Ks)}}}function Jo(t,e,n){let i,o,a;ve(t,Be,O=>n(30,i=O)),ve(t,kt,O=>n(7,o=O)),ve(t,$l,O=>n(8,a=O));let r={...i},_="1.0.0",d=!1,u=!1,v="",f="",m="";async function j(){n(3,u=!0),n(4,v="checking"),n(6,m=""),n(5,f="");try{const O=await window.go.main.App.CheckForUpdate();O?.available?(n(4,v="available"),n(5,f=O.latest||"")):n(4,v="latest")}catch(O){n(4,v="error"),n(6,m=String(O)),ee(o.error_update_check+O,"error")}finally{n(3,u=!1)}}async function w(){if(confirm(o.confirm_update)){n(3,u=!0),n(4,v="downloading"),n(6,m="");try{await window.go.main.App.ApplyUpdate(),ee(o.notif_updating,"info")}catch(O){n(4,v="error"),n(6,m=String(O)),n(3,u=!1),ee(o.error_update+O,"error")}}}async function A(){Ze(Be,i={...r},i);try{n(2,d=!!await window.go.main.App.SaveSettings(r)),r.lang&&sn(r.lang),ee(o.notif_settings_saved,"info"),d&&ee(o.notif_reconnect_required,"info")}catch(O){ee(o.error_save+O,"error")}}async function p(){if(confirm(o.confirm_reset))try{n(0,r=await window.go.main.App.ResetSettings()),Ze(Be,i={...r},i),n(2,d=!1),r.lang&&sn(r.lang),ee(o.notif_settings_saved,"info")}catch(O){ee(o.error_save+O,"error")}}function C(O){const Y=Math.min(150,Math.max(75,Number(O.target.value)||100));n(0,r.uiScale=Y,r),Ze(Be,i={...i,uiScale:Y},i)}function D(O){n(0,r.lang=O.target.value,r),sn(O.target.value)}function P(){Ze(Be,i={...i,theme:r.theme},i)}fn(async()=>{try{const O=await window.go.main.App.GetSettings();O&&(n(0,r={...r,...O}),r.connectionMode||n(0,r.connectionMode="direct",r),Ze(Be,i=r,i),r.lang&&sn(r.lang)),window.go.main.App.GetVersion&&n(1,_=await window.go.main.App.GetVersion())}catch{}});const k=[[]];function N(){r.serverAddr=this.value,n(0,r)}function y(){r.nickname=this.value,n(0,r)}function I(){r.serverToken=this.value,n(0,r)}function J(){r.autoConnect=this.checked,n(0,r)}function B(){r.autoJoinLastRoom=this.checked,n(0,r)}function S(){r.connectionMode=Ji(this),n(0,r)}function E(){r.mtu=Oi(this.value),n(0,r)}function M(){r.dnsServer=this.value,n(0,r)}function L(){r.socks5Proxy=this.value,n(0,r)}function q(){r.stunServer=this.value,n(0,r)}function V(){r.startWithWindows=this.checked,n(0,r)}function Q(){r.theme=this.__value,n(0,r)}function ce(){r.theme=this.__value,n(0,r)}return[r,_,d,u,v,f,m,o,a,j,w,A,p,C,D,P,N,y,I,J,B,S,E,M,L,q,V,Q,k,ce]}class Go extends wt{constructor(e){super(),gt(this,e,Jo,Ko,dt,{})}}function Di(t,e,n){const i=t.slice();return i[13]=e[n],i}function Vo(t){let e,n,i,o,a,r,_,d,u,v,f,m,j,w,A,p;o=new vo({});const C=[Qo,Xo,Ho,Yo],D=[];function P(k,N){return k[3]==="network"?0:k[3]==="chat"?1:k[3]==="settings"?2:3}return v=P(t),f=D[v]=C[v](t),j=new So({}),{c(){e=c("div"),n=c("div"),i=c("div"),Bt(o.$$.fragment),a=h(),r=c("div"),_=h(),d=c("main"),u=c("div"),f.c(),m=h(),Bt(j.$$.fragment),s(r,"class","drag-handle svelte-1hi7jen"),ke(r,"active",t[1]),s(i,"class","sidebar-wrapper svelte-1hi7jen"),Vs(i,"width",t[0]+"px"),s(u,"class","view-fade svelte-1hi7jen"),s(u,"key",t[3]),s(d,"class","main-area svelte-1hi7jen"),s(n,"class","layout svelte-1hi7jen"),s(e,"class","shell svelte-1hi7jen")},m(k,N){K(k,e,N),l(e,n),l(n,i),mt(o,i,null),l(i,a),l(i,r),l(n,_),l(n,d),l(d,u),D[v].m(u,null),l(e,m),mt(j,e,null),w=!0,A||(p=W(r,"mousedown",t[6]),A=!0)},p(k,N){(!w||N&2)&&ke(r,"active",k[1]),(!w||N&1)&&Vs(i,"width",k[0]+"px");let y=v;v=P(k),v===y?D[v].p(k,N):(Ui(),lt(D[y],1,1,()=>{D[y]=null}),zi(),f=D[v],f?f.p(k,N):(f=D[v]=C[v](k),f.c()),Ye(f,1),f.m(u,null)),(!w||N&8)&&s(u,"key",k[3])},i(k){w||(Ye(o.$$.fragment,k),Ye(f),Ye(j.$$.fragment,k),w=!0)},o(k){lt(o.$$.fragment,k),lt(f),lt(j.$$.fragment,k),w=!1},d(k){k&&F(e),ht(o),D[v].d(),ht(j),A=!1,p()}}}function Bo(t){let e,n,i,o;return i=new Lo({}),{c(){e=c("div"),n=c("div"),Bt(i.$$.fragment),s(n,"class","fullscreen-connect svelte-1hi7jen"),s(e,"class","shell connect-shell svelte-1hi7jen")},m(a,r){K(a,e,r),l(e,n),mt(i,n,null),o=!0},p:de,i(a){o||(Ye(i.$$.fragment,a),o=!0)},o(a){lt(i.$$.fragment,a),o=!1},d(a){a&&F(e),ht(i)}}}function Yo(t){let e,n,i;return{c(){e=c("div"),n=g("Unknown view: "),i=g(t[3]),s(e,"class","unknown-view svelte-1hi7jen")},m(o,a){K(o,e,a),l(e,n),l(e,i)},p(o,a){a&8&&b(i,o[3])},i:de,o:de,d(o){o&&F(e)}}}function Ho(t){let e,n;return e=new Go({}),{c(){Bt(e.$$.fragment)},m(i,o){mt(e,i,o),n=!0},p:de,i(i){n||(Ye(e.$$.fragment,i),n=!0)},o(i){lt(e.$$.fragment,i),n=!1},d(i){ht(e,i)}}}function Xo(t){let e,n;return e=new Mo({}),{c(){Bt(e.$$.fragment)},m(i,o){mt(e,i,o),n=!0},p:de,i(i){n||(Ye(e.$$.fragment,i),n=!0)},o(i){lt(e.$$.fragment,i),n=!1},d(i){ht(e,i)}}}function Qo(t){let e,n;return e=new bo({}),{c(){Bt(e.$$.fragment)},m(i,o){mt(e,i,o),n=!0},p:de,i(i){n||(Ye(e.$$.fragment,i),n=!0)},o(i){lt(e.$$.fragment,i),n=!1},d(i){ht(e,i)}}}function Li(t){let e,n,i=t[4].msg+"",o,a,r,_=t[2].dismiss_error+"",d,u,v,f;return{c(){e=c("div"),n=c("span"),o=g(i),a=h(),r=c("button"),d=g(_),s(n,"class","error-strip-msg svelte-1hi7jen"),s(r,"type","button"),s(r,"class","error-strip-dismiss svelte-1hi7jen"),s(r,"aria-label",u=t[2].dismiss_error),s(e,"class","error-strip svelte-1hi7jen"),s(e,"role","alert")},m(m,j){K(m,e,j),l(e,n),l(n,o),l(e,a),l(e,r),l(r,d),v||(f=W(r,"click",un),v=!0)},p(m,j){j&16&&i!==(i=m[4].msg+"")&&b(o,i),j&4&&_!==(_=m[2].dismiss_error+"")&&b(d,_),j&4&&u!==(u=m[2].dismiss_error)&&s(r,"aria-label",u)},d(m){m&&F(e),v=!1,f()}}}function Ii(t,e){let n,i,o=e[13].type==="error"?"!":">",a,r,_=e[13].msg+"",d,u,v;return{key:t,first:null,c(){n=c("div"),i=c("span"),a=g(o),r=h(),d=g(_),u=h(),s(i,"class","notif-icon svelte-1hi7jen"),s(n,"class",v="notification "+e[13].type+" svelte-1hi7jen"),s(n,"role","status"),this.first=n},m(f,m){K(f,n,m),l(n,i),l(i,a),l(n,r),l(n,d),l(n,u)},p(f,m){e=f,m&32&&o!==(o=e[13].type==="error"?"!":">")&&b(a,o),m&32&&_!==(_=e[13].msg+"")&&b(d,_),m&32&&v!==(v="notification "+e[13].type+" svelte-1hi7jen")&&s(n,"class",v)},d(f){f&&F(n)}}}function Zo(t){let e,n,i,o,a,r,_,d,u=[],v=new Map,f,m;const j=[Bo,Vo],w=[];function A(P,k){return P[3]==="connect"?0:1}a=A(t),r=w[a]=j[a](t);let p=t[4]&&Li(t),C=ft(t[5]);const D=P=>P[13].id;for(let P=0;P{w[N]=null}),zi(),r=w[a],r?r.p(P,k):(r=w[a]=j[a](P),r.c()),Ye(r,1),r.m(_.parentNode,_)),P[4]?p?p.p(P,k):(p=Li(P),p.c(),p.m(d.parentNode,d)):p&&(p.d(1),p=null),k&32&&(C=ft(P[5]),u=sl(u,k,D,1,P,C,v,f.parentNode,ll,Ii,f,Di))},i(P){m||(Ye(r),m=!0)},o(P){lt(r),m=!1},d(P){P&&(F(e),F(n),F(i),F(o),F(_),F(d),F(f)),w[a].d(P),p&&p.d(P);for(let k=0;kn(2,i=p)),ve(t,Be,p=>n(7,o=p)),ve(t,Ce,p=>n(3,a=p)),ve(t,nl,p=>n(4,r=p)),ve(t,Wl,p=>n(5,_=p));let d=220,u=!1,v,f,m=!0;function j(p){n(1,u=!0),v=p.clientX,f=d,document.addEventListener("mousemove",w),document.addEventListener("mouseup",A),p.preventDefault()}function w(p){if(!u)return;const C=f+(p.clientX-v);n(0,d=Math.max(140,Math.min(400,C)))}function A(){n(1,u=!1),document.removeEventListener("mousemove",w),document.removeEventListener("mouseup",A)}return fn(async()=>{window.addEventListener("keydown",Ri);try{const p=await window.go.main.App.LoadConfig();p&&(Be.set({...o,...p}),p.lang&&sn(p.lang))}catch{}window.runtime?.EventsOn&&(window.runtime.EventsOn("status_changed",p=>{m&&(ze.set(p),!p.connected&&!p.reconnecting&&Ce.set("connect"))}),window.runtime.EventsOn("peers_changed",p=>{m&&Yl.set(p||[])}),window.runtime.EventsOn("error",p=>{m&&ee(p,"error")}),window.runtime.EventsOn("chat_message",p=>{m&&Ql(p.fromID,p.nickname,p.message,!1,"sent",!1,!!p.isDM)}),window.runtime.EventsOn("system_chat",p=>{m&&lo(p.message||"")}),window.runtime.EventsOn("room_deleted",p=>{m&&(ee(i.notif_room_deleted,"error"),Ce.set("network"))}),window.runtime.EventsOn("auto_join_skipped",p=>{if(!m)return;const C=p?.room||"";ee(ne(i.notif_auto_join_skipped,{name:C}),"info")}))}),Mi(()=>{m=!1,window.removeEventListener("keydown",Ri),document.removeEventListener("mousemove",w),document.removeEventListener("mouseup",A),window.runtime?.EventsOff&&(window.runtime.EventsOff("status_changed"),window.runtime.EventsOff("peers_changed"),window.runtime.EventsOff("error"),window.runtime.EventsOff("chat_message"),window.runtime.EventsOff("system_chat"),window.runtime.EventsOff("room_deleted"),window.runtime.EventsOff("auto_join_skipped"))}),t.$$.update=()=>{if(t.$$.dirty&128){const p=$o(o.uiScale)/100;document.documentElement.style.zoom=String(p)}t.$$.dirty&128&&(o.theme==="light"?document.documentElement.classList.add("light-theme"):document.documentElement.classList.remove("light-theme"))},[d,u,i,a,r,_,j,o]}class ea extends wt{constructor(e){super(),gt(this,e,xo,Zo,dt,{})}}new ea({target:document.getElementById("app")}); diff --git a/client/frontend/dist/assets/index-Ciw-gyve.css b/client/frontend/dist/assets/index-Ciw-gyve.css new file mode 100644 index 0000000..d6d54a6 --- /dev/null +++ b/client/frontend/dist/assets/index-Ciw-gyve.css @@ -0,0 +1 @@ +.sidebar.svelte-a1nde2.svelte-a1nde2{width:100%;height:100%;background:var(--bg-surface);display:flex;flex-direction:column;flex-shrink:0}.sidebar-header.svelte-a1nde2.svelte-a1nde2{padding:12px;border-bottom:1px solid var(--border)}.sidebar-header.svelte-a1nde2 h2.svelte-a1nde2{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:var(--text-dim);font-weight:600}.sidebar-meta.svelte-a1nde2.svelte-a1nde2{font-size:var(--font-size-xs);color:var(--text-muted);margin-top:4px}.sidebar-actions.svelte-a1nde2.svelte-a1nde2{padding:8px;display:flex;flex-direction:column;gap:6px;border-bottom:1px solid var(--border)}.sidebar-actions.svelte-a1nde2 .btn.svelte-a1nde2{min-height:32px;padding:6px 12px}.network-list.svelte-a1nde2.svelte-a1nde2{flex:1;overflow-y:auto;overflow-x:hidden;padding:4px 0}.network-item.svelte-a1nde2.svelte-a1nde2{display:flex;align-items:center;padding:10px 12px;min-height:40px;cursor:pointer;gap:8px;border-bottom:1px solid var(--border-deep);transition:background .12s ease,opacity .12s ease;position:relative}.network-item.svelte-a1nde2.svelte-a1nde2:hover,.network-item.svelte-a1nde2.svelte-a1nde2:focus-visible{background:var(--bg-hover)}.network-item.active.svelte-a1nde2.svelte-a1nde2{background:var(--bg-active)}.network-item.disabled.svelte-a1nde2.svelte-a1nde2{opacity:.55}.network-indicator.svelte-a1nde2.svelte-a1nde2{width:8px;height:8px;border-radius:50%;background:var(--text-dim);flex-shrink:0}.network-indicator.active-dot.svelte-a1nde2.svelte-a1nde2{background:var(--text-bright)}.network-info.svelte-a1nde2.svelte-a1nde2{flex:1;min-width:0}.network-name.svelte-a1nde2.svelte-a1nde2{font-size:var(--font-size);color:var(--text-bright);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.network-meta.svelte-a1nde2.svelte-a1nde2{font-size:var(--font-size-xs);color:var(--text-secondary);line-height:1.4}.row-actions.svelte-a1nde2.svelte-a1nde2{position:relative;flex-shrink:0}.menu-btn.svelte-a1nde2.svelte-a1nde2{background:none;border:1px solid transparent;border-radius:var(--radius-sm, 4px);color:var(--text-muted);cursor:pointer;width:32px;height:32px;display:flex;align-items:center;justify-content:center}.menu-btn.svelte-a1nde2.svelte-a1nde2:hover,.menu-btn[aria-expanded=true].svelte-a1nde2.svelte-a1nde2{color:var(--text-bright);border-color:var(--border);background:var(--bg-raised)}.overflow-menu.svelte-a1nde2.svelte-a1nde2{position:absolute;right:0;top:100%;z-index:20;min-width:160px;background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius-md, 6px);display:flex;flex-direction:column;box-shadow:0 4px 12px #00000059}.menu-item.svelte-a1nde2.svelte-a1nde2{background:none;border:none;text-align:left;padding:10px 12px;min-height:36px;color:var(--text-primary);font-family:inherit;font-size:var(--font-size-sm);cursor:pointer}.menu-item.svelte-a1nde2.svelte-a1nde2:hover{background:var(--bg-hover);color:var(--text-bright)}.menu-item.danger.svelte-a1nde2.svelte-a1nde2{color:var(--fault, var(--error))}.menu-item.danger.svelte-a1nde2.svelte-a1nde2:hover{background:#e23d3d1a}.empty-desc.svelte-a1nde2.svelte-a1nde2{margin-top:6px;font-size:var(--font-size-xs);color:var(--text-dim)}.empty-state.svelte-a1nde2.svelte-a1nde2{padding:16px;text-align:center;color:var(--text-muted);font-size:var(--font-size-sm)}.sidebar-footer.svelte-a1nde2.svelte-a1nde2{padding:8px;border-top:1px solid var(--border)}.settings-btn.svelte-a1nde2.svelte-a1nde2{width:100%;min-height:32px}.modal-overlay.svelte-a1nde2.svelte-a1nde2{position:fixed;inset:0;background:#000000b3;display:flex;align-items:center;justify-content:center;z-index:100;animation:svelte-a1nde2-fadeIn .12s ease-out}@keyframes svelte-a1nde2-fadeIn{0%{opacity:0}to{opacity:1}}.modal.svelte-a1nde2.svelte-a1nde2{background:var(--bg-surface);border:1px solid var(--border);border-radius:var(--radius-md, 6px);padding:20px;width:320px;max-height:80vh;overflow-y:auto;display:flex;flex-direction:column;gap:10px}.modal.svelte-a1nde2 h3.svelte-a1nde2{font-size:var(--font-size);color:var(--text-bright);font-weight:600;text-transform:uppercase;letter-spacing:.08em;font-size:10px}.modal.svelte-a1nde2 input.svelte-a1nde2{padding:10px;min-height:36px;border:1px solid var(--border);border-radius:var(--radius-sm, 4px);background:var(--bg-primary);color:var(--text-primary);font-size:var(--font-size);font-family:var(--font-mono)}.modal.svelte-a1nde2 input.invalid.svelte-a1nde2{border-color:var(--error)}.field-error.svelte-a1nde2.svelte-a1nde2,.modal-error.svelte-a1nde2.svelte-a1nde2{font-size:var(--font-size-xs);color:var(--error)}.modal-error.svelte-a1nde2.svelte-a1nde2{padding:8px;border:1px solid var(--error);background:#c45c5c14}.modal-actions.svelte-a1nde2.svelte-a1nde2{display:flex;gap:6px;justify-content:flex-end}.modal-actions.svelte-a1nde2 .btn.svelte-a1nde2{min-height:32px;padding:6px 12px}.sr-only.svelte-a1nde2.svelte-a1nde2{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.peer-view.svelte-ji2phz.svelte-ji2phz{display:flex;flex-direction:column;height:100%}.peer-header.svelte-ji2phz.svelte-ji2phz{padding:12px 16px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px;background:var(--bg-surface);flex-wrap:wrap}.peer-header.svelte-ji2phz h2.svelte-ji2phz{font-size:10px;font-weight:600;color:var(--text-dim);text-transform:uppercase;letter-spacing:.08em}.room-chat-btn.svelte-ji2phz.svelte-ji2phz{margin-left:auto;background:transparent;border:1px solid var(--border);border-radius:var(--radius-md, 6px);color:var(--text-secondary);font-family:inherit;font-size:var(--font-size-xs);padding:6px 10px;min-height:32px;cursor:pointer;position:relative}.room-chat-btn.svelte-ji2phz.svelte-ji2phz:hover{color:var(--text-bright);border-color:var(--border-hover)}.badge.svelte-ji2phz.svelte-ji2phz{display:inline-block;min-width:14px;padding:0 4px;margin-left:4px;background:var(--fault, var(--error));color:#fff;font-size:10px;line-height:14px;text-align:center}.peer-table.svelte-ji2phz.svelte-ji2phz{flex:1;overflow:auto;min-height:0;min-width:0}.table-row.svelte-ji2phz.svelte-ji2phz{display:grid;grid-template-columns:minmax(56px,72px) minmax(72px,1fr) minmax(88px,110px) minmax(48px,70px) minmax(72px,96px) minmax(64px,80px);gap:8px;align-items:center;padding:10px 16px;min-height:40px;border-bottom:1px solid var(--border-deep);font-size:var(--font-size-sm);min-width:520px}.table-header-row.svelte-ji2phz.svelte-ji2phz{color:var(--text-muted);text-transform:uppercase;font-size:var(--font-size-xs);letter-spacing:.08em}.self-row.svelte-ji2phz.svelte-ji2phz{background:var(--bg-surface)}.nickname.svelte-ji2phz.svelte-ji2phz{color:var(--text-bright);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.self-tag.svelte-ji2phz.svelte-ji2phz{margin-left:6px;font-size:var(--font-size-xs);color:var(--text-muted)}.col-ip.svelte-ji2phz.svelte-ji2phz,.col-ping.svelte-ji2phz.svelte-ji2phz,.col-path.svelte-ji2phz.svelte-ji2phz{font-family:var(--font-mono);color:var(--text-secondary)}.col-path.svelte-ji2phz.svelte-ji2phz{display:flex;align-items:center;gap:6px}.col-ping.probing.svelte-ji2phz.svelte-ji2phz{color:var(--text-bright)}.clickable.svelte-ji2phz.svelte-ji2phz{cursor:pointer}.clickable.svelte-ji2phz.svelte-ji2phz:hover{color:var(--text-bright)}.status-cell.svelte-ji2phz.svelte-ji2phz{display:flex;align-items:center;gap:6px}.status-text.svelte-ji2phz.svelte-ji2phz{font-size:var(--font-size-xs);color:var(--text-secondary)}.sq.svelte-ji2phz.svelte-ji2phz{width:8px;height:8px;border-radius:50%;display:inline-block;flex-shrink:0}.sq-online.svelte-ji2phz.svelte-ji2phz{background:var(--text-bright)}.sq-offline.svelte-ji2phz.svelte-ji2phz{background:var(--text-dim)}.col-action.svelte-ji2phz.svelte-ji2phz{display:flex;gap:2px;justify-content:flex-end}.row-btn.svelte-ji2phz.svelte-ji2phz{background:transparent;border:none;border-radius:var(--radius-sm, 4px);color:var(--text-muted);cursor:pointer;min-width:32px;min-height:32px;padding:0;display:flex;align-items:center;justify-content:center}.row-btn.svelte-ji2phz.svelte-ji2phz:hover:not(:disabled){color:var(--text-bright)}.row-btn.svelte-ji2phz.svelte-ji2phz:disabled{opacity:.35;cursor:not-allowed}.empty-peers.svelte-ji2phz.svelte-ji2phz{padding:48px 24px;text-align:center;color:var(--text-muted)}.empty-label.svelte-ji2phz.svelte-ji2phz{color:var(--text-secondary);margin:8px 0 4px}.empty-desc.svelte-ji2phz.svelte-ji2phz{font-size:var(--font-size-xs)}.statusbar.svelte-3s78ew{min-height:var(--statusbar-height);background:var(--bg-deep);border-top:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;gap:12px;padding:4px 12px;font-size:var(--font-size-xs);color:var(--text-secondary);flex-shrink:0;font-family:var(--font-mono);z-index:1;position:relative;min-width:0}.status-left.svelte-3s78ew,.status-right.svelte-3s78ew{display:flex;align-items:center;gap:8px 14px;min-width:0}.status-right.svelte-3s78ew{flex:1 1 auto;justify-content:flex-end}.status-item.svelte-3s78ew{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:36ch}.status-server.svelte-3s78ew{max-width:28ch}.status-ver.svelte-3s78ew{flex-shrink:0;max-width:none}.hint-fault.svelte-3s78ew{color:var(--fault, var(--error))}.connect-view.svelte-1br9j49.svelte-1br9j49{display:flex;align-items:center;justify-content:center;width:100%;height:100%;padding:32px 24px}.connect-form.svelte-1br9j49.svelte-1br9j49,.connected-info.svelte-1br9j49.svelte-1br9j49{width:min(360px,100%);display:flex;flex-direction:column;gap:16px;animation:svelte-1br9j49-connectIn .45s cubic-bezier(.16,1,.3,1) both}@keyframes svelte-1br9j49-connectIn{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}.brand-block.svelte-1br9j49.svelte-1br9j49{text-align:center;margin-bottom:12px}.brand.svelte-1br9j49.svelte-1br9j49{font-family:var(--font-display);font-size:clamp(36px,7vw,48px);font-weight:400;letter-spacing:.02em;text-transform:uppercase;color:var(--text-bright);line-height:1.05}.tagline.svelte-1br9j49.svelte-1br9j49{margin-top:10px;font-size:var(--font-size-sm);color:var(--text-secondary);text-transform:none;letter-spacing:.02em;line-height:1.45}.field.svelte-1br9j49.svelte-1br9j49{display:flex;flex-direction:column;gap:7px}label.svelte-1br9j49.svelte-1br9j49{font-size:var(--font-size-xs);color:var(--text-secondary);text-transform:uppercase;letter-spacing:.08em}input.svelte-1br9j49.svelte-1br9j49{background:#111111d9;border:1px solid var(--border-light);color:var(--text-bright);padding:13px 14px;min-height:44px;font-family:var(--font-mono);font-size:var(--font-size);transition:border-color .15s ease,background .15s ease}input.svelte-1br9j49.svelte-1br9j49::placeholder{color:var(--text-dim)}input.svelte-1br9j49.svelte-1br9j49:hover:not(:disabled){border-color:var(--border-hover)}input.svelte-1br9j49.svelte-1br9j49:focus{outline:none;border-color:var(--text-bright);background:#141414f2}input.invalid.svelte-1br9j49.svelte-1br9j49{border-color:var(--error)}.field-error.svelte-1br9j49.svelte-1br9j49{font-size:var(--font-size-xs);color:var(--error)}.connect-btn.svelte-1br9j49.svelte-1br9j49,.disconnect-btn.svelte-1br9j49.svelte-1br9j49,.secondary-btn.svelte-1br9j49.svelte-1br9j49{border:none;padding:15px 18px;min-height:48px;font-family:var(--font-mono);font-size:var(--font-size);cursor:pointer;text-transform:uppercase;letter-spacing:.12em;font-weight:600;transition:background .15s ease,border-color .15s ease,transform .12s ease}.connect-btn.svelte-1br9j49.svelte-1br9j49{margin-top:4px;background:var(--accent);color:var(--accent-ink)}.connect-btn.svelte-1br9j49.svelte-1br9j49:hover:not(:disabled){background:var(--accent-hover);transform:translateY(-1px)}.connect-btn.svelte-1br9j49.svelte-1br9j49:active:not(:disabled){transform:translateY(0)}.connect-btn.svelte-1br9j49.svelte-1br9j49:disabled{opacity:.45;cursor:not-allowed;transform:none}.secondary-btn.svelte-1br9j49.svelte-1br9j49{background:transparent;color:var(--text-primary);border:1px solid var(--border-light);font-weight:500;letter-spacing:.08em}.secondary-btn.svelte-1br9j49.svelte-1br9j49:hover:not(:disabled){border-color:var(--accent);color:var(--text-bright)}.disconnect-btn.svelte-1br9j49.svelte-1br9j49{background:transparent;color:var(--error);border:1px solid var(--error);font-weight:500}.phase.svelte-1br9j49.svelte-1br9j49{font-size:var(--font-size-xs);color:var(--text-muted);text-align:center;letter-spacing:.04em}.invite-disclosure.svelte-1br9j49.svelte-1br9j49{margin-top:8px;border-top:1px solid var(--border);padding-top:14px}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49{cursor:pointer;color:var(--text-muted);font-size:var(--font-size-sm);list-style:none;min-height:36px;display:flex;align-items:center;justify-content:center;transition:color .15s ease}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49:hover{color:var(--text-secondary)}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49::-webkit-details-marker{display:none}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49:before{content:"+";margin-right:8px;color:var(--text-dim)}.invite-disclosure[open].svelte-1br9j49 summary.svelte-1br9j49:before{content:"−"}.invite-block.svelte-1br9j49.svelte-1br9j49{display:flex;flex-direction:column;gap:10px;margin-top:12px}.connected-line.svelte-1br9j49.svelte-1br9j49{display:flex;align-items:center;gap:8px;color:var(--text-bright)}.info-line.svelte-1br9j49.svelte-1br9j49{display:flex;justify-content:space-between;font-size:var(--font-size-sm);color:var(--text-secondary)}.info-value.svelte-1br9j49.svelte-1br9j49{color:var(--text-primary);font-family:var(--font-mono)}.sq.svelte-1br9j49.svelte-1br9j49{width:8px;height:8px;display:inline-block}.sq-green.svelte-1br9j49.svelte-1br9j49{background:var(--success)}.sq-warn.svelte-1br9j49.svelte-1br9j49{background:var(--warning)}.sr-only.svelte-1br9j49.svelte-1br9j49{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.light-theme input.svelte-1br9j49.svelte-1br9j49{background:#ffffffa6}.light-theme input.svelte-1br9j49.svelte-1br9j49:focus{background:#ffffffe6}.chat-view.svelte-dxth9d.svelte-dxth9d{display:flex;flex-direction:column;height:100%}.chat-header.svelte-dxth9d.svelte-dxth9d{display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid var(--border);background:var(--bg-surface)}.back-btn.svelte-dxth9d.svelte-dxth9d{width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:transparent;border:1px solid var(--border);border-radius:var(--radius-sm, 4px);color:var(--text-secondary);cursor:pointer}.chat-title.svelte-dxth9d.svelte-dxth9d{color:var(--text-bright);font-size:var(--font-size)}.chat-messages.svelte-dxth9d.svelte-dxth9d{flex:1;overflow-y:auto;padding:16px;min-height:0}.empty-chat.svelte-dxth9d.svelte-dxth9d{text-align:center;padding:40px 16px;color:var(--text-muted)}.empty-chat-label.svelte-dxth9d.svelte-dxth9d{color:var(--text-secondary);margin:8px 0 4px}.empty-chat-desc.svelte-dxth9d.svelte-dxth9d{font-size:var(--font-size-xs)}.date-sep.svelte-dxth9d.svelte-dxth9d{text-align:center;font-size:var(--font-size-xs);color:var(--text-dim);margin:12px 0}.system-line.svelte-dxth9d.svelte-dxth9d{text-align:center;font-size:var(--font-size-xs);color:var(--text-muted);margin:8px 0}.msg.svelte-dxth9d.svelte-dxth9d{margin-bottom:10px;max-width:80%}.msg.self.svelte-dxth9d.svelte-dxth9d{margin-left:auto;text-align:right}.msg-meta.svelte-dxth9d.svelte-dxth9d{font-size:var(--font-size-xs);color:var(--text-muted);margin-bottom:2px}.msg-body.svelte-dxth9d.svelte-dxth9d{display:inline-block;padding:8px 10px;background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius-sm, 4px);color:var(--text-primary);white-space:pre-wrap;word-break:break-word;text-align:left}.msg.self.svelte-dxth9d .msg-body.svelte-dxth9d{background:var(--bg-active)}.retry-btn.svelte-dxth9d.svelte-dxth9d{margin-left:6px;background:transparent;border:none;color:var(--error);cursor:pointer;font-size:var(--font-size-xs)}.chat-input-area.svelte-dxth9d.svelte-dxth9d{display:flex;gap:8px;padding:12px 16px;border-top:1px solid var(--border);background:var(--bg-surface)}textarea.svelte-dxth9d.svelte-dxth9d{flex:1;resize:none;background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius-sm, 4px);color:var(--text-primary);padding:8px 10px;font-family:inherit;font-size:var(--font-size);min-height:36px}textarea.svelte-dxth9d.svelte-dxth9d:disabled{opacity:.5}.send-btn.svelte-dxth9d.svelte-dxth9d{background:var(--accent);color:var(--accent-ink);border:none;border-radius:var(--radius-md, 6px);padding:0 16px;cursor:pointer;font-family:inherit;text-transform:uppercase}.send-btn.svelte-dxth9d.svelte-dxth9d:disabled{opacity:.4;cursor:not-allowed}.settings-view.svelte-51kqlv.svelte-51kqlv{display:flex;flex-direction:column;height:100%;padding:24px 32px}.settings-content.svelte-51kqlv.svelte-51kqlv{flex:1;overflow-y:auto;min-height:0;height:0}.settings-title.svelte-51kqlv.svelte-51kqlv{font-size:10px;font-weight:600;color:var(--text-dim);text-transform:uppercase;letter-spacing:.08em;margin-bottom:20px}.reconnect-banner.svelte-51kqlv.svelte-51kqlv{background:var(--bg-raised);border:1px solid var(--border-hover);color:var(--text-bright);padding:10px 12px;margin-bottom:16px;font-size:var(--font-size-sm)}.section.svelte-51kqlv.svelte-51kqlv{margin-bottom:24px}.section-title.svelte-51kqlv.svelte-51kqlv{font-size:10px;font-weight:600;color:var(--text-dim);letter-spacing:.08em;text-transform:uppercase;margin-bottom:10px}.hint.svelte-51kqlv.svelte-51kqlv{font-size:var(--font-size-xs);color:var(--text-muted);margin:6px 0 12px;line-height:1.4}.reconnect-hint.svelte-51kqlv.svelte-51kqlv{color:var(--text-secondary)}.setting-row.svelte-51kqlv.svelte-51kqlv{display:flex;align-items:center;gap:12px;margin-bottom:10px;min-height:32px}.setting-label.svelte-51kqlv.svelte-51kqlv{min-width:140px;color:var(--text-secondary);font-size:var(--font-size-sm)}.toggle-label.svelte-51kqlv.svelte-51kqlv{color:var(--text-muted);font-size:var(--font-size-xs)}input[type=text].svelte-51kqlv.svelte-51kqlv,input[type=password].svelte-51kqlv.svelte-51kqlv,input[type=number].svelte-51kqlv.svelte-51kqlv,select.svelte-51kqlv.svelte-51kqlv{flex:1;background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius-sm, 4px);color:var(--text-primary);padding:8px 10px;min-height:32px;font-family:var(--font-mono);font-size:var(--font-size-sm)}input[type=checkbox].svelte-51kqlv.svelte-51kqlv{width:18px;height:18px}.radio-group.svelte-51kqlv.svelte-51kqlv{display:flex;gap:12px}.radio-option.svelte-51kqlv.svelte-51kqlv{display:flex;align-items:center;gap:6px;color:var(--text-secondary);font-size:var(--font-size-sm);min-height:32px}.scale-row.svelte-51kqlv input[type=range].svelte-51kqlv{flex:1;min-width:120px;accent-color:var(--accent)}.scale-value.svelte-51kqlv.svelte-51kqlv{min-width:44px;text-align:right;color:var(--text-secondary);font-size:var(--font-size-sm);font-family:var(--font-mono)}.actions-section.svelte-51kqlv.svelte-51kqlv{display:flex;gap:8px;align-items:center}.actions-section.svelte-51kqlv .btn.svelte-51kqlv{min-height:32px;padding:6px 12px}.update-row.svelte-51kqlv.svelte-51kqlv{flex-wrap:wrap}.update-row.svelte-51kqlv .btn.svelte-51kqlv{min-height:32px;padding:6px 12px}.btn-check.svelte-51kqlv.svelte-51kqlv,.btn-update.svelte-51kqlv.svelte-51kqlv{background:var(--bg-raised);border:1px solid var(--border);color:var(--text-primary);font-family:var(--font-mono);font-size:var(--font-size-sm);cursor:pointer}.btn-check.svelte-51kqlv.svelte-51kqlv:hover:not(:disabled),.btn-update.svelte-51kqlv.svelte-51kqlv:hover:not(:disabled){border-color:var(--border-hover);color:var(--text-bright)}.btn-check.svelte-51kqlv.svelte-51kqlv:disabled,.btn-update.svelte-51kqlv.svelte-51kqlv:disabled{opacity:.5;cursor:default}.ver.svelte-51kqlv.svelte-51kqlv{margin-left:auto;color:var(--text-dim);font-size:var(--font-size-xs)}.band.svelte-s9thm6{display:flex;align-items:center;gap:16px;padding:8px 12px;min-height:48px;background:var(--bg-surface);border-bottom:1px solid var(--border);flex-shrink:0}.wordmark.svelte-s9thm6{font-size:13px;font-weight:600;letter-spacing:.04em;color:var(--text-bright);flex-shrink:0}.facts.svelte-s9thm6{display:flex;flex-wrap:wrap;align-items:center;gap:16px 20px;flex:1;min-width:0}.fact.svelte-s9thm6{display:flex;flex-direction:column;gap:2px;min-width:0}.cap.svelte-s9thm6{font-size:10px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--text-dim)}.val.svelte-s9thm6{color:var(--text-bright);font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:28ch}.mono.svelte-s9thm6{font-family:var(--font-mono);font-weight:500}.vip.svelte-s9thm6{background:none;border:none;padding:0;text-align:left;cursor:pointer;color:var(--text-bright)}.vip.svelte-s9thm6:hover{text-decoration:underline}.path-row.svelte-s9thm6{display:flex;align-items:center;gap:6px}.actions.svelte-s9thm6{display:flex;gap:8px;flex-shrink:0;margin-left:auto}.shell.svelte-rf9j86{display:flex;flex-direction:column;height:100%;width:100%;position:relative;z-index:1;min-height:0}.connect-shell.svelte-rf9j86{z-index:1}.connected-shell.svelte-rf9j86{background:var(--bg-primary)}.layout.svelte-rf9j86{display:flex;flex:1;min-height:0;position:relative}.fullscreen-connect.svelte-rf9j86{display:flex;flex:1;width:100%;align-items:center;justify-content:center;min-height:0}.sidebar-wrapper.svelte-rf9j86{position:relative;flex-shrink:0;background:var(--bg-surface);border-right:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden;min-height:0}.drag-handle.svelte-rf9j86{position:absolute;top:0;right:-3px;width:6px;height:100%;cursor:col-resize;z-index:10;background:transparent;transition:background .1s}.drag-handle.svelte-rf9j86:hover,.drag-handle.active.svelte-rf9j86,.drag-handle.svelte-rf9j86:focus-visible{background:var(--border-hover)}.main-area.svelte-rf9j86{flex:1;display:flex;flex-direction:column;overflow:hidden;background:var(--bg-primary);min-width:0;min-height:0}.view-fade.svelte-rf9j86{flex:1;display:flex;flex-direction:column;min-height:0;min-width:0;animation:svelte-rf9j86-viewIn .2s ease-out}@keyframes svelte-rf9j86-viewIn{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.unknown-view.svelte-rf9j86{padding:40px;color:var(--text-muted)}.error-strip.svelte-rf9j86{position:fixed;left:12px;right:12px;bottom:calc(var(--statusbar-height) + 12px);z-index:1100;display:flex;align-items:center;gap:12px;padding:10px 14px;background:var(--bg-raised);border:1px solid var(--error);color:var(--error);font-size:var(--font-size-sm)}.error-strip-msg.svelte-rf9j86{flex:1;min-width:0;word-break:break-word}.error-strip-dismiss.svelte-rf9j86{flex-shrink:0;min-height:32px;padding:4px 10px;border:1px solid var(--error);background:transparent;color:var(--error);cursor:pointer;font-family:var(--font-mono);font-size:var(--font-size-xs);text-transform:uppercase}.error-strip-dismiss.svelte-rf9j86:hover{background:#c45c5c1f}.notification.svelte-rf9j86{position:fixed;top:12px;right:12px;padding:6px 12px;font-size:var(--font-size-sm);z-index:1000;background:var(--bg-raised);border:1px solid var(--border);color:var(--text-primary);animation:svelte-rf9j86-slideIn .15s ease-out}.notification.error.svelte-rf9j86{border-color:var(--error);color:var(--error)}.notification.info.svelte-rf9j86{border-color:var(--border)}.notif-icon.svelte-rf9j86{margin-right:6px;font-weight:700}@keyframes svelte-rf9j86-slideIn{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}.space-bg,.space-bg:before,.space-bg:after,.space-dust,.space-dust:before{position:fixed;pointer-events:none;z-index:0}.space-bg{inset:0;background:radial-gradient(ellipse 85% 65% at 50% 36%,rgba(255,255,255,.045) 0%,transparent 55%),radial-gradient(ellipse 120% 80% at 50% 100%,rgba(255,255,255,.03) 0%,transparent 50%),radial-gradient(ellipse 100% 100% at 50% 50%,#0a0a0a,#050505 70%,#000)}.space-bg:before{content:"";position:absolute;inset:0;opacity:.8;background:radial-gradient(1.2px 1.2px at 5% 10%,rgba(255,255,255,.55) 0%,transparent 100%),radial-gradient(1px 1px at 12% 32%,rgba(255,255,255,.35) 0%,transparent 100%),radial-gradient(1px 1px at 18% 68%,rgba(255,255,255,.32) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 25% 45%,rgba(255,255,255,.5) 0%,transparent 100%),radial-gradient(1px 1px at 32% 18%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1px 1px at 38% 78%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 45% 15%,rgba(255,255,255,.5) 0%,transparent 100%),radial-gradient(1px 1px at 52% 58%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1px 1px at 58% 28%,rgba(255,255,255,.26) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 65% 10%,rgba(255,255,255,.5) 0%,transparent 100%),radial-gradient(1px 1px at 72% 72%,rgba(255,255,255,.35) 0%,transparent 100%),radial-gradient(1px 1px at 78% 40%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 85% 65%,rgba(255,255,255,.48) 0%,transparent 100%),radial-gradient(1px 1px at 90% 22%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1px 1px at 94% 88%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(1px 1px at 8% 88%,rgba(255,255,255,.26) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 30% 92%,rgba(255,255,255,.4) 0%,transparent 100%),radial-gradient(1px 1px at 48% 42%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(1px 1px at 62% 88%,rgba(255,255,255,.32) 0%,transparent 100%),radial-gradient(1px 1px at 88% 52%,rgba(255,255,255,.26) 0%,transparent 100%)}.space-bg:after{content:"";position:absolute;inset:0;background-image:radial-gradient(1.5px 1.5px at 8% 18%,rgba(255,255,255,.7) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 48% 38%,rgba(255,255,255,.6) 0%,transparent 100%),radial-gradient(1.5px 1.5px at 88% 28%,rgba(255,255,255,.65) 0%,transparent 100%),radial-gradient(1px 1px at 22% 55%,rgba(255,255,255,.45) 0%,transparent 100%),radial-gradient(1px 1px at 70% 60%,rgba(255,255,255,.4) 0%,transparent 100%);animation:twinkle 9s ease-in-out infinite alternate;opacity:.5}@keyframes twinkle{0%{opacity:.2}45%{opacity:.5}to{opacity:.25}}.space-dust{inset:0;background:radial-gradient(ellipse 80% 70% at 50% 45%,transparent 42%,rgba(0,0,0,.62) 100%);opacity:1}.space-dust:before{content:"";position:absolute;inset:0;opacity:.32;background:radial-gradient(.5px .5px at 20% 30%,rgba(255,255,255,.4) 0%,transparent 100%),radial-gradient(.5px .5px at 40% 60%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(.5px .5px at 60% 25%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(.5px .5px at 75% 70%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(.5px .5px at 88% 40%,rgba(255,255,255,.3) 0%,transparent 100%)}.light-theme .space-bg,.light-theme .space-bg:before,.light-theme .space-bg:after,.light-theme .space-dust,.light-theme .space-dust:before{display:none!important}html[data-app=connected]{--bg-deep: #0a0a0a;--bg-primary: #0a0a0a;--bg-surface: #111111;--bg-raised: #181818;--bg-hover: #1c1c1c;--bg-active: #222222;--border-deep: #1a1a1a;--border: #2a2a2a;--border-light: #3a3a3a;--border-hover: #4a4a4a;--text-bright: #f0f0f0;--text-primary: #f0f0f0;--text-secondary: #8a8a8a;--text-muted: #8a8a8a;--text-dim: #5c5c5c;--accent: #ffffff;--accent-hover: #f0f0f0;--accent-ink: #0a0a0a;--live: #2fbf62;--fault: #e23d3d;--success: #8a8a8a;--warning: #8a8a8a;--error: #e23d3d;--focus-ring: #f0f0f0;--font-sans: ui-sans-serif, "Segoe UI", system-ui, sans-serif;--font-mono: ui-monospace, "Cascadia Code", Consolas, monospace;--font-size: 13px;--font-size-sm: 12px;--font-size-xs: 10px;--line-height: 1.45;--radius-sm: 4px;--radius-md: 6px;--statusbar-height: 26px}html[data-app=connected].light-theme{--bg-deep: #f5f5f5;--bg-primary: #f5f5f5;--bg-surface: #ececec;--bg-raised: #e4e4e4;--bg-hover: #dedede;--bg-active: #d6d6d6;--border-deep: #e0e0e0;--border: #d0d0d0;--border-light: #c4c4c4;--border-hover: #999999;--text-bright: #111111;--text-primary: #111111;--text-secondary: #5c5c5c;--text-muted: #6a6a6a;--text-dim: #8a8a8a;--accent: #111111;--accent-hover: #000000;--accent-ink: #f5f5f5;--live: #1a8f45;--fault: #c41e1e;--success: #6a6a6a;--warning: #6a6a6a;--error: #c41e1e;--focus-ring: #111111}html[data-app=connected],html[data-app=connected] body,html[data-app=connected] #app{color:var(--text-primary);font-family:var(--font-sans);font-size:var(--font-size);line-height:var(--line-height);background:var(--bg-deep)}html[data-app=connected] input,html[data-app=connected] textarea,html[data-app=connected] button,html[data-app=connected] select{font-family:inherit}html[data-app=connected] .btn{padding:6px 12px;min-height:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-md);background:transparent;color:var(--text-primary);cursor:pointer;font-size:var(--font-size-sm);text-align:center;font-family:var(--font-sans);transition:background .12s ease,border-color .12s ease,opacity .12s ease}html[data-app=connected] .btn:hover:not(:disabled){background:var(--bg-hover);border-color:var(--border-hover)}html[data-app=connected] .btn.primary,html[data-app=connected] .btn-save{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:500}html[data-app=connected] .btn.primary:hover,html[data-app=connected] .btn-save:hover{background:var(--accent-hover)}html[data-app=connected] .btn:disabled{opacity:.4;cursor:not-allowed}html[data-app=connected] .btn.danger{color:var(--fault);border-color:var(--fault)}html[data-app=connected] .path-dot{width:8px;height:8px;border-radius:50%;display:inline-block;flex-shrink:0;background:var(--text-dim)}html[data-app=connected] .path-dot.direct{background:var(--live)}html[data-app=connected] .path-dot.relay,html[data-app=connected] .path-dot.reconnecting,html[data-app=connected] .path-dot.disconnected{background:var(--fault)}html[data-app=connected] .unread-badge{background:var(--fault);color:#fff}@media (prefers-reduced-motion: reduce){html[data-app=connected] *,html[data-app=connected] *:before,html[data-app=connected] *:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@font-face{font-family:Bungee;font-style:normal;font-weight:400;font-display:swap;src:url(/assets/bungee-latin-Dfnurram.woff2) format("woff2")}:root{--bg-deep: #000000;--bg-primary: #050505;--bg-surface: #0a0a0a;--bg-raised: #111111;--bg-hover: #181818;--bg-active: #1f1f1f;--border-deep: #111111;--border: #1c1c1c;--border-light: #2a2a2a;--border-hover: #3d3d3d;--text-bright: #f5f5f5;--text-primary: #c8c8c8;--text-secondary: #8a8a8a;--text-muted: #5c5c5c;--text-dim: #3a3a3a;--accent: #f0f0f0;--accent-hover: #ffffff;--accent-ink: #000000;--success: #9a9a9a;--warning: #c8c8c8;--error: #c45c5c;--focus-ring: #f0f0f0;--sidebar-width: 220px;--statusbar-height: 28px;--font-display: "Bungee", ui-sans-serif, system-ui, sans-serif;--font-mono: ui-monospace, "Cascadia Code", "SF Mono", Consolas, "Liberation Mono", monospace;--font-size: 12px;--font-size-sm: 11px;--font-size-xs: 10px;--line-height: 1.6}.light-theme{--bg-deep: #f5f5f5;--bg-primary: #f0f0f0;--bg-surface: #e8e8e8;--bg-raised: #e0e0e0;--bg-hover: #d8d8d8;--bg-active: #cfcfcf;--border-deep: #d0d0d0;--border: #cccccc;--border-light: #bbbbbb;--border-hover: #999999;--text-bright: #111111;--text-primary: #222222;--text-secondary: #555555;--text-muted: #888888;--text-dim: #aaaaaa;--accent: #000000;--accent-hover: #222222;--accent-ink: #f5f5f5;--success: #555555;--warning: #333333;--error: #b33a3a;--focus-ring: #000000}*,*:before,*:after{margin:0;padding:0;box-sizing:border-box}html,body,#app{height:100%;width:100%;overflow:hidden;color:var(--text-primary);font-family:var(--font-mono);font-size:var(--font-size);line-height:var(--line-height);-webkit-font-smoothing:antialiased;user-select:auto}html,body{background:var(--bg-deep)}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border)}::-webkit-scrollbar-thumb:hover{background:var(--border-hover)}::-webkit-scrollbar-corner{background:transparent}::selection{background:#ffffff1a;color:var(--text-bright)}input,textarea,button,select{font-family:var(--font-mono);font-size:var(--font-size)}input:focus-visible,textarea:focus-visible,select:focus-visible,button:focus-visible,[tabindex]:focus-visible,.network-item:focus-visible,.clickable:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}button{cursor:pointer;border:none;background:none;color:inherit}a{color:var(--text-bright);text-decoration:none}a:hover{text-decoration:underline}.btn{padding:8px 12px;min-height:36px;border:1px solid var(--border);background:var(--bg-raised);color:var(--text-primary);cursor:pointer;font-size:var(--font-size-sm);text-align:center;font-family:var(--font-mono);transition:background .1s ease,opacity .1s ease}.btn:hover:not(:disabled){background:var(--bg-hover)}.btn.primary,.btn-save{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:500}.btn.primary:hover,.btn-save:hover{background:var(--accent-hover)}.btn:disabled{opacity:.4;cursor:not-allowed}.btn.danger{color:var(--error);border-color:var(--error)}.empty-state{padding:16px;text-align:center;color:var(--text-muted);font-size:var(--font-size-sm)} diff --git a/client/frontend/dist/assets/index-coA7a2P7.css b/client/frontend/dist/assets/index-coA7a2P7.css deleted file mode 100644 index 43570b8..0000000 --- a/client/frontend/dist/assets/index-coA7a2P7.css +++ /dev/null @@ -1 +0,0 @@ -.sidebar.svelte-1oaanap.svelte-1oaanap{width:100%;height:100%;background:var(--bg-surface);display:flex;flex-direction:column;flex-shrink:0}.sidebar-header.svelte-1oaanap.svelte-1oaanap{padding:12px;border-bottom:1px solid var(--border)}.sidebar-header.svelte-1oaanap h2.svelte-1oaanap{font-size:11px;text-transform:uppercase;letter-spacing:1px;color:var(--text-secondary);font-weight:600}.sidebar-meta.svelte-1oaanap.svelte-1oaanap{font-size:var(--font-size-xs);color:var(--text-muted);margin-top:4px}.sidebar-actions.svelte-1oaanap.svelte-1oaanap{padding:8px;display:flex;flex-direction:column;gap:6px;border-bottom:1px solid var(--border)}.sidebar-actions.svelte-1oaanap .btn.svelte-1oaanap{min-height:36px;padding:8px 10px}.network-list.svelte-1oaanap.svelte-1oaanap{flex:1;overflow-y:auto;overflow-x:hidden;padding:4px 0}.network-item.svelte-1oaanap.svelte-1oaanap{display:flex;align-items:center;padding:10px 12px;min-height:44px;cursor:pointer;gap:8px;border-bottom:1px solid var(--border-deep);transition:background .12s ease,opacity .12s ease;position:relative}.network-item.svelte-1oaanap.svelte-1oaanap:hover,.network-item.svelte-1oaanap.svelte-1oaanap:focus-visible{background:var(--bg-hover)}.network-item.active.svelte-1oaanap.svelte-1oaanap{background:var(--bg-active)}.network-item.disabled.svelte-1oaanap.svelte-1oaanap{opacity:.55}.network-indicator.svelte-1oaanap.svelte-1oaanap{width:4px;height:12px;background:var(--text-muted);flex-shrink:0}.network-indicator.active-dot.svelte-1oaanap.svelte-1oaanap{background:var(--accent)}.network-info.svelte-1oaanap.svelte-1oaanap{flex:1;min-width:0}.network-name.svelte-1oaanap.svelte-1oaanap{font-size:var(--font-size);color:var(--text-bright);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.network-meta.svelte-1oaanap.svelte-1oaanap{font-size:var(--font-size-xs);color:var(--text-secondary);line-height:1.4}.row-actions.svelte-1oaanap.svelte-1oaanap{position:relative;flex-shrink:0}.menu-btn.svelte-1oaanap.svelte-1oaanap{background:none;border:1px solid transparent;color:var(--text-muted);cursor:pointer;font-family:var(--font-mono);font-size:16px;line-height:1;width:32px;height:32px;display:flex;align-items:center;justify-content:center}.menu-btn.svelte-1oaanap.svelte-1oaanap:hover,.menu-btn[aria-expanded=true].svelte-1oaanap.svelte-1oaanap{color:var(--text-bright);border-color:var(--border);background:var(--bg-raised)}.overflow-menu.svelte-1oaanap.svelte-1oaanap{position:absolute;right:0;top:100%;z-index:20;min-width:160px;background:var(--bg-raised);border:1px solid var(--border);display:flex;flex-direction:column;box-shadow:0 4px 12px #00000059}.menu-item.svelte-1oaanap.svelte-1oaanap{background:none;border:none;text-align:left;padding:10px 12px;min-height:36px;color:var(--text-primary);font-family:var(--font-mono);font-size:var(--font-size-sm);cursor:pointer}.menu-item.svelte-1oaanap.svelte-1oaanap:hover{background:var(--bg-hover);color:var(--text-bright)}.menu-item.danger.svelte-1oaanap.svelte-1oaanap{color:var(--error)}.menu-item.danger.svelte-1oaanap.svelte-1oaanap:hover{background:#c45c5c1f}.empty-desc.svelte-1oaanap.svelte-1oaanap{margin-top:6px;font-size:var(--font-size-xs);color:var(--text-dim)}.empty-state.svelte-1oaanap.svelte-1oaanap{padding:16px;text-align:center;color:var(--text-muted);font-size:var(--font-size-sm)}.sidebar-footer.svelte-1oaanap.svelte-1oaanap{padding:8px;border-top:1px solid var(--border)}.settings-btn.svelte-1oaanap.svelte-1oaanap{width:100%;min-height:36px}.modal-overlay.svelte-1oaanap.svelte-1oaanap{position:fixed;inset:0;background:#000000b3;display:flex;align-items:center;justify-content:center;z-index:100;animation:svelte-1oaanap-fadeIn .12s ease-out}@keyframes svelte-1oaanap-fadeIn{0%{opacity:0}to{opacity:1}}.modal.svelte-1oaanap.svelte-1oaanap{background:var(--bg-surface);border:1px solid var(--border);padding:20px;width:320px;max-height:80vh;overflow-y:auto;display:flex;flex-direction:column;gap:10px}.modal.svelte-1oaanap h3.svelte-1oaanap{font-size:var(--font-size);color:var(--text-bright);font-weight:500;text-transform:uppercase;letter-spacing:.5px}.modal.svelte-1oaanap input.svelte-1oaanap{padding:10px;min-height:40px;border:1px solid var(--border);background:var(--bg-primary);color:var(--text-primary);font-size:var(--font-size);font-family:var(--font-mono)}.modal.svelte-1oaanap input.invalid.svelte-1oaanap{border-color:var(--error)}.field-error.svelte-1oaanap.svelte-1oaanap,.modal-error.svelte-1oaanap.svelte-1oaanap{font-size:var(--font-size-xs);color:var(--error)}.modal-error.svelte-1oaanap.svelte-1oaanap{padding:8px;border:1px solid var(--error);background:#c45c5c14}.modal-actions.svelte-1oaanap.svelte-1oaanap{display:flex;gap:6px;justify-content:flex-end}.modal-actions.svelte-1oaanap .btn.svelte-1oaanap{min-height:36px;padding:8px 12px}.sr-only.svelte-1oaanap.svelte-1oaanap{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.peer-view.svelte-mpjrp9.svelte-mpjrp9{display:flex;flex-direction:column;height:100%}.peer-header.svelte-mpjrp9.svelte-mpjrp9{padding:12px 16px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px;background:var(--bg-surface);flex-wrap:wrap}.peer-header.svelte-mpjrp9 h2.svelte-mpjrp9{font-size:var(--font-size);font-weight:500;color:var(--text-bright);text-transform:uppercase;letter-spacing:.5px}.ip-badge.svelte-mpjrp9.svelte-mpjrp9{padding:4px 8px;min-height:28px;background:var(--bg-raised);font-size:var(--font-size-xs);font-family:var(--font-mono);color:var(--text-secondary);border:1px solid var(--border);cursor:pointer}.ip-badge.svelte-mpjrp9.svelte-mpjrp9:hover{border-color:var(--border-hover);color:var(--text-bright)}.room-chat-btn.svelte-mpjrp9.svelte-mpjrp9{margin-left:auto;background:transparent;border:1px solid var(--border);color:var(--text-secondary);font-family:var(--font-mono);font-size:var(--font-size-xs);padding:6px 10px;min-height:32px;cursor:pointer;position:relative}.room-chat-btn.svelte-mpjrp9.svelte-mpjrp9:hover{color:var(--text-bright);border-color:var(--border-hover)}.relay-hint.svelte-mpjrp9.svelte-mpjrp9{font-size:var(--font-size-xs);color:var(--text-muted)}.badge.svelte-mpjrp9.svelte-mpjrp9{display:inline-block;min-width:14px;padding:0 4px;margin-left:4px;background:var(--accent);color:var(--accent-ink);font-size:10px;line-height:14px;text-align:center}.peer-table.svelte-mpjrp9.svelte-mpjrp9{flex:1;overflow:auto;min-height:0;min-width:0}.table-row.svelte-mpjrp9.svelte-mpjrp9{display:grid;grid-template-columns:minmax(56px,72px) minmax(72px,1fr) minmax(88px,110px) minmax(48px,70px) minmax(52px,72px) minmax(64px,80px);gap:8px;align-items:center;padding:10px 16px;min-height:40px;border-bottom:1px solid var(--border-deep);font-size:var(--font-size-sm);min-width:520px}.table-header-row.svelte-mpjrp9.svelte-mpjrp9{color:var(--text-muted);text-transform:uppercase;font-size:var(--font-size-xs);letter-spacing:.4px}.self-row.svelte-mpjrp9.svelte-mpjrp9{background:var(--bg-surface)}.nickname.svelte-mpjrp9.svelte-mpjrp9{color:var(--text-bright);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.self-tag.svelte-mpjrp9.svelte-mpjrp9{margin-left:6px;font-size:var(--font-size-xs);color:var(--text-muted)}.col-ip.svelte-mpjrp9.svelte-mpjrp9,.col-ping.svelte-mpjrp9.svelte-mpjrp9,.col-path.svelte-mpjrp9.svelte-mpjrp9{font-family:var(--font-mono);color:var(--text-secondary)}.col-ping.probing.svelte-mpjrp9.svelte-mpjrp9{color:var(--text-bright)}.clickable.svelte-mpjrp9.svelte-mpjrp9{cursor:pointer}.clickable.svelte-mpjrp9.svelte-mpjrp9:hover{color:var(--text-bright)}.status-cell.svelte-mpjrp9.svelte-mpjrp9{display:flex;align-items:center;gap:6px}.status-text.svelte-mpjrp9.svelte-mpjrp9{font-size:var(--font-size-xs);color:var(--text-secondary)}.sq.svelte-mpjrp9.svelte-mpjrp9{width:8px;height:8px;display:inline-block;flex-shrink:0}.sq-online.svelte-mpjrp9.svelte-mpjrp9{background:var(--success)}.sq-offline.svelte-mpjrp9.svelte-mpjrp9{background:var(--text-dim)}.col-action.svelte-mpjrp9.svelte-mpjrp9{display:flex;gap:2px;justify-content:flex-end}.row-btn.svelte-mpjrp9.svelte-mpjrp9{background:transparent;border:none;color:var(--text-muted);cursor:pointer;font-family:var(--font-mono);min-width:32px;min-height:32px;padding:0}.row-btn.svelte-mpjrp9.svelte-mpjrp9:hover:not(:disabled){color:var(--text-bright)}.row-btn.svelte-mpjrp9.svelte-mpjrp9:disabled{opacity:.35;cursor:not-allowed}.empty-peers.svelte-mpjrp9.svelte-mpjrp9{padding:48px 24px;text-align:center;color:var(--text-muted)}.empty-label.svelte-mpjrp9.svelte-mpjrp9{color:var(--text-secondary);margin:8px 0 4px}.empty-desc.svelte-mpjrp9.svelte-mpjrp9{font-size:var(--font-size-xs)}.statusbar.svelte-1pzfkl{min-height:var(--statusbar-height);background:var(--bg-deep);border-top:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;gap:12px;padding:4px 12px;font-size:var(--font-size-xs);color:var(--text-secondary);flex-shrink:0;font-family:var(--font-mono);z-index:1;position:relative;min-width:0}.status-left.svelte-1pzfkl,.status-right.svelte-1pzfkl{display:flex;align-items:center;gap:8px 14px;min-width:0;flex-wrap:wrap}.status-left.svelte-1pzfkl{flex:0 1 auto}.status-right.svelte-1pzfkl{flex:1 1 auto;justify-content:flex-end;opacity:.85}.status-item.svelte-1pzfkl{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:36ch}.status-server.svelte-1pzfkl{max-width:28ch}.status-room.svelte-1pzfkl{max-width:22ch}.status-ver.svelte-1pzfkl{flex-shrink:0;max-width:none}.degraded.svelte-1pzfkl{color:var(--warning)}.sq.svelte-1pzfkl{display:inline-block;width:7px;height:7px;background:var(--error);vertical-align:middle;flex-shrink:0}.sq.sq-connected.svelte-1pzfkl{background:var(--success)}.sq.sq-warn.svelte-1pzfkl{background:var(--warning)}.connect-view.svelte-1br9j49.svelte-1br9j49{display:flex;align-items:center;justify-content:center;width:100%;height:100%;padding:32px 24px}.connect-form.svelte-1br9j49.svelte-1br9j49,.connected-info.svelte-1br9j49.svelte-1br9j49{width:min(360px,100%);display:flex;flex-direction:column;gap:16px;animation:svelte-1br9j49-connectIn .45s cubic-bezier(.16,1,.3,1) both}@keyframes svelte-1br9j49-connectIn{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}.brand-block.svelte-1br9j49.svelte-1br9j49{text-align:center;margin-bottom:12px}.brand.svelte-1br9j49.svelte-1br9j49{font-family:var(--font-display);font-size:clamp(36px,7vw,48px);font-weight:400;letter-spacing:.02em;text-transform:uppercase;color:var(--text-bright);line-height:1.05}.tagline.svelte-1br9j49.svelte-1br9j49{margin-top:10px;font-size:var(--font-size-sm);color:var(--text-secondary);text-transform:none;letter-spacing:.02em;line-height:1.45}.field.svelte-1br9j49.svelte-1br9j49{display:flex;flex-direction:column;gap:7px}label.svelte-1br9j49.svelte-1br9j49{font-size:var(--font-size-xs);color:var(--text-secondary);text-transform:uppercase;letter-spacing:.08em}input.svelte-1br9j49.svelte-1br9j49{background:#111111d9;border:1px solid var(--border-light);color:var(--text-bright);padding:13px 14px;min-height:44px;font-family:var(--font-mono);font-size:var(--font-size);transition:border-color .15s ease,background .15s ease}input.svelte-1br9j49.svelte-1br9j49::placeholder{color:var(--text-dim)}input.svelte-1br9j49.svelte-1br9j49:hover:not(:disabled){border-color:var(--border-hover)}input.svelte-1br9j49.svelte-1br9j49:focus{outline:none;border-color:var(--text-bright);background:#141414f2}input.invalid.svelte-1br9j49.svelte-1br9j49{border-color:var(--error)}.field-error.svelte-1br9j49.svelte-1br9j49{font-size:var(--font-size-xs);color:var(--error)}.connect-btn.svelte-1br9j49.svelte-1br9j49,.disconnect-btn.svelte-1br9j49.svelte-1br9j49,.secondary-btn.svelte-1br9j49.svelte-1br9j49{border:none;padding:15px 18px;min-height:48px;font-family:var(--font-mono);font-size:var(--font-size);cursor:pointer;text-transform:uppercase;letter-spacing:.12em;font-weight:600;transition:background .15s ease,border-color .15s ease,transform .12s ease}.connect-btn.svelte-1br9j49.svelte-1br9j49{margin-top:4px;background:var(--accent);color:var(--accent-ink)}.connect-btn.svelte-1br9j49.svelte-1br9j49:hover:not(:disabled){background:var(--accent-hover);transform:translateY(-1px)}.connect-btn.svelte-1br9j49.svelte-1br9j49:active:not(:disabled){transform:translateY(0)}.connect-btn.svelte-1br9j49.svelte-1br9j49:disabled{opacity:.45;cursor:not-allowed;transform:none}.secondary-btn.svelte-1br9j49.svelte-1br9j49{background:transparent;color:var(--text-primary);border:1px solid var(--border-light);font-weight:500;letter-spacing:.08em}.secondary-btn.svelte-1br9j49.svelte-1br9j49:hover:not(:disabled){border-color:var(--accent);color:var(--text-bright)}.disconnect-btn.svelte-1br9j49.svelte-1br9j49{background:transparent;color:var(--error);border:1px solid var(--error);font-weight:500}.phase.svelte-1br9j49.svelte-1br9j49{font-size:var(--font-size-xs);color:var(--text-muted);text-align:center;letter-spacing:.04em}.invite-disclosure.svelte-1br9j49.svelte-1br9j49{margin-top:8px;border-top:1px solid var(--border);padding-top:14px}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49{cursor:pointer;color:var(--text-muted);font-size:var(--font-size-sm);list-style:none;min-height:36px;display:flex;align-items:center;justify-content:center;transition:color .15s ease}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49:hover{color:var(--text-secondary)}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49::-webkit-details-marker{display:none}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49:before{content:"+";margin-right:8px;color:var(--text-dim)}.invite-disclosure[open].svelte-1br9j49 summary.svelte-1br9j49:before{content:"−"}.invite-block.svelte-1br9j49.svelte-1br9j49{display:flex;flex-direction:column;gap:10px;margin-top:12px}.connected-line.svelte-1br9j49.svelte-1br9j49{display:flex;align-items:center;gap:8px;color:var(--text-bright)}.info-line.svelte-1br9j49.svelte-1br9j49{display:flex;justify-content:space-between;font-size:var(--font-size-sm);color:var(--text-secondary)}.info-value.svelte-1br9j49.svelte-1br9j49{color:var(--text-primary);font-family:var(--font-mono)}.sq.svelte-1br9j49.svelte-1br9j49{width:8px;height:8px;display:inline-block}.sq-green.svelte-1br9j49.svelte-1br9j49{background:var(--success)}.sq-warn.svelte-1br9j49.svelte-1br9j49{background:var(--warning)}.sr-only.svelte-1br9j49.svelte-1br9j49{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.light-theme input.svelte-1br9j49.svelte-1br9j49{background:#ffffffa6}.light-theme input.svelte-1br9j49.svelte-1br9j49:focus{background:#ffffffe6}.chat-view.svelte-11c1d7e.svelte-11c1d7e{display:flex;flex-direction:column;height:100%}.chat-header.svelte-11c1d7e.svelte-11c1d7e{display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid var(--border);background:var(--bg-surface)}.back-btn.svelte-11c1d7e.svelte-11c1d7e{width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:transparent;border:1px solid var(--border);color:var(--text-secondary);cursor:pointer;font-family:var(--font-mono)}.chat-title.svelte-11c1d7e.svelte-11c1d7e{color:var(--text-bright);font-size:var(--font-size)}.chat-messages.svelte-11c1d7e.svelte-11c1d7e{flex:1;overflow-y:auto;padding:16px;min-height:0}.empty-chat.svelte-11c1d7e.svelte-11c1d7e{text-align:center;padding:40px 16px;color:var(--text-muted)}.empty-chat-label.svelte-11c1d7e.svelte-11c1d7e{color:var(--text-secondary);margin:8px 0 4px}.empty-chat-desc.svelte-11c1d7e.svelte-11c1d7e{font-size:var(--font-size-xs)}.date-sep.svelte-11c1d7e.svelte-11c1d7e{text-align:center;font-size:var(--font-size-xs);color:var(--text-dim);margin:12px 0}.system-line.svelte-11c1d7e.svelte-11c1d7e{text-align:center;font-size:var(--font-size-xs);color:var(--text-muted);margin:8px 0}.msg.svelte-11c1d7e.svelte-11c1d7e{margin-bottom:10px;max-width:80%}.msg.self.svelte-11c1d7e.svelte-11c1d7e{margin-left:auto;text-align:right}.msg-meta.svelte-11c1d7e.svelte-11c1d7e{font-size:var(--font-size-xs);color:var(--text-muted);margin-bottom:2px}.msg-body.svelte-11c1d7e.svelte-11c1d7e{display:inline-block;padding:8px 10px;background:var(--bg-raised);border:1px solid var(--border);color:var(--text-primary);white-space:pre-wrap;word-break:break-word;text-align:left}.msg.self.svelte-11c1d7e .msg-body.svelte-11c1d7e{background:var(--bg-active)}.retry-btn.svelte-11c1d7e.svelte-11c1d7e{margin-left:6px;background:transparent;border:none;color:var(--error);cursor:pointer;font-size:var(--font-size-xs)}.chat-input-area.svelte-11c1d7e.svelte-11c1d7e{display:flex;gap:8px;padding:12px 16px;border-top:1px solid var(--border);background:var(--bg-surface)}textarea.svelte-11c1d7e.svelte-11c1d7e{flex:1;resize:none;background:var(--bg-raised);border:1px solid var(--border);color:var(--text-primary);padding:8px 10px;font-family:var(--font-mono);font-size:var(--font-size);min-height:36px}textarea.svelte-11c1d7e.svelte-11c1d7e:disabled{opacity:.5}.send-btn.svelte-11c1d7e.svelte-11c1d7e{background:var(--accent);color:var(--accent-ink);border:none;padding:0 16px;cursor:pointer;font-family:var(--font-mono);text-transform:uppercase}.send-btn.svelte-11c1d7e.svelte-11c1d7e:disabled{opacity:.4;cursor:not-allowed}.settings-view.svelte-1pfl9w0.svelte-1pfl9w0{display:flex;flex-direction:column;height:100%;padding:24px 32px}.settings-content.svelte-1pfl9w0.svelte-1pfl9w0{flex:1;overflow-y:auto;min-height:0;height:0}.settings-title.svelte-1pfl9w0.svelte-1pfl9w0{font-size:var(--font-size);color:var(--text-bright);text-transform:uppercase;letter-spacing:1px;font-weight:500;margin-bottom:20px}.reconnect-banner.svelte-1pfl9w0.svelte-1pfl9w0{background:var(--bg-raised);border:1px solid var(--border-hover);color:var(--text-bright);padding:10px 12px;margin-bottom:16px;font-size:var(--font-size-sm)}.section.svelte-1pfl9w0.svelte-1pfl9w0{margin-bottom:24px}.section-title.svelte-1pfl9w0.svelte-1pfl9w0{font-size:var(--font-size-xs);color:var(--text-muted);letter-spacing:1px}.hint.svelte-1pfl9w0.svelte-1pfl9w0{font-size:var(--font-size-xs);color:var(--text-muted);margin:6px 0 12px;line-height:1.4}.reconnect-hint.svelte-1pfl9w0.svelte-1pfl9w0{color:var(--text-secondary)}.setting-row.svelte-1pfl9w0.svelte-1pfl9w0{display:flex;align-items:center;gap:12px;margin-bottom:10px;min-height:32px}.setting-label.svelte-1pfl9w0.svelte-1pfl9w0{min-width:140px;color:var(--text-secondary);font-size:var(--font-size-sm)}.toggle-label.svelte-1pfl9w0.svelte-1pfl9w0{color:var(--text-muted);font-size:var(--font-size-xs)}input[type=text].svelte-1pfl9w0.svelte-1pfl9w0,input[type=password].svelte-1pfl9w0.svelte-1pfl9w0,input[type=number].svelte-1pfl9w0.svelte-1pfl9w0,select.svelte-1pfl9w0.svelte-1pfl9w0{flex:1;background:var(--bg-raised);border:1px solid var(--border);color:var(--text-primary);padding:8px 10px;min-height:36px;font-family:var(--font-mono);font-size:var(--font-size-sm)}input[type=checkbox].svelte-1pfl9w0.svelte-1pfl9w0{width:18px;height:18px}.radio-group.svelte-1pfl9w0.svelte-1pfl9w0{display:flex;gap:12px}.radio-option.svelte-1pfl9w0.svelte-1pfl9w0{display:flex;align-items:center;gap:6px;color:var(--text-secondary);font-size:var(--font-size-sm);min-height:32px}.scale-row.svelte-1pfl9w0 input[type=range].svelte-1pfl9w0{flex:1;min-width:120px;accent-color:var(--accent)}.scale-value.svelte-1pfl9w0.svelte-1pfl9w0{min-width:44px;text-align:right;color:var(--text-secondary);font-size:var(--font-size-sm);font-family:var(--font-mono)}.actions-section.svelte-1pfl9w0.svelte-1pfl9w0{display:flex;gap:8px;align-items:center}.actions-section.svelte-1pfl9w0 .btn.svelte-1pfl9w0{min-height:36px;padding:8px 14px}.update-row.svelte-1pfl9w0.svelte-1pfl9w0{flex-wrap:wrap}.update-row.svelte-1pfl9w0 .btn.svelte-1pfl9w0{min-height:36px;padding:8px 14px}.btn-check.svelte-1pfl9w0.svelte-1pfl9w0,.btn-update.svelte-1pfl9w0.svelte-1pfl9w0{background:var(--bg-raised);border:1px solid var(--border);color:var(--text-primary);font-family:var(--font-mono);font-size:var(--font-size-sm);cursor:pointer}.btn-check.svelte-1pfl9w0.svelte-1pfl9w0:hover:not(:disabled),.btn-update.svelte-1pfl9w0.svelte-1pfl9w0:hover:not(:disabled){border-color:var(--border-hover);color:var(--text-bright)}.btn-check.svelte-1pfl9w0.svelte-1pfl9w0:disabled,.btn-update.svelte-1pfl9w0.svelte-1pfl9w0:disabled{opacity:.5;cursor:default}.ver.svelte-1pfl9w0.svelte-1pfl9w0{margin-left:auto;color:var(--text-dim);font-size:var(--font-size-xs)}.shell.svelte-1hi7jen{display:flex;flex-direction:column;height:100%;width:100%;position:relative;z-index:1;min-height:0}.connect-shell.svelte-1hi7jen{z-index:1}.layout.svelte-1hi7jen{display:flex;flex:1;min-height:0;position:relative}.fullscreen-connect.svelte-1hi7jen{display:flex;flex:1;width:100%;align-items:center;justify-content:center;min-height:0}.sidebar-wrapper.svelte-1hi7jen{position:relative;flex-shrink:0;background:var(--bg-surface);border-right:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden;min-height:0}.drag-handle.svelte-1hi7jen{position:absolute;top:0;right:-3px;width:6px;height:100%;cursor:col-resize;z-index:10;background:transparent;transition:background .1s}.drag-handle.svelte-1hi7jen:hover,.drag-handle.active.svelte-1hi7jen,.drag-handle.svelte-1hi7jen:focus-visible{background:var(--border-hover)}.main-area.svelte-1hi7jen{flex:1;display:flex;flex-direction:column;overflow:hidden;background:var(--bg-primary);min-width:0;min-height:0}.view-fade.svelte-1hi7jen{flex:1;display:flex;flex-direction:column;min-height:0;min-width:0;animation:svelte-1hi7jen-viewIn .2s ease-out}@keyframes svelte-1hi7jen-viewIn{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.unknown-view.svelte-1hi7jen{padding:40px;color:var(--text-muted)}.error-strip.svelte-1hi7jen{position:fixed;left:12px;right:12px;bottom:calc(var(--statusbar-height) + 12px);z-index:1100;display:flex;align-items:center;gap:12px;padding:10px 14px;background:var(--bg-raised);border:1px solid var(--error);color:var(--error);font-size:var(--font-size-sm)}.error-strip-msg.svelte-1hi7jen{flex:1;min-width:0;word-break:break-word}.error-strip-dismiss.svelte-1hi7jen{flex-shrink:0;min-height:32px;padding:4px 10px;border:1px solid var(--error);background:transparent;color:var(--error);cursor:pointer;font-family:var(--font-mono);font-size:var(--font-size-xs);text-transform:uppercase}.error-strip-dismiss.svelte-1hi7jen:hover{background:#c45c5c1f}.notification.svelte-1hi7jen{position:fixed;top:12px;right:12px;padding:6px 12px;font-size:var(--font-size-sm);z-index:1000;background:var(--bg-raised);border:1px solid var(--border);color:var(--text-primary);animation:svelte-1hi7jen-slideIn .15s ease-out}.notification.error.svelte-1hi7jen{border-color:var(--error);color:var(--error)}.notification.info.svelte-1hi7jen{border-color:var(--border)}.notif-icon.svelte-1hi7jen{margin-right:6px;font-weight:700}@keyframes svelte-1hi7jen-slideIn{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}.space-bg,.space-bg:before,.space-bg:after,.space-dust,.space-dust:before{position:fixed;pointer-events:none;z-index:0}.space-bg{inset:0;background:radial-gradient(ellipse 85% 65% at 50% 36%,rgba(255,255,255,.045) 0%,transparent 55%),radial-gradient(ellipse 120% 80% at 50% 100%,rgba(255,255,255,.03) 0%,transparent 50%),radial-gradient(ellipse 100% 100% at 50% 50%,#0a0a0a,#050505 70%,#000)}.space-bg:before{content:"";position:absolute;inset:0;opacity:.8;background:radial-gradient(1.2px 1.2px at 5% 10%,rgba(255,255,255,.55) 0%,transparent 100%),radial-gradient(1px 1px at 12% 32%,rgba(255,255,255,.35) 0%,transparent 100%),radial-gradient(1px 1px at 18% 68%,rgba(255,255,255,.32) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 25% 45%,rgba(255,255,255,.5) 0%,transparent 100%),radial-gradient(1px 1px at 32% 18%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1px 1px at 38% 78%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 45% 15%,rgba(255,255,255,.5) 0%,transparent 100%),radial-gradient(1px 1px at 52% 58%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1px 1px at 58% 28%,rgba(255,255,255,.26) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 65% 10%,rgba(255,255,255,.5) 0%,transparent 100%),radial-gradient(1px 1px at 72% 72%,rgba(255,255,255,.35) 0%,transparent 100%),radial-gradient(1px 1px at 78% 40%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 85% 65%,rgba(255,255,255,.48) 0%,transparent 100%),radial-gradient(1px 1px at 90% 22%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1px 1px at 94% 88%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(1px 1px at 8% 88%,rgba(255,255,255,.26) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 30% 92%,rgba(255,255,255,.4) 0%,transparent 100%),radial-gradient(1px 1px at 48% 42%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(1px 1px at 62% 88%,rgba(255,255,255,.32) 0%,transparent 100%),radial-gradient(1px 1px at 88% 52%,rgba(255,255,255,.26) 0%,transparent 100%)}.space-bg:after{content:"";position:absolute;inset:0;background-image:radial-gradient(1.5px 1.5px at 8% 18%,rgba(255,255,255,.7) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 48% 38%,rgba(255,255,255,.6) 0%,transparent 100%),radial-gradient(1.5px 1.5px at 88% 28%,rgba(255,255,255,.65) 0%,transparent 100%),radial-gradient(1px 1px at 22% 55%,rgba(255,255,255,.45) 0%,transparent 100%),radial-gradient(1px 1px at 70% 60%,rgba(255,255,255,.4) 0%,transparent 100%);animation:twinkle 9s ease-in-out infinite alternate;opacity:.5}@keyframes twinkle{0%{opacity:.2}45%{opacity:.5}to{opacity:.25}}.space-dust{inset:0;background:radial-gradient(ellipse 80% 70% at 50% 45%,transparent 42%,rgba(0,0,0,.62) 100%);opacity:1}.space-dust:before{content:"";position:absolute;inset:0;opacity:.32;background:radial-gradient(.5px .5px at 20% 30%,rgba(255,255,255,.4) 0%,transparent 100%),radial-gradient(.5px .5px at 40% 60%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(.5px .5px at 60% 25%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(.5px .5px at 75% 70%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(.5px .5px at 88% 40%,rgba(255,255,255,.3) 0%,transparent 100%)}.light-theme .space-bg,.light-theme .space-bg:before,.light-theme .space-bg:after,.light-theme .space-dust,.light-theme .space-dust:before{display:none!important}@font-face{font-family:Bungee;font-style:normal;font-weight:400;font-display:swap;src:url(/assets/bungee-latin-Dfnurram.woff2) format("woff2")}:root{--bg-deep: #000000;--bg-primary: #050505;--bg-surface: #0a0a0a;--bg-raised: #111111;--bg-hover: #181818;--bg-active: #1f1f1f;--border-deep: #111111;--border: #1c1c1c;--border-light: #2a2a2a;--border-hover: #3d3d3d;--text-bright: #f5f5f5;--text-primary: #c8c8c8;--text-secondary: #8a8a8a;--text-muted: #5c5c5c;--text-dim: #3a3a3a;--accent: #f0f0f0;--accent-hover: #ffffff;--accent-ink: #000000;--success: #9a9a9a;--warning: #c8c8c8;--error: #c45c5c;--focus-ring: #f0f0f0;--sidebar-width: 220px;--statusbar-height: 28px;--font-display: "Bungee", ui-sans-serif, system-ui, sans-serif;--font-mono: ui-monospace, "Cascadia Code", "SF Mono", Consolas, "Liberation Mono", monospace;--font-size: 12px;--font-size-sm: 11px;--font-size-xs: 10px;--line-height: 1.6}.light-theme{--bg-deep: #f5f5f5;--bg-primary: #f0f0f0;--bg-surface: #e8e8e8;--bg-raised: #e0e0e0;--bg-hover: #d8d8d8;--bg-active: #cfcfcf;--border-deep: #d0d0d0;--border: #cccccc;--border-light: #bbbbbb;--border-hover: #999999;--text-bright: #111111;--text-primary: #222222;--text-secondary: #555555;--text-muted: #888888;--text-dim: #aaaaaa;--accent: #000000;--accent-hover: #222222;--accent-ink: #f5f5f5;--success: #555555;--warning: #333333;--error: #b33a3a;--focus-ring: #000000}*,*:before,*:after{margin:0;padding:0;box-sizing:border-box}html,body,#app{height:100%;width:100%;overflow:hidden;color:var(--text-primary);font-family:var(--font-mono);font-size:var(--font-size);line-height:var(--line-height);-webkit-font-smoothing:antialiased;user-select:auto}html,body{background:var(--bg-deep)}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border)}::-webkit-scrollbar-thumb:hover{background:var(--border-hover)}::-webkit-scrollbar-corner{background:transparent}::selection{background:#ffffff1a;color:var(--text-bright)}input,textarea,button,select{font-family:var(--font-mono);font-size:var(--font-size)}input:focus-visible,textarea:focus-visible,select:focus-visible,button:focus-visible,[tabindex]:focus-visible,.network-item:focus-visible,.clickable:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}button{cursor:pointer;border:none;background:none;color:inherit}a{color:var(--text-bright);text-decoration:none}a:hover{text-decoration:underline}.btn{padding:8px 12px;min-height:36px;border:1px solid var(--border);background:var(--bg-raised);color:var(--text-primary);cursor:pointer;font-size:var(--font-size-sm);text-align:center;font-family:var(--font-mono);transition:background .1s ease,opacity .1s ease}.btn:hover:not(:disabled){background:var(--bg-hover)}.btn.primary,.btn-save{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:500}.btn.primary:hover,.btn-save:hover{background:var(--accent-hover)}.btn:disabled{opacity:.4;cursor:not-allowed}.btn.danger{color:var(--error);border-color:var(--error)}.empty-state{padding:16px;text-align:center;color:var(--text-muted);font-size:var(--font-size-sm)} diff --git a/client/frontend/dist/assets/index-nNWLt_UA.js b/client/frontend/dist/assets/index-nNWLt_UA.js new file mode 100644 index 0000000..650b775 --- /dev/null +++ b/client/frontend/dist/assets/index-nNWLt_UA.js @@ -0,0 +1 @@ +(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))i(o);new MutationObserver(o=>{for(const a of o)if(a.type==="childList")for(const r of a.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&i(r)}).observe(document,{childList:!0,subtree:!0});function n(o){const a={};return o.integrity&&(a.integrity=o.integrity),o.referrerPolicy&&(a.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?a.credentials="include":o.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function i(o){if(o.ep)return;o.ep=!0;const a=n(o);fetch(o.href,a)}})();function ve(){}function qi(t){return t()}function Os(){return Object.create(null)}function Pe(t){t.forEach(qi)}function Kl(t){return typeof t=="function"}function lt(t,e){return t!=t?e==e:t!==e||t&&typeof t=="object"||typeof t=="function"}function Di(t){return Object.keys(t).length===0}function Vl(t,...e){if(t==null){for(const i of e)i(void 0);return ve}const n=t.subscribe(...e);return n.unsubscribe?()=>n.unsubscribe():n}function xt(t){let e;return Vl(t,n=>e=n)(),e}function pe(t,e,n){t.$$.on_destroy.push(Vl(e,n))}function Ge(t,e,n){return t.set(n),e}function l(t,e){t.appendChild(e)}function G(t,e,n){t.insertBefore(e,n||null)}function B(t){t.parentNode&&t.parentNode.removeChild(t)}function c(t){return document.createElement(t)}function Fe(t){return document.createElementNS("http://www.w3.org/2000/svg",t)}function h(t){return document.createTextNode(t)}function m(){return h(" ")}function Rl(){return h("")}function V(t,e,n,i){return t.addEventListener(e,n,i),()=>t.removeEventListener(e,n,i)}function Mt(t){return function(e){return e.stopPropagation(),t.call(this,e)}}function s(t,e,n){n==null?t.removeAttribute(e):t.getAttribute(e)!==n&&t.setAttribute(e,n)}function Li(t){let e;return{p(...n){e=n,e.forEach(i=>t.push(i))},r(){e.forEach(n=>t.splice(t.indexOf(n),1))}}}function Ai(t){return t===""?null:+t}function zi(t){return Array.from(t.childNodes)}function w(t,e){e=""+e,t.data!==e&&(t.data=e)}function ae(t,e){t.value=e??""}function Ms(t,e,n,i){n==null?t.style.removeProperty(e):t.style.setProperty(e,n,"")}function Qn(t,e,n){for(let i=0;ii.call(this,e))}const Tt=[],Ut=[];let Ot=[];const Us=[],Ti=Promise.resolve();let Tl=!1;function Oi(){Tl||(Tl=!0,Ti.then(Ci))}function $n(t){Ot.push(t)}const Il=new Set;let It=0;function Ci(){if(It!==0)return;const t=tn;do{try{for(;Itt.indexOf(i)===-1?e.push(i):n.push(i)),n.forEach(i=>i()),Ot=e}const Zn=new Set;let vt;function Pi(){vt={r:0,c:[],p:vt}}function Ni(){vt.r||Pe(vt.c),vt=vt.p}function Oe(t,e){t&&t.i&&(Zn.delete(t),t.i(e))}function He(t,e,n,i){if(t&&t.o){if(Zn.has(t))return;Zn.add(t),vt.c.push(()=>{Zn.delete(t),i&&(n&&t.d(1),i())}),t.o(e)}else i&&i()}function ut(t){return t?.length!==void 0?t:Array.from(t)}function el(t,e){t.d(1),e.delete(t.key)}function tl(t,e,n,i,o,a,r,u,_,d,f,p){let v=t.length,k=a.length,g=v;const P={};for(;g--;)P[t[g].key]=g;const A=[],y=new Map,S=new Map,E=[];for(g=k;g--;){const D=p(o,a,g),K=n(D);let j=r.get(K);j?E.push(()=>j.p(D,e)):(j=d(K,D),j.c()),y.set(K,A[g]=j),K in P&&S.set(K,Math.abs(g-P[K]))}const R=new Set,U=new Set;function b(D){Oe(D,1),D.m(u,f),r.set(D.key,D),f=D.first,k--}for(;v&&k;){const D=A[k-1],K=t[v-1],j=D.key,q=K.key;D===K?(f=D.first,v--,k--):y.has(q)?!r.has(j)||R.has(j)?b(D):U.has(q)?v--:S.get(j)>S.get(q)?(U.add(j),b(D)):(R.add(q),v--):(_(K,r),v--)}for(;v--;){const D=t[v];y.has(D.key)||_(D,r)}for(;k;)b(A[k-1]);return Pe(E),A}function mt(t){t&&t.c()}function rt(t,e,n){const{fragment:i,after_update:o}=t.$$;i&&i.m(e,n),$n(()=>{const a=t.$$.on_mount.map(qi).filter(Kl);t.$$.on_destroy?t.$$.on_destroy.push(...a):Pe(a),t.$$.on_mount=[]}),o.forEach($n)}function ct(t,e){const n=t.$$;n.fragment!==null&&(Ui(n.after_update),Pe(n.on_destroy),n.fragment&&n.fragment.d(e),n.on_destroy=n.fragment=null,n.ctx=[])}function Wi(t,e){t.$$.dirty[0]===-1&&(Tt.push(t),Oi(),t.$$.dirty.fill(0)),t.$$.dirty[e/31|0]|=1<{const g=k.length?k[0]:v;return d.ctx&&o(d.ctx[p],d.ctx[p]=g)&&(!d.skip_bound&&d.bound[p]&&d.bound[p](g),f&&Wi(t,p)),v}):[],d.update(),f=!0,Pe(d.before_update),d.fragment=i?i(d.ctx):!1,e.target){if(e.hydrate){const p=zi(e.target);d.fragment&&d.fragment.l(p),p.forEach(B)}else d.fragment&&d.fragment.c();e.intro&&Oe(t.$$.fragment),rt(t,e.target,e.anchor),Ci()}en(_)}class dt{$$=void 0;$$set=void 0;$destroy(){ct(this,1),this.$destroy=ve}$on(e,n){if(!Kl(n))return ve;const i=this.$$.callbacks[e]||(this.$$.callbacks[e]=[]);return i.push(n),()=>{const o=i.indexOf(n);o!==-1&&i.splice(o,1)}}$set(e){this.$$set&&!Di(e)&&(this.$$.skip_bound=!0,this.$$set(e),this.$$.skip_bound=!1)}}const Fi="4",Rt=[];function Ki(t,e){return{subscribe:Ye(t,e).subscribe}}function Ye(t,e=ve){let n;const i=new Set;function o(u){if(lt(t,u)&&(t=u,n)){const _=!Rt.length;for(const d of i)d[1](),Rt.push(d,t);if(_){for(let d=0;d{i.delete(d),i.size===0&&n&&(n(),n=null)}}return{set:o,update:a,subscribe:r}}function Vi(t,e,n){const i=!Array.isArray(t),o=i?[t]:t;if(!o.every(Boolean))throw new Error("derived() expects stores as input, got a falsy value");const a=e.length<2;return Ki(n,(r,u)=>{let _=!1;const d=[];let f=0,p=ve;const v=()=>{if(f)return;p();const g=e(i?d[0]:d,r,u);a?r(g):p=Kl(g)?g:ve},k=o.map((g,P)=>Vl(g,A=>{d[P]=A,f&=~(1<{f|=1<[...i,{id:n,msg:t,type:e}]),setTimeout(()=>{Ml.update(i=>i.filter(o=>o.id!==n))},4e3),e==="error"&&Hi(t)}function Hi(t){if(!t){xn.set(null);return}xn.set({id:++Gi,msg:String(t)})}function ln(){xn.set(null)}function Ul(t,e){return t&&t.id?"peer:"+t.id:"room:"+(e||"network")}function sn(){return Ul(xt(nn),xt(De).room)}function Hl(t,e,n,i=!1,o="sent",a=!1,r=!1){const u=++Bi;let _;a?_=Ul(null,xt(De).room):i?_=sn():r?_="peer:"+t:_=Ul(null,xt(De).room),Bl.update(p=>{const v=p[_]?[...p[_]]:[];return v.push({id:i&&t.startsWith("local_")?t:u,fromID:t,nickname:e,message:n,timestamp:Date.now(),isSelf:i,status:o,system:a}),{...p,[_]:v.length>Ws?v.slice(-Ws):v}});const d=xt(Ae),f=sn();!i&&!(d==="chat"&&_===f)&&Gl.update(p=>({...p,[_]:(p[_]||0)+1}))}function Yi(t){Hl("system","",t,!1,"sent",!0)}function Wl(t){Gl.update(e=>{const n={...e};return delete n[t],n})}function Zt(t,e){const n=sn();Bl.update(i=>{const o=i[n];return o?{...i,[n]:o.map(a=>a.id===t?{...a,status:e}:a)}:i})}const Xi={subscribe(t){return Bl.subscribe(e=>{t(e[sn()]||[])})}};typeof window<"u"&&(window.__svelte||(window.__svelte={v:new Set})).v.add(Fi);const Fl={brand:"Entangled",tagline:"Private LAN for friends — anywhere.",networks:"Networks",network_count:"{n} network(s)",create_network:"Create Network",join_network:"Join Network",connecting:"Connecting...",peer_count:"{n} peer(s)",offline_click:"Offline — click to connect",saved:"Saved",no_networks:"No saved networks",no_networks_desc:"Create or join a network to get started",settings:"Settings",network_name:"Network name",password_opt:"Password (optional)",cancel:"Cancel",create:"Create",join:"Join",leave:"Leave network",remove:"Remove saved",delete_room:"Delete network",more_actions:"More actions",copy_invite:"Copy invite",paste_invite:"Have an invite?",invite_copied:"Invite copied",invite_placeholder:"server|room|password",server_addr:"Server Address",nickname:"Nickname",server_token:"Server token",server_token_desc:"optional shared secret (ENTANGLED_TOKEN)",connect:"Connect",disconnect:"Disconnect",connected:"Connected",server:"Server",virtual_ip:"Virtual IP",na:"N/A",reconnecting:"Reconnecting...",disconnected:"Disconnected",phase_dialing:"Dialing server…",phase_auth:"Authenticating…",phase_ready:"Ready",phase_error:"Error",room_chat:"Room Chat",chat:"Chat",col_nickname:"Nickname",col_ip:"Virtual IP",col_ping:"Ping",ping_peer:"Ping",ping_sent:"Pinging {name}…",error_ping:"Ping failed: {err}",col_path:"Path",col_status:"Status",status_online:"Online",status_offline:"Offline",path_p2p:"Direct",path_relay:"Relay",path_ws:"Fallback",path_unknown:"—",path_p2p_tip:"Peer-to-peer direct connection",path_relay_tip:"Traffic routed through the server relay",path_ws_tip:"WebSocket fallback path",you:"You",me:"me",no_peers:"No peers connected",no_peers_desc:"Create or join a network, then wait for friends",network:"Network",chat_with:"Chat with {name}",room_chat_title:"Room Chat — {room}",back:"Back",no_messages:"No messages yet",no_messages_desc:"Send a message to start the conversation",type_message:"Type a message...",send:"Send",send_disabled_no_room:"Join a network to chat",msg_truncated:"Message truncated to 1000 characters",retry:"Retry",today:"Today",yesterday:"Yesterday",you_self:"You",status_connected:"Connected",status_disconnected:"Disconnected",status_reconnecting:"Reconnecting…",status_relay_degraded:"Some peers on relay",status_server:"Server: {s}",status_ip:"IP: {ip}",status_network:"Network: {room}",status_peers:"Peers: {n}",version:"Entangled v{v}",settings_title:"Settings",section_connection:"CONNECTION",section_network:"ADVANCED NETWORK",section_system:"SYSTEM",section_appearance:"APPEARANCE",advanced_warn:"Only change these if you know what they do.",reconnect_apply:"Reconnect to apply",auto_connect:"Auto Connect",auto_connect_desc:"connect to last server on startup",auto_join:"Auto Join Last Room",auto_join_desc:"join last open room after connect (password rooms need a manual join after restart)",connection_mode:"Connection",connection_direct:"Direct (P2P)",connection_relay:"Relay (server)",connection_mode_desc:"Direct prefers peer-to-peer and uses relay only when needed. Relay forces all traffic through the server.",mtu:"MTU",mtu_desc:"Packet size. Wrong values can break games or cause lag.",dns_server:"DNS Server",dns_desc:"Optional DNS for the virtual network. Leave blank for system default.",socks5:"SOCKS5 Proxy",socks5_placeholder:"e.g. 127.0.0.1:10808",socks5_desc:"Proxies signaling (WebSocket) only — not peer/relay UDP. Reconnect to apply.",stun_server:"STUN Server",stun_desc:"Helps find your public address for direct links. Reconnect to apply.",start_windows:"Start with Windows",updates:"Updates",check_updates:"Check for updates",apply_update:"Update",update_checking:"Checking for updates…",update_latest:"You are up to date.",update_available:"Update available: v{v}",update_downloading:"Downloading update… the app will restart.",update_failed:"Update failed",confirm_update:"Download and install the update? The app will restart.",error_update_check:"Update check failed: ",error_update:"Update failed: ",notif_updating:"Installing update…",ui_scale:"UI Scale",ui_scale_desc:"Scales the whole interface. Use with window resize or F11 fullscreen.",theme:"Theme",theme_dark:"Dark",theme_light:"Light",language:"Language",save:"SAVE",reset:"RESET TO DEFAULTS",language_en:"English",language_ru:"Russian",language_zh:"Chinese",copied:"Copied",header_room:"Room",header_vip:"VIP",header_path:"Path",header_peers:"Peers",dismiss_error:"Dismiss",field_required:"Required",notif_created:"Network created: {name}",notif_joined:"Joined network: {name}",notif_left:"Left network",notif_removed:"Removed: {name}",notif_deleted:"Network deleted: {name}",notif_connected:"Connected to {addr}",notif_disconnected:"Disconnected",notif_settings_saved:"Settings saved",notif_reconnect_required:"Reconnect to apply proxy / STUN / token changes",notif_auto_join_skipped:'Auto-join skipped for "{name}" — enter the password to join',notif_need_config:"Set server & nickname in Connect page first",notif_room_deleted:"Network was deleted by owner",invite_no_password:"Invite copied without password (not stored). Add it before sharing.",error_create:"Failed to create network: {err}",error_join:"Failed to join: {err}",error_leave:"Failed to leave: {err}",error_remove:"Failed to remove: {err}",error_connect:"Connection failed: {err}",error_disconnect:"Error: {err}",error_send:"Failed to send: {err}",error_not_connected:"Not connected — cannot send message",error_invalid_invite:"Invalid invite: server and room are required",error_save:"Failed to save settings: {err}",confirm_disconnect:"Disconnect from server?",confirm_leave:"Leave the current network? It stays in your saved list.",confirm_leave_remove:"Leave and remove this network from your saved list?",confirm_remove:'Remove "{name}" from saved networks? (does not delete the network for others)',confirm_delete:'Permanently delete network "{name}" for everyone?',confirm_reset:"Reset all settings to defaults?"},Qi={brand:"Entangled",tagline:"Частная LAN для друзей — где угодно.",networks:"Сети",network_count:"{n} сет(ь/и/ей)",create_network:"Создать сеть",join_network:"Подключиться",connecting:"Подключение...",peer_count:"{n} участник(ов)",offline_click:"Не в сети — нажмите для подключения",saved:"Сохранено",no_networks:"Нет сохранённых сетей",no_networks_desc:"Создайте или войдите в сеть, чтобы начать",settings:"Настройки",network_name:"Название сети",password_opt:"Пароль (опционально)",cancel:"Отмена",create:"Создать",join:"Войти",leave:"Покинуть сеть",remove:"Убрать из списка",delete_room:"Удалить сеть",more_actions:"Ещё действия",copy_invite:"Копировать инвайт",paste_invite:"Есть инвайт?",invite_copied:"Инвайт скопирован",invite_placeholder:"сервер|комната|пароль",server_addr:"Адрес сервера",nickname:"Псевдоним",server_token:"Токен сервера",server_token_desc:"опциональный секрет (ENTANGLED_TOKEN)",connect:"Подключиться",disconnect:"Отключиться",connected:"Подключено",server:"Сервер",virtual_ip:"Виртуальный IP",na:"Н/Д",reconnecting:"Переподключение...",disconnected:"Отключено",phase_dialing:"Подключение к серверу…",phase_auth:"Аутентификация…",phase_ready:"Готово",phase_error:"Ошибка",room_chat:"Чат комнаты",chat:"Чат",col_nickname:"Псевдоним",col_ip:"Виртуальный IP",col_ping:"Пинг",ping_peer:"Пинг",ping_sent:"Пинг {name}…",error_ping:"Пинг не удался: {err}",col_path:"Путь",col_status:"Статус",status_online:"В сети",status_offline:"Не в сети",path_p2p:"Прямой",path_relay:"Релей",path_ws:"Запасной",path_unknown:"—",path_p2p_tip:"Прямое соединение peer-to-peer",path_relay_tip:"Трафик через серверный релей",path_ws_tip:"Запасной путь через WebSocket",you:"Вы",me:"я",no_peers:"Нет подключённых участников",no_peers_desc:"Создайте или войдите в сеть и дождитесь друзей",network:"Сеть",chat_with:"Чат с {name}",room_chat_title:"Чат комнаты — {room}",back:"Назад",no_messages:"Сообщений пока нет",no_messages_desc:"Отправьте сообщение, чтобы начать разговор",type_message:"Введите сообщение...",send:"Отправить",send_disabled_no_room:"Войдите в сеть, чтобы писать",msg_truncated:"Сообщение обрезано до 1000 символов",retry:"Повторить",today:"Сегодня",yesterday:"Вчера",you_self:"Вы",status_connected:"Подключено",status_disconnected:"Отключено",status_reconnecting:"Переподключение…",status_relay_degraded:"Часть пиров через релей",status_server:"Сервер: {s}",status_ip:"IP: {ip}",status_network:"Сеть: {room}",status_peers:"Участники: {n}",version:"Entangled v{v}",settings_title:"Настройки",section_connection:"ПОДКЛЮЧЕНИЕ",section_network:"ДОП. СЕТЬ",section_system:"СИСТЕМА",section_appearance:"ВНЕШНИЙ ВИД",advanced_warn:"Меняйте только если понимаете, что делаете.",reconnect_apply:"Переподключитесь, чтобы применить",auto_connect:"Автоподключение",auto_connect_desc:"подключаться к последнему серверу при запуске",auto_join:"Автовход в комнату",auto_join_desc:"входить в последнюю открытую комнату (с паролем — вручную после перезапуска)",connection_mode:"Соединение",connection_direct:"Прямое (P2P)",connection_relay:"Релей (сервер)",connection_mode_desc:"Прямое предпочитает P2P и использует релей только при необходимости. Релей гонит весь трафик через сервер.",mtu:"MTU",mtu_desc:"Размер пакета. Неверное значение ломает игры или даёт лаги.",dns_server:"DNS-сервер",dns_desc:"Опциональный DNS виртуальной сети. Пусто — системный по умолчанию.",socks5:"SOCKS5-прокси",socks5_placeholder:"напр. 127.0.0.1:10808",socks5_desc:"Только сигнальный WebSocket, не UDP пиров/релея. Переподключитесь, чтобы применить.",stun_server:"STUN-сервер",stun_desc:"Помогает найти публичный адрес. Переподключитесь, чтобы применить.",start_windows:"Запуск с Windows",updates:"Обновления",check_updates:"Проверить обновления",apply_update:"Обновить",update_checking:"Проверка обновлений…",update_latest:"У вас актуальная версия.",update_available:"Доступно обновление: v{v}",update_downloading:"Загрузка обновления… приложение перезапустится.",update_failed:"Ошибка обновления",confirm_update:"Скачать и установить обновление? Приложение перезапустится.",error_update_check:"Не удалось проверить обновления: ",error_update:"Не удалось обновить: ",notif_updating:"Установка обновления…",ui_scale:"Масштаб UI",ui_scale_desc:"Масштабирует весь интерфейс. Вместе с изменением размера окна или F11.",theme:"Тема",theme_dark:"Тёмная",theme_light:"Светлая",language:"Язык",save:"СОХРАНИТЬ",reset:"СБРОСИТЬ",language_en:"Английский",language_ru:"Русский",language_zh:"Китайский",copied:"Скопировано",header_room:"Комната",header_vip:"VIP",header_path:"Путь",header_peers:"Участники",dismiss_error:"Закрыть",field_required:"Обязательно",notif_created:"Сеть создана: {name}",notif_joined:"Подключились к сети: {name}",notif_left:"Покинули сеть",notif_removed:"Удалено: {name}",notif_deleted:"Сеть удалена: {name}",notif_connected:"Подключились к {addr}",notif_disconnected:"Отключились",notif_settings_saved:"Настройки сохранены",notif_reconnect_required:"Переподключитесь, чтобы применить прокси / STUN / токен",notif_auto_join_skipped:"Автовход пропущен для «{name}» — введите пароль вручную",notif_need_config:"Укажите сервер и псевдоним на странице подключения",notif_room_deleted:"Сеть удалена владельцем",invite_no_password:"Инвайт скопирован без пароля (он не хранится). Добавьте перед отправкой.",error_create:"Не удалось создать сеть: {err}",error_join:"Не удалось подключиться: {err}",error_leave:"Не удалось покинуть: {err}",error_remove:"Не удалось удалить: {err}",error_connect:"Ошибка подключения: {err}",error_disconnect:"Ошибка: {err}",error_send:"Не удалось отправить: {err}",error_not_connected:"Нет подключения — невозможно отправить сообщение",error_invalid_invite:"Неверный инвайт: нужны сервер и комната",error_save:"Не удалось сохранить настройки: {err}",confirm_disconnect:"Отключиться от сервера?",confirm_leave:"Покинуть текущую сеть? Она останется в сохранённых.",confirm_leave_remove:"Покинуть и убрать сеть из сохранённых?",confirm_remove:'Убрать "{name}" из сохранённых? (сеть для других не удалится)',confirm_delete:'Навсегда удалить сеть "{name}" для всех?',confirm_reset:"Сбросить все настройки?"},Zi={brand:"Entangled",tagline:"朋友的私人局域网 — 随时随地。",networks:"网络",network_count:"{n} 个网络",create_network:"创建网络",join_network:"加入网络",connecting:"连接中...",peer_count:"{n} 个节点",offline_click:"离线 — 点击连接",saved:"已保存",no_networks:"暂无保存的网络",no_networks_desc:"创建或加入网络以开始",settings:"设置",network_name:"网络名称",password_opt:"密码(可选)",cancel:"取消",create:"创建",join:"加入",leave:"离开网络",remove:"移除已保存",delete_room:"删除网络",more_actions:"更多操作",copy_invite:"复制邀请",paste_invite:"有邀请码?",invite_copied:"邀请已复制",invite_placeholder:"服务器|房间|密码",server_addr:"服务器地址",nickname:"昵称",server_token:"服务器令牌",server_token_desc:"可选共享密钥(ENTANGLED_TOKEN)",connect:"连接",disconnect:"断开",connected:"已连接",server:"服务器",virtual_ip:"虚拟 IP",na:"无",reconnecting:"重新连接...",disconnected:"已断开",phase_dialing:"正在连接服务器…",phase_auth:"正在验证…",phase_ready:"就绪",phase_error:"错误",room_chat:"房间聊天",chat:"聊天",col_nickname:"昵称",col_ip:"虚拟 IP",col_ping:"延迟",ping_peer:"测速",ping_sent:"正在测速 {name}…",error_ping:"测速失败: {err}",col_path:"路径",col_status:"状态",status_online:"在线",status_offline:"离线",path_p2p:"直连",path_relay:"中继",path_ws:"备用",path_unknown:"—",path_p2p_tip:"点对点直连",path_relay_tip:"经服务器中继转发",path_ws_tip:"WebSocket 备用路径",you:"你",me:"我",no_peers:"暂无连接的节点",no_peers_desc:"创建或加入网络,然后等待好友",network:"网络",chat_with:"与 {name} 聊天",room_chat_title:"房间聊天 — {room}",back:"返回",no_messages:"暂无消息",no_messages_desc:"发送一条消息开始对话",type_message:"输入消息...",send:"发送",send_disabled_no_room:"加入网络后才能聊天",msg_truncated:"消息已截断至 1000 个字符",retry:"重试",today:"今天",yesterday:"昨天",you_self:"你",status_connected:"已连接",status_disconnected:"已断开",status_reconnecting:"重新连接…",status_relay_degraded:"部分节点经中继",status_server:"服务器: {s}",status_ip:"IP: {ip}",status_network:"网络: {room}",status_peers:"节点: {n}",version:"Entangled v{v}",settings_title:"设置",section_connection:"连接",section_network:"高级网络",section_system:"系统",section_appearance:"外观",advanced_warn:"仅在了解作用时更改这些选项。",reconnect_apply:"重新连接以生效",auto_connect:"自动连接",auto_connect_desc:"启动时自动连接到上次的服务器",auto_join:"自动加入房间",auto_join_desc:"连接后自动加入上次的开放房间(有密码的房间重启后需手动加入)",connection_mode:"连接方式",connection_direct:"直连 (P2P)",connection_relay:"中继 (服务器)",connection_mode_desc:"直连优先点对点,必要时才用中继。中继模式强制全部流量经服务器。",mtu:"MTU",mtu_desc:"数据包大小。错误值可能导致游戏异常或卡顿。",dns_server:"DNS 服务器",dns_desc:"虚拟网络可选 DNS。留空则使用系统默认。",socks5:"SOCKS5 代理",socks5_placeholder:"例如 127.0.0.1:10808",socks5_desc:"仅代理信令 WebSocket,不含节点/中继 UDP。重新连接以生效。",stun_server:"STUN 服务器",stun_desc:"用于发现公网地址以便直连。重新连接以生效。",start_windows:"开机自启",updates:"更新",check_updates:"检查更新",apply_update:"更新",update_checking:"正在检查更新…",update_latest:"已是最新版本。",update_available:"有可用更新:v{v}",update_downloading:"正在下载更新…应用将重启。",update_failed:"更新失败",confirm_update:"下载并安装更新?应用将重启。",error_update_check:"检查更新失败:",error_update:"更新失败:",notif_updating:"正在安装更新…",ui_scale:"界面缩放",ui_scale_desc:"缩放整个界面。可配合窗口调整大小或 F11 全屏使用。",theme:"主题",theme_dark:"深色",theme_light:"浅色",language:"语言",save:"保存",reset:"重置为默认",language_en:"英语",language_ru:"俄语",language_zh:"中文",copied:"已复制",header_room:"房间",header_vip:"VIP",header_path:"路径",header_peers:"节点",dismiss_error:"关闭",field_required:"必填",notif_created:"网络已创建: {name}",notif_joined:"已加入网络: {name}",notif_left:"已离开网络",notif_removed:"已删除: {name}",notif_deleted:"网络已删除: {name}",notif_connected:"已连接到 {addr}",notif_disconnected:"已断开连接",notif_settings_saved:"设置已保存",notif_reconnect_required:"请重新连接以使代理 / STUN / 令牌生效",notif_auto_join_skipped:"已跳过自动加入「{name}」— 请输入密码后手动加入",notif_need_config:"请先在连接页面设置服务器和昵称",notif_room_deleted:"网络已被所有者删除",invite_no_password:"邀请已复制但无密码(密码不存储)。分享前请自行添加。",error_create:"创建网络失败: {err}",error_join:"加入失败: {err}",error_leave:"离开失败: {err}",error_remove:"删除失败: {err}",error_connect:"连接失败: {err}",error_disconnect:"错误: {err}",error_send:"发送失败: {err}",error_not_connected:"未连接 — 无法发送消息",error_invalid_invite:"无效邀请:需要服务器和房间名",error_save:"保存设置失败: {err}",confirm_disconnect:"确定断开服务器连接?",confirm_leave:"离开当前网络?仍保留在已保存列表中。",confirm_leave_remove:"离开并从已保存列表中移除?",confirm_remove:'从已保存网络中移除 "{name}"?(不会删除他人的网络)',confirm_delete:'永久删除网络 "{name}"(对所有人)?',confirm_reset:"确定重置所有设置?"},Yl={en:Fl,ru:Qi,zh:Zi};function $i(){const t=localStorage.getItem("entangled_locale");if(t&&Yl[t])return t;const e=navigator.language?.slice(0,2);return e==="ru"?"ru":e==="zh"?"zh":"en"}const Xl=Ye($i()),ft=Vi(Xl,t=>{const e=Yl[t]||Fl;return new Proxy(e,{get(n,i){if(typeof i=="string")return n[i]??Fl[i]??i}})});function $t(t){Yl[t]&&(localStorage.setItem("entangled_locale",t),Xl.set(t))}function re(t,e){return t?String(t).replace(/\{(\w+)\}/g,(n,i)=>e&&e[i]!=null?e[i]:`{${i}}`):""}function xi(t,e){return t?.reconnecting?"reconnecting":t?.connected?(e||[]).some(o=>o.connected&&(o.path==="relay"||o.path==="ws"))?"relay":"direct":"disconnected"}function Fs(t,e,n){const i=t.slice();return i[62]=e[n],i}function Ks(t){let e,n,i=t[16].no_networks+"",o,a,r,u=t[16].no_networks_desc+"",_,d;return{c(){e=c("div"),n=c("div"),o=h(i),a=m(),r=c("div"),_=h(u),d=m(),s(r,"class","empty-desc svelte-a1nde2"),s(e,"class","empty-state svelte-a1nde2")},m(f,p){G(f,e,p),l(e,n),l(n,o),l(e,a),l(e,r),l(r,_),l(e,d)},p(f,p){p[0]&65536&&i!==(i=f[16].no_networks+"")&&w(o,i),p[0]&65536&&u!==(u=f[16].no_networks_desc+"")&&w(_,u)},d(f){f&&B(e)}}}function eo(t){let e=t[16].saved+"",n;return{c(){n=h(e)},m(i,o){G(i,n,o)},p(i,o){o[0]&65536&&e!==(e=i[16].saved+"")&&w(n,e)},d(i){i&&B(n)}}}function to(t){let e=t[16].offline_click+"",n;return{c(){n=h(e)},m(i,o){G(i,n,o)},p(i,o){o[0]&65536&&e!==(e=i[16].offline_click+"")&&w(n,e)},d(i){i&&B(n)}}}function no(t){let e=re(t[16].peer_count,{n:t[18].peerCount})+"",n;return{c(){n=h(e)},m(i,o){G(i,n,o)},p(i,o){o[0]&327680&&e!==(e=re(i[16].peer_count,{n:i[18].peerCount})+"")&&w(n,e)},d(i){i&&B(n)}}}function lo(t){let e=t[16].connecting+"",n;return{c(){n=h(e)},m(i,o){G(i,n,o)},p(i,o){o[0]&65536&&e!==(e=i[16].connecting+"")&&w(n,e)},d(i){i&&B(n)}}}function Vs(t){let e,n,i=t[16].copy_invite+"",o,a,r,u,_=t[16].remove+"",d,f,p,v;function k(...y){return t[40](t[62],...y)}let g=t[18].room===t[62].name&&Js(t);function P(...y){return t[42](t[62],...y)}let A=t[18].room===t[62].name&&t[18].isOwner&&Bs(t);return{c(){e=c("div"),n=c("button"),o=h(i),a=m(),g&&g.c(),r=m(),u=c("button"),d=h(_),f=m(),A&&A.c(),s(n,"type","button"),s(n,"role","menuitem"),s(n,"class","menu-item svelte-a1nde2"),s(u,"type","button"),s(u,"role","menuitem"),s(u,"class","menu-item danger svelte-a1nde2"),s(e,"class","overflow-menu svelte-a1nde2"),s(e,"role","menu"),s(e,"tabindex","-1")},m(y,S){G(y,e,S),l(e,n),l(n,o),l(e,a),g&&g.m(e,null),l(e,r),l(e,u),l(u,d),l(e,f),A&&A.m(e,null),p||(v=[V(n,"click",k),V(u,"click",P),V(e,"click",Mt(t[37])),V(e,"keydown",Mt(t[38]))],p=!0)},p(y,S){t=y,S[0]&65536&&i!==(i=t[16].copy_invite+"")&&w(o,i),t[18].room===t[62].name?g?g.p(t,S):(g=Js(t),g.c(),g.m(e,r)):g&&(g.d(1),g=null),S[0]&65536&&_!==(_=t[16].remove+"")&&w(d,_),t[18].room===t[62].name&&t[18].isOwner?A?A.p(t,S):(A=Bs(t),A.c(),A.m(e,null)):A&&(A.d(1),A=null)},d(y){y&&B(e),g&&g.d(),A&&A.d(),p=!1,Pe(v)}}}function Js(t){let e,n=t[16].leave+"",i,o,a;return{c(){e=c("button"),i=h(n),s(e,"type","button"),s(e,"role","menuitem"),s(e,"class","menu-item svelte-a1nde2")},m(r,u){G(r,e,u),l(e,i),o||(a=V(e,"click",t[41]),o=!0)},p(r,u){u[0]&65536&&n!==(n=r[16].leave+"")&&w(i,n)},d(r){r&&B(e),o=!1,a()}}}function Bs(t){let e,n=t[16].delete_room+"",i,o,a;function r(...u){return t[43](t[62],...u)}return{c(){e=c("button"),i=h(n),s(e,"type","button"),s(e,"role","menuitem"),s(e,"class","menu-item danger svelte-a1nde2")},m(u,_){G(u,e,_),l(e,i),o||(a=V(e,"click",r),o=!0)},p(u,_){t=u,_[0]&65536&&n!==(n=t[16].delete_room+"")&&w(i,n)},d(u){u&&B(e),o=!1,a()}}}function Gs(t,e){let n,i,o,a,r,u=e[62].name+"",_,d,f,p,v,k,g,P,A,y,S,E,R,U,b,D,K,j,q;function H(N,M){return N[11]===N[62].name?lo:N[18].room===N[62].name?no:N[18].connected?eo:to}let T=H(e),O=T(e);function Z(...N){return e[39](e[62],...N)}let C=e[13]===e[62].name&&Vs(e);function W(){return e[44](e[62])}function ne(...N){return e[45](e[62],...N)}return{key:t,first:null,c(){n=c("div"),i=c("div"),o=m(),a=c("div"),r=c("div"),_=h(u),d=m(),f=c("div"),O.c(),p=m(),v=c("div"),k=c("button"),g=Fe("svg"),P=Fe("circle"),A=Fe("circle"),y=Fe("circle"),U=m(),C&&C.c(),b=m(),s(i,"class","network-indicator svelte-a1nde2"),s(i,"aria-hidden","true"),Ee(i,"active-dot",e[18].room===e[62].name),s(r,"class","network-name svelte-a1nde2"),s(f,"class","network-meta svelte-a1nde2"),s(a,"class","network-info svelte-a1nde2"),s(P,"cx","8"),s(P,"cy","3.5"),s(P,"r","1.25"),s(P,"fill","currentColor"),s(A,"cx","8"),s(A,"cy","8"),s(A,"r","1.25"),s(A,"fill","currentColor"),s(y,"cx","8"),s(y,"cy","12.5"),s(y,"r","1.25"),s(y,"fill","currentColor"),s(g,"width","16"),s(g,"height","16"),s(g,"viewBox","0 0 16 16"),s(g,"aria-hidden","true"),s(k,"type","button"),s(k,"class","menu-btn svelte-a1nde2"),s(k,"aria-haspopup","menu"),s(k,"aria-expanded",S=e[13]===e[62].name),s(k,"aria-label",E=e[16].more_actions),s(k,"title",R=e[16].more_actions),s(v,"class","row-actions svelte-a1nde2"),s(n,"class","network-item svelte-a1nde2"),s(n,"role","button"),s(n,"tabindex","0"),s(n,"aria-current",D=e[18].room===e[62].name?"true":void 0),s(n,"aria-label",K=e[62].name),Ee(n,"active",e[18].room===e[62].name),Ee(n,"disabled",!e[18].connected&&!e[11]),this.first=n},m(N,M){G(N,n,M),l(n,i),l(n,o),l(n,a),l(a,r),l(r,_),l(a,d),l(a,f),O.m(f,null),l(n,p),l(n,v),l(v,k),l(k,g),l(g,P),l(g,A),l(g,y),l(v,U),C&&C.m(v,null),l(n,b),j||(q=[V(k,"click",Z),V(n,"click",W),V(n,"keydown",ne)],j=!0)},p(N,M){e=N,M[0]&262145&&Ee(i,"active-dot",e[18].room===e[62].name),M[0]&1&&u!==(u=e[62].name+"")&&w(_,u),T===(T=H(e))&&O?O.p(e,M):(O.d(1),O=T(e),O&&(O.c(),O.m(f,null))),M[0]&8193&&S!==(S=e[13]===e[62].name)&&s(k,"aria-expanded",S),M[0]&65536&&E!==(E=e[16].more_actions)&&s(k,"aria-label",E),M[0]&65536&&R!==(R=e[16].more_actions)&&s(k,"title",R),e[13]===e[62].name?C?C.p(e,M):(C=Vs(e),C.c(),C.m(v,null)):C&&(C.d(1),C=null),M[0]&262145&&D!==(D=e[18].room===e[62].name?"true":void 0)&&s(n,"aria-current",D),M[0]&1&&K!==(K=e[62].name)&&s(n,"aria-label",K),M[0]&262145&&Ee(n,"active",e[18].room===e[62].name),M[0]&264192&&Ee(n,"disabled",!e[18].connected&&!e[11])},d(N){N&&B(n),O.d(),C&&C.d(),j=!1,Pe(q)}}}function Hs(t){let e,n,i,o=t[16].create_network+"",a,r,u,_=t[16].network_name+"",d,f,p,v,k,g,P,A,y=t[16].password_opt+"",S,E,R,U,b,D,K,j,q=t[16].cancel+"",H,T,O,Z=t[16].create+"",C,W,ne,N=t[9]&&Ys(t),M=t[7]&&Xs(t);return{c(){e=c("div"),n=c("div"),i=c("h3"),a=h(o),r=m(),u=c("label"),d=h(_),f=m(),p=c("input"),g=m(),N&&N.c(),P=m(),A=c("label"),S=h(y),E=m(),R=c("input"),b=m(),M&&M.c(),D=m(),K=c("div"),j=c("button"),H=h(q),T=m(),O=c("button"),C=h(Z),s(i,"id","create-title"),s(i,"class","svelte-a1nde2"),s(u,"class","sr-only svelte-a1nde2"),s(u,"for","create-name"),s(p,"id","create-name"),s(p,"type","text"),s(p,"placeholder",v=t[16].network_name),s(p,"aria-invalid",k=!!t[9]),s(p,"class","svelte-a1nde2"),Ee(p,"invalid",t[9]),s(A,"class","sr-only svelte-a1nde2"),s(A,"for","create-pass"),s(R,"id","create-pass"),s(R,"type","password"),s(R,"placeholder",U=t[16].password_opt),s(R,"class","svelte-a1nde2"),s(j,"class","btn svelte-a1nde2"),s(O,"class","btn primary svelte-a1nde2"),s(K,"class","modal-actions svelte-a1nde2"),s(n,"class","modal svelte-a1nde2"),s(n,"role","dialog"),s(n,"aria-modal","true"),s(n,"aria-labelledby","create-title"),s(e,"class","modal-overlay svelte-a1nde2"),s(e,"role","presentation")},m(F,J){G(F,e,J),l(e,n),l(n,i),l(i,a),l(n,r),l(n,u),l(u,d),l(n,f),l(n,p),ae(p,t[3]),l(n,g),N&&N.m(n,null),l(n,P),l(n,A),l(A,S),l(n,E),l(n,R),ae(R,t[4]),l(n,b),M&&M.m(n,null),l(n,D),l(n,K),l(K,j),l(j,H),l(K,T),l(K,O),l(O,C),t[49](n),W||(ne=[V(p,"input",t[47]),V(R,"input",t[48]),V(j,"click",t[20]),V(O,"click",t[23]),V(n,"click",Mt(t[35])),V(n,"keydown",Mt(t[36])),V(e,"click",t[20]),V(e,"keydown",t[50])],W=!0)},p(F,J){J[0]&65536&&o!==(o=F[16].create_network+"")&&w(a,o),J[0]&65536&&_!==(_=F[16].network_name+"")&&w(d,_),J[0]&65536&&v!==(v=F[16].network_name)&&s(p,"placeholder",v),J[0]&512&&k!==(k=!!F[9])&&s(p,"aria-invalid",k),J[0]&8&&p.value!==F[3]&&ae(p,F[3]),J[0]&512&&Ee(p,"invalid",F[9]),F[9]?N?N.p(F,J):(N=Ys(F),N.c(),N.m(n,P)):N&&(N.d(1),N=null),J[0]&65536&&y!==(y=F[16].password_opt+"")&&w(S,y),J[0]&65536&&U!==(U=F[16].password_opt)&&s(R,"placeholder",U),J[0]&16&&R.value!==F[4]&&ae(R,F[4]),F[7]?M?M.p(F,J):(M=Xs(F),M.c(),M.m(n,D)):M&&(M.d(1),M=null),J[0]&65536&&q!==(q=F[16].cancel+"")&&w(H,q),J[0]&65536&&Z!==(Z=F[16].create+"")&&w(C,Z)},d(F){F&&B(e),N&&N.d(),M&&M.d(),t[49](null),W=!1,Pe(ne)}}}function Ys(t){let e,n;return{c(){e=c("span"),n=h(t[9]),s(e,"class","field-error svelte-a1nde2"),s(e,"role","alert")},m(i,o){G(i,e,o),l(e,n)},p(i,o){o[0]&512&&w(n,i[9])},d(i){i&&B(e)}}}function Xs(t){let e,n;return{c(){e=c("div"),n=h(t[7]),s(e,"class","modal-error svelte-a1nde2"),s(e,"role","alert")},m(i,o){G(i,e,o),l(e,n)},p(i,o){o[0]&128&&w(n,i[7])},d(i){i&&B(e)}}}function Qs(t){let e,n,i,o=t[16].join_network+"",a,r,u,_=t[16].network_name+"",d,f,p,v,k,g,P,A,y=t[16].password_opt+"",S,E,R,U,b,D,K,j,q=t[16].cancel+"",H,T,O,Z=t[16].join+"",C,W,ne,N=t[10]&&Zs(t),M=t[8]&&$s(t);return{c(){e=c("div"),n=c("div"),i=c("h3"),a=h(o),r=m(),u=c("label"),d=h(_),f=m(),p=c("input"),g=m(),N&&N.c(),P=m(),A=c("label"),S=h(y),E=m(),R=c("input"),b=m(),M&&M.c(),D=m(),K=c("div"),j=c("button"),H=h(q),T=m(),O=c("button"),C=h(Z),s(i,"id","join-title"),s(i,"class","svelte-a1nde2"),s(u,"class","sr-only svelte-a1nde2"),s(u,"for","join-name"),s(p,"id","join-name"),s(p,"type","text"),s(p,"placeholder",v=t[16].network_name),s(p,"aria-invalid",k=!!t[10]),s(p,"class","svelte-a1nde2"),Ee(p,"invalid",t[10]),s(A,"class","sr-only svelte-a1nde2"),s(A,"for","join-pass"),s(R,"id","join-pass"),s(R,"type","password"),s(R,"placeholder",U=t[16].password_opt),s(R,"class","svelte-a1nde2"),s(j,"class","btn svelte-a1nde2"),s(O,"class","btn primary svelte-a1nde2"),s(K,"class","modal-actions svelte-a1nde2"),s(n,"class","modal svelte-a1nde2"),s(n,"role","dialog"),s(n,"aria-modal","true"),s(n,"aria-labelledby","join-title"),s(e,"class","modal-overlay svelte-a1nde2"),s(e,"role","presentation")},m(F,J){G(F,e,J),l(e,n),l(n,i),l(i,a),l(n,r),l(n,u),l(u,d),l(n,f),l(n,p),ae(p,t[5]),l(n,g),N&&N.m(n,null),l(n,P),l(n,A),l(A,S),l(n,E),l(n,R),ae(R,t[6]),l(n,b),M&&M.m(n,null),l(n,D),l(n,K),l(K,j),l(j,H),l(K,T),l(K,O),l(O,C),t[54](n),W||(ne=[V(p,"input",t[51]),V(R,"input",t[52]),V(j,"click",t[22]),V(O,"click",t[53]),V(n,"click",Mt(t[33])),V(n,"keydown",Mt(t[34])),V(e,"click",t[22]),V(e,"keydown",t[55])],W=!0)},p(F,J){J[0]&65536&&o!==(o=F[16].join_network+"")&&w(a,o),J[0]&65536&&_!==(_=F[16].network_name+"")&&w(d,_),J[0]&65536&&v!==(v=F[16].network_name)&&s(p,"placeholder",v),J[0]&1024&&k!==(k=!!F[10])&&s(p,"aria-invalid",k),J[0]&32&&p.value!==F[5]&&ae(p,F[5]),J[0]&1024&&Ee(p,"invalid",F[10]),F[10]?N?N.p(F,J):(N=Zs(F),N.c(),N.m(n,P)):N&&(N.d(1),N=null),J[0]&65536&&y!==(y=F[16].password_opt+"")&&w(S,y),J[0]&65536&&U!==(U=F[16].password_opt)&&s(R,"placeholder",U),J[0]&64&&R.value!==F[6]&&ae(R,F[6]),F[8]?M?M.p(F,J):(M=$s(F),M.c(),M.m(n,D)):M&&(M.d(1),M=null),J[0]&65536&&q!==(q=F[16].cancel+"")&&w(H,q),J[0]&65536&&Z!==(Z=F[16].join+"")&&w(C,Z)},d(F){F&&B(e),N&&N.d(),M&&M.d(),t[54](null),W=!1,Pe(ne)}}}function Zs(t){let e,n;return{c(){e=c("span"),n=h(t[10]),s(e,"class","field-error svelte-a1nde2"),s(e,"role","alert")},m(i,o){G(i,e,o),l(e,n)},p(i,o){o[0]&1024&&w(n,i[10])},d(i){i&&B(e)}}}function $s(t){let e,n;return{c(){e=c("div"),n=h(t[8]),s(e,"class","modal-error svelte-a1nde2"),s(e,"role","alert")},m(i,o){G(i,e,o),l(e,n)},p(i,o){o[0]&256&&w(n,i[8])},d(i){i&&B(e)}}}function so(t){let e,n,i,o=t[16].networks+"",a,r,u,_=re(t[16].network_count,{n:t[0].length})+"",d,f,p,v,k=t[16].create_network+"",g,P,A,y,S=t[16].join_network+"",E,R,U,b,D=[],K=new Map,j,q,H,T=t[16].settings+"",O,Z,C,W,ne,N,M=ut(t[0]);const F=X=>X[62].name;for(let X=0;Xn(16,i=L)),pe(t,Ae,L=>n(17,o=L)),pe(t,De,L=>n(18,a=L));let r=[],u=!1,_=!1,d="",f="",p="",v="",k="",g="",P="",A="",y="",S="",E="",R="network",U=null,b,D;on(async()=>{n(0,r=await window.go.main.App.GetSavedRooms());const L=await window.go.main.App.LoadConfig();L.serverAddr&&(y=L.serverAddr),L.nickname&&(S=L.nickname),window.addEventListener("keydown",K),window.addEventListener("click",j)}),Ei(()=>{window.removeEventListener("keydown",K),window.removeEventListener("click",j)});function K(L){if(L.key==="Escape"){if(U){n(13,U=null);return}if(u){T();return}if(_){Z();return}}}function j(){n(13,U=null)}async function q(){n(0,r=await window.go.main.App.GetSavedRooms())}function H(){n(7,k=""),n(9,P=""),n(1,u=!0),ln()}function T(){n(1,u=!1),n(7,k=""),n(9,P="")}function O(){n(8,g=""),n(10,A=""),n(2,_=!0),ln()}function Z(){n(2,_=!1),n(8,g=""),n(10,A="")}async function C(){if(n(9,P=""),n(7,k=""),!d.trim()){n(9,P=i.field_required);return}try{await window.go.main.App.CreateRoom(d,f),le(re(i.notif_created,{name:d})),Ge(Ae,o="network",o),T(),n(3,d=""),n(4,f=""),await q()}catch(L){n(7,k=re(i.error_create,{err:L})),le(k,"error")}}async function W(L,x){n(10,A=""),n(8,g="");const ee=L||p,oe=x!==void 0?x:v;if(!ee.trim()){n(10,A=i.field_required);return}try{await window.go.main.App.JoinRoom(ee,oe),le(re(i.notif_joined,{name:ee})),Ge(Ae,o="network",o),Z(),n(5,p=""),n(6,v=""),await q()}catch(Ne){n(8,g=re(i.error_join,{err:Ne})),le(g,"error"),_||(n(5,p=ee),n(6,v=""),n(2,_=!0))}}async function ne(){if(confirm(i.confirm_leave))try{await window.go.main.App.LeaveRoom(),le(i.notif_left),await q()}catch(L){le(re(i.error_leave,{err:L}),"error")}}async function N(L){const x=a.room===L;if(x){if(!confirm(i.confirm_leave_remove))return}else if(!confirm(re(i.confirm_remove,{name:L})))return;try{x&&await window.go.main.App.LeaveRoom(),await window.go.main.App.RemoveSavedRoom(L),le(re(i.notif_removed,{name:L})),await q()}catch(ee){le(re(i.error_remove,{err:ee}),"error")}}async function M(L){if(confirm(re(i.confirm_delete,{name:L})))try{await window.go.main.App.DeleteRoom(L),await window.go.main.App.RemoveSavedRoom(L),le(re(i.notif_deleted,{name:L})),await q()}catch(x){le(String(x),"error")}}async function F(L){try{const x=await window.go.main.App.FormatInvite(L.name,L.password||"");await window.go.main.App.CopyText(x);const ee=String(x).split("|"),oe=ee.length>=3&&ee[2]!=="";L.locked&&!oe?le(i.invite_no_password,"info"):le(i.invite_copied)}catch(x){le(String(x),"error")}}async function J(){try{const L=await window.go.main.App.LoadConfig();L.serverAddr&&(y=L.serverAddr),L.nickname&&(S=L.nickname)}catch{}}async function se(L,x,ee){if(!E){n(11,E=L),n(13,U=null);try{await J();const oe=ee||y;if(!a.connected){if(!oe||!S){le(i.notif_need_config,"error"),Ge(Ae,o="connect",o);return}const Ne=await window.go.main.App.Connect(oe,S);De.set(Ne),await q()}await window.go.main.App.JoinRoom(L,x||""),Ge(Ae,o="network",o),await q()}catch(oe){const Ne=re(i.error_join,{err:oe});le(Ne,"error"),n(5,p=L),n(6,v=""),n(8,g=Ne),n(2,_=!0)}finally{n(11,E="")}}}function te(L,x){(L.key==="Enter"||L.key===" ")&&(L.preventDefault(),se(x.name,x.password,x.server))}function X(L,x){L.stopPropagation(),n(13,U=U===x?null:x)}function $(L,x){L.stopPropagation(),n(13,U=null),x()}function me(L){zt.call(this,t,L)}function Se(L){zt.call(this,t,L)}function ye(L){zt.call(this,t,L)}function de(L){zt.call(this,t,L)}function ge(L){zt.call(this,t,L)}function je(L){zt.call(this,t,L)}const ke=(L,x)=>X(x,L.name),we=(L,x)=>$(x,()=>F(L)),ce=L=>$(L,ne),Ce=(L,x)=>$(x,()=>N(L.name)),he=(L,x)=>$(x,()=>M(L.name)),be=L=>se(L.name,L.password,L.server),fe=(L,x)=>te(x,L),ue=()=>{o==="settings"?Ge(Ae,o=R,o):(n(12,R=o),Ge(Ae,o="settings",o))};function ie(){d=this.value,n(3,d)}function z(){f=this.value,n(4,f)}function Q(L){Ut[L?"unshift":"push"](()=>{b=L,n(14,b)})}const st=L=>L.key==="Escape"&&T();function xe(){p=this.value,n(5,p)}function _e(){v=this.value,n(6,v)}const et=()=>W();function qe(L){Ut[L?"unshift":"push"](()=>{D=L,n(15,D)})}return[r,u,_,d,f,p,v,k,g,P,A,E,R,U,b,D,i,o,a,H,T,O,Z,C,W,ne,N,M,F,se,te,X,$,me,Se,ye,de,ge,je,ke,we,ce,Ce,he,be,fe,ue,ie,z,Q,st,xe,_e,et,qe,L=>L.key==="Escape"&&Z()]}class oo extends dt{constructor(e){super(),_t(this,e,io,so,lt,{},null,[-1,-1,-1])}}function xs(t,e,n){const i=t.slice();return i[22]=e[n],i}function ei(t){let e,n=t[4].chat+"",i,o,a,r,u,_=t[2]>0&&ti(t);return{c(){e=c("button"),i=h(n),o=m(),_&&_.c(),s(e,"class","room-chat-btn svelte-ji2phz"),s(e,"title",a=t[4].room_chat)},m(d,f){G(d,e,f),l(e,i),l(e,o),_&&_.m(e,null),r||(u=V(e,"click",t[7]),r=!0)},p(d,f){f&16&&n!==(n=d[4].chat+"")&&w(i,n),d[2]>0?_?_.p(d,f):(_=ti(d),_.c(),_.m(e,null)):_&&(_.d(1),_=null),f&16&&a!==(a=d[4].room_chat)&&s(e,"title",a)},d(d){d&&B(e),_&&_.d(),r=!1,u()}}}function ti(t){let e,n;return{c(){e=c("span"),n=h(t[2]),s(e,"class","badge unread-badge svelte-ji2phz")},m(i,o){G(i,e,o),l(e,n)},p(i,o){o&4&&w(n,i[2])},d(i){i&&B(e)}}}function ni(t){let e,n,i=t[4].no_peers+"",o,a,r,u=t[4].no_peers_desc+"",_,d;return{c(){e=c("div"),n=c("div"),o=h(i),a=m(),r=c("div"),_=h(u),d=m(),s(n,"class","empty-label svelte-ji2phz"),s(r,"class","empty-desc svelte-ji2phz"),s(e,"class","empty-peers svelte-ji2phz")},m(f,p){G(f,e,p),l(e,n),l(n,o),l(e,a),l(e,r),l(r,_),l(e,d)},p(f,p){p&16&&i!==(i=f[4].no_peers+"")&&w(o,i),p&16&&u!==(u=f[4].no_peers_desc+"")&&w(_,u)},d(f){f&&B(e)}}}function li(t){let e,n=t[10](t[22].id)+"",i;return{c(){e=c("span"),i=h(n),s(e,"class","badge unread-badge svelte-ji2phz")},m(o,a){G(o,e,a),l(e,i)},p(o,a){a&8&&n!==(n=o[10](o[22].id)+"")&&w(i,n)},d(o){o&&B(e)}}}function ao(t){let e;return{c(){e=h("...")},m(n,i){G(n,e,i)},p:ve,d(n){n&&B(e)}}}function ro(t){let e=t[22].ping+"",n,i;return{c(){n=h(e),i=h("ms")},m(o,a){G(o,n,a),G(o,i,a)},p(o,a){a&8&&e!==(e=o[22].ping+"")&&w(n,e)},d(o){o&&(B(n),B(i))}}}function co(t){let e;return{c(){e=h("-")},m(n,i){G(n,e,i)},p:ve,d(n){n&&B(e)}}}function uo(t){let e=t[4].path_unknown+"",n;return{c(){n=h(e)},m(i,o){G(i,n,o)},p(i,o){o&16&&e!==(e=i[4].path_unknown+"")&&w(n,e)},d(i){i&&B(n)}}}function _o(t){let e,n,i,o=t[11](t[22].path)+"",a;return{c(){e=c("span"),i=m(),a=h(o),s(e,"class",n="path-dot "+ii(t[22].path)+" svelte-ji2phz"),s(e,"aria-hidden","true")},m(r,u){G(r,e,u),G(r,i,u),G(r,a,u)},p(r,u){u&8&&n!==(n="path-dot "+ii(r[22].path)+" svelte-ji2phz")&&s(e,"class",n),u&8&&o!==(o=r[11](r[22].path)+"")&&w(a,o)},d(r){r&&(B(e),B(i),B(a))}}}function si(t,e){let n,i,o,a,r,u,_=(e[22].connected?e[4].status_online:e[4].status_offline)+"",d,f,p,v,k=(e[22].nickname||e[22].id)+"",g,P,A=e[10](e[22].id)>0,y,S,E=(e[22].virtualIP||e[4].na)+"",R,U,b,D,K,j,q,H,T,O,Z,C,W,ne,N,M,F,J,se,te,X,$,me,Se,ye,de=A&&li(e);function ge(){return e[18](e[22])}function je(...ie){return e[19](e[22],...ie)}function ke(ie,z){return ie[22].connected?ie[22].ping>=0&&!ie[1][ie[22].id]?ro:ao:co}let we=ke(e),ce=we(e);function Ce(ie,z){return ie[22].path?_o:uo}let he=Ce(e),be=he(e);function fe(){return e[20](e[22])}function ue(){return e[21](e[22])}return{key:t,first:null,c(){n=c("div"),i=c("span"),o=c("span"),r=m(),u=c("span"),d=h(_),f=m(),p=c("span"),v=c("span"),g=h(k),P=m(),de&&de.c(),y=m(),S=c("span"),R=h(E),U=m(),b=c("span"),ce.c(),D=m(),K=c("span"),be.c(),q=m(),H=c("span"),T=c("button"),O=Fe("svg"),Z=Fe("circle"),C=Fe("circle"),W=Fe("circle"),F=m(),J=c("button"),se=Fe("svg"),te=Fe("path"),me=m(),s(o,"class",a="sq "+(e[22].connected?"sq-online":"sq-offline")+" svelte-ji2phz"),s(o,"aria-hidden","true"),s(u,"class","status-text svelte-ji2phz"),s(i,"class","status-cell svelte-ji2phz"),s(i,"role","cell"),s(v,"class","nickname svelte-ji2phz"),s(p,"class","col-name"),s(p,"role","cell"),s(S,"class","col-ip clickable svelte-ji2phz"),s(S,"role","button"),s(S,"tabindex","0"),s(b,"class","col-ping svelte-ji2phz"),s(b,"role","cell"),Ee(b,"probing",e[22].connected&&(e[22].ping<0||e[1][e[22].id])),s(K,"class","col-path svelte-ji2phz"),s(K,"role","cell"),s(K,"title",j=e[12](e[22].path)),s(Z,"cx","8"),s(Z,"cy","8"),s(Z,"r","1.6"),s(Z,"fill","currentColor"),s(C,"cx","8"),s(C,"cy","8"),s(C,"r","4.2"),s(C,"fill","none"),s(C,"stroke","currentColor"),s(C,"stroke-width","1.2"),s(W,"cx","8"),s(W,"cy","8"),s(W,"r","6.4"),s(W,"fill","none"),s(W,"stroke","currentColor"),s(W,"stroke-width","1.1"),s(W,"opacity","0.55"),s(O,"width","14"),s(O,"height","14"),s(O,"viewBox","0 0 16 16"),s(O,"aria-hidden","true"),s(T,"class","row-btn svelte-ji2phz"),T.disabled=ne=!e[22].connected||!!e[1][e[22].id],s(T,"title",N=e[4].ping_peer),s(T,"aria-label",M=e[4].ping_peer),s(te,"d","M3 4.5h10v6.5H7.2L4 13.5V11H3z"),s(te,"fill","none"),s(te,"stroke","currentColor"),s(te,"stroke-width","1.2"),s(te,"stroke-linejoin","round"),s(se,"width","14"),s(se,"height","14"),s(se,"viewBox","0 0 16 16"),s(se,"aria-hidden","true"),s(J,"class","row-btn svelte-ji2phz"),s(J,"title",X=e[4].chat+" "+(e[22].nickname||e[22].id)),s(J,"aria-label",$=e[4].chat+" "+(e[22].nickname||e[22].id)),s(H,"class","col-action svelte-ji2phz"),s(H,"role","cell"),s(n,"class","table-row svelte-ji2phz"),s(n,"role","row"),this.first=n},m(ie,z){G(ie,n,z),l(n,i),l(i,o),l(i,r),l(i,u),l(u,d),l(n,f),l(n,p),l(p,v),l(v,g),l(p,P),de&&de.m(p,null),l(n,y),l(n,S),l(S,R),l(n,U),l(n,b),ce.m(b,null),l(n,D),l(n,K),be.m(K,null),l(n,q),l(n,H),l(H,T),l(T,O),l(O,Z),l(O,C),l(O,W),l(H,F),l(H,J),l(J,se),l(se,te),l(n,me),Se||(ye=[V(S,"click",ge),V(S,"keydown",je),V(T,"click",fe),V(J,"click",ue)],Se=!0)},p(ie,z){e=ie,z&8&&a!==(a="sq "+(e[22].connected?"sq-online":"sq-offline")+" svelte-ji2phz")&&s(o,"class",a),z&24&&_!==(_=(e[22].connected?e[4].status_online:e[4].status_offline)+"")&&w(d,_),z&8&&k!==(k=(e[22].nickname||e[22].id)+"")&&w(g,k),z&8&&(A=e[10](e[22].id)>0),A?de?de.p(e,z):(de=li(e),de.c(),de.m(p,null)):de&&(de.d(1),de=null),z&24&&E!==(E=(e[22].virtualIP||e[4].na)+"")&&w(R,E),we===(we=ke(e))&&ce?ce.p(e,z):(ce.d(1),ce=we(e),ce&&(ce.c(),ce.m(b,null))),z&10&&Ee(b,"probing",e[22].connected&&(e[22].ping<0||e[1][e[22].id])),he===(he=Ce(e))&&be?be.p(e,z):(be.d(1),be=he(e),be&&(be.c(),be.m(K,null))),z&8&&j!==(j=e[12](e[22].path))&&s(K,"title",j),z&10&&ne!==(ne=!e[22].connected||!!e[1][e[22].id])&&(T.disabled=ne),z&16&&N!==(N=e[4].ping_peer)&&s(T,"title",N),z&16&&M!==(M=e[4].ping_peer)&&s(T,"aria-label",M),z&24&&X!==(X=e[4].chat+" "+(e[22].nickname||e[22].id))&&s(J,"title",X),z&24&&$!==($=e[4].chat+" "+(e[22].nickname||e[22].id))&&s(J,"aria-label",$)},d(ie){ie&&B(n),de&&de.d(),ce.d(),be.d(),Se=!1,Pe(ye)}}}function fo(t){let e,n,i,o=t[4].header_peers+"",a,r,u,_,d,f,p,v,k,g=t[4].col_nickname+"",P,A,y,S=t[4].col_ip+"",E,R,U,b=t[4].col_ping+"",D,K,j,q=t[4].col_path+"",H,T,O,Z,C,W,ne,N,M,F=t[4].status_online+"",J,se,te,X,$=(t[5].nickname||t[4].you)+"",me,Se,ye,de=t[4].me+"",ge,je,ke,we=(t[0].virtualIP||t[4].na)+"",ce,Ce,he,be,fe,ue,ie,z,Q=[],st=new Map,xe,_e,et,qe=t[0].room&&ei(t),Me=ut(t[3]);const L=ee=>ee[22].id;for(let ee=0;een(4,a=j)),pe(t,Gl,j=>n(14,r=j)),pe(t,De,j=>n(0,u=j)),pe(t,Ol,j=>n(15,_=j)),pe(t,Ke,j=>n(5,d=j));let f={};function p(j){nn.set({id:j.id,nickname:j.nickname||j.id}),Wl("peer:"+j.id),Ae.set("chat")}function v(){nn.set(null),Wl("room:"+(u.room||"network")),Ae.set("chat")}async function k(j){if(j)try{await window.go.main.App.CopyText(j),le(a.copied)}catch{}}async function g(j){if(!(!j?.id||!j.connected||f[j.id])){n(1,f={...f,[j.id]:!0});try{await window.go.main.App.PingPeer(j.id),le(re(a.ping_sent,{name:j.nickname||j.id}))}catch(q){le(re(a.error_ping,{err:q}),"error")}finally{setTimeout(()=>{const q={...f};delete q[j.id],n(1,f=q)},800)}}}function P(j){return r["peer:"+j]||0}function A(j){return j==="p2p"?a.path_p2p:j==="relay"?a.path_relay:j==="ws"?a.path_ws:a.path_unknown}function y(j){return j==="p2p"?a.path_p2p_tip:j==="relay"?a.path_relay_tip:j==="ws"?a.path_ws_tip:""}function S(j,q){(j.key==="Enter"||j.key===" ")&&(j.preventDefault(),k(q))}const E=()=>k(u.virtualIP),R=j=>S(j,u.virtualIP),U=j=>k(j.virtualIP),b=(j,q)=>S(q,j.virtualIP),D=j=>g(j),K=j=>p(j);return t.$$.update=()=>{t.$$.dirty&32768&&n(3,i=[..._].sort((j,q)=>(j.nickname||"").localeCompare(q.nickname||""))),t.$$.dirty&16385&&n(2,o=r["room:"+(u.room||"network")]||0)},[u,f,o,i,a,d,p,v,k,g,P,A,y,S,r,_,E,R,U,b,D,K]}class vo extends dt{constructor(e){super(),_t(this,e,po,fo,lt,{})}}function oi(t){let e,n=t[2].status_reconnecting+"",i;return{c(){e=c("span"),i=h(n),s(e,"class","hint-fault svelte-3s78ew")},m(o,a){G(o,e,a),l(e,i)},p(o,a){a&4&&n!==(n=o[2].status_reconnecting+"")&&w(i,n)},d(o){o&&B(e)}}}function ai(t){let e,n=re(t[2].status_server,{s:t[3].server})+"",i,o;return{c(){e=c("span"),i=h(n),s(e,"class","status-item status-server svelte-3s78ew"),s(e,"title",o=t[3].server)},m(a,r){G(a,e,r),l(e,i)},p(a,r){r&12&&n!==(n=re(a[2].status_server,{s:a[3].server})+"")&&w(i,n),r&8&&o!==(o=a[3].server)&&s(e,"title",o)},d(a){a&&B(e)}}}function mo(t){let e,n,i,o,a,r,u=re(t[2].version,{v:t[1]})+"",_,d=t[0]==="reconnecting"&&oi(t),f=t[3].server&&ai(t);return{c(){e=c("footer"),n=c("div"),d&&d.c(),i=m(),o=c("div"),f&&f.c(),a=m(),r=c("span"),_=h(u),s(n,"class","status-left svelte-3s78ew"),s(r,"class","status-item status-ver svelte-3s78ew"),s(o,"class","status-right svelte-3s78ew"),s(e,"class","statusbar svelte-3s78ew"),s(e,"role","status"),s(e,"aria-live","polite")},m(p,v){G(p,e,v),l(e,n),d&&d.m(n,null),l(e,i),l(e,o),f&&f.m(o,null),l(o,a),l(o,r),l(r,_)},p(p,[v]){p[0]==="reconnecting"?d?d.p(p,v):(d=oi(p),d.c(),d.m(n,null)):d&&(d.d(1),d=null),p[3].server?f?f.p(p,v):(f=ai(p),f.c(),f.m(o,a)):f&&(f.d(1),f=null),v&6&&u!==(u=re(p[2].version,{v:p[1]})+"")&&w(_,u)},i:ve,o:ve,d(p){p&&B(e),d&&d.d(),f&&f.d()}}}function ho(t,e,n){let i,o;pe(t,ft,u=>n(2,i=u)),pe(t,De,u=>n(3,o=u));let{pathAggregate:a="disconnected"}=e,r="1.0.0";return on(async()=>{try{window.go?.main?.App?.GetVersion&&n(1,r=await window.go.main.App.GetVersion())}catch{}}),t.$$set=u=>{"pathAggregate"in u&&n(0,a=u.pathAggregate)},[a,r,i,o]}class go extends dt{constructor(e){super(),_t(this,e,ho,mo,lt,{pathAggregate:0})}}function ko(t){let e,n,i,o,a=t[0].server+"",r,u,_,d=t[1].server+"",f,p,v,k,g=t[0].virtual_ip+"",P,A,y,S=(t[1].virtualIP||t[0].na)+"",E,R,U,b=t[0].disconnect+"",D,K,j;function q(O,Z){return O[1].reconnecting?yo:bo}let H=q(t),T=H(t);return{c(){e=c("div"),T.c(),n=m(),i=c("div"),o=c("span"),r=h(a),u=m(),_=c("span"),f=h(d),p=m(),v=c("div"),k=c("span"),P=h(g),A=m(),y=c("span"),E=h(S),R=m(),U=c("button"),D=h(b),s(_,"class","info-value svelte-1br9j49"),s(i,"class","info-line svelte-1br9j49"),s(y,"class","info-value svelte-1br9j49"),s(v,"class","info-line svelte-1br9j49"),s(U,"class","disconnect-btn svelte-1br9j49"),s(e,"class","connected-info svelte-1br9j49")},m(O,Z){G(O,e,Z),T.m(e,null),l(e,n),l(e,i),l(i,o),l(o,r),l(i,u),l(i,_),l(_,f),l(e,p),l(e,v),l(v,k),l(k,P),l(v,A),l(v,y),l(y,E),l(e,R),l(e,U),l(U,D),K||(j=V(U,"click",t[12]),K=!0)},p(O,Z){H===(H=q(O))&&T?T.p(O,Z):(T.d(1),T=H(O),T&&(T.c(),T.m(e,n))),Z&1&&a!==(a=O[0].server+"")&&w(r,a),Z&2&&d!==(d=O[1].server+"")&&w(f,d),Z&1&&g!==(g=O[0].virtual_ip+"")&&w(P,g),Z&3&&S!==(S=(O[1].virtualIP||O[0].na)+"")&&w(E,S),Z&1&&b!==(b=O[0].disconnect+"")&&w(D,b)},d(O){O&&B(e),T.d(),K=!1,j()}}}function wo(t){let e,n,i,o=t[0].brand+"",a,r,u,_=t[0].tagline+"",d,f,p,v,k=t[0].server_addr+"",g,P,A,y,S,E,R,U,b,D=t[0].nickname+"",K,j,q,H,T,O,Z,C,W=(t[5]?t[0].connecting:t[0].connect)+"",ne,N,M,F,J,se=t[0].paste_invite+"",te,X,$,me,Se=t[0].paste_invite+"",ye,de,ge,je,ke,we,ce=t[0].join+"",Ce,he,be,fe=t[7].serverAddr&&ri(t),ue=t[7].nickname&&ci(t),ie=(t[5]||t[1].phase==="dialing"||t[1].phase==="auth")&&ui(t);return{c(){e=c("div"),n=c("div"),i=c("h1"),a=h(o),r=m(),u=c("p"),d=h(_),f=m(),p=c("div"),v=c("label"),g=h(k),P=m(),A=c("input"),E=m(),fe&&fe.c(),R=m(),U=c("div"),b=c("label"),K=h(D),j=m(),q=c("input"),O=m(),ue&&ue.c(),Z=m(),C=c("button"),ne=h(W),N=m(),ie&&ie.c(),M=m(),F=c("details"),J=c("summary"),te=h(se),X=m(),$=c("div"),me=c("label"),ye=h(Se),de=m(),ge=c("input"),ke=m(),we=c("button"),Ce=h(ce),s(i,"class","brand svelte-1br9j49"),s(u,"class","tagline svelte-1br9j49"),s(n,"class","brand-block svelte-1br9j49"),s(v,"for","server-input"),s(v,"class","svelte-1br9j49"),s(A,"id","server-input"),s(A,"type","text"),s(A,"placeholder","host:8080"),s(A,"aria-invalid",y=!!t[7].serverAddr),s(A,"aria-describedby",S=t[7].serverAddr?"server-err":void 0),s(A,"class","svelte-1br9j49"),Ee(A,"invalid",t[7].serverAddr),s(p,"class","field svelte-1br9j49"),s(b,"for","nick-input"),s(b,"class","svelte-1br9j49"),s(q,"id","nick-input"),s(q,"type","text"),s(q,"placeholder","Player"),s(q,"aria-invalid",H=!!t[7].nickname),s(q,"aria-describedby",T=t[7].nickname?"nick-err":void 0),s(q,"class","svelte-1br9j49"),Ee(q,"invalid",t[7].nickname),s(U,"class","field svelte-1br9j49"),s(C,"class","connect-btn svelte-1br9j49"),C.disabled=t[5],s(J,"class","svelte-1br9j49"),s(me,"for","invite-input"),s(me,"class","sr-only svelte-1br9j49"),s(ge,"id","invite-input"),s(ge,"type","text"),s(ge,"placeholder",je=t[0].invite_placeholder),s(ge,"class","svelte-1br9j49"),s(we,"class","secondary-btn svelte-1br9j49"),we.disabled=t[5],s($,"class","invite-block svelte-1br9j49"),s(F,"class","invite-disclosure svelte-1br9j49"),s(e,"class","connect-form svelte-1br9j49")},m(z,Q){G(z,e,Q),l(e,n),l(n,i),l(i,a),l(n,r),l(n,u),l(u,d),l(e,f),l(e,p),l(p,v),l(v,g),l(p,P),l(p,A),ae(A,t[2]),l(p,E),fe&&fe.m(p,null),l(e,R),l(e,U),l(U,b),l(b,K),l(U,j),l(U,q),ae(q,t[3]),l(U,O),ue&&ue.m(U,null),l(e,Z),l(e,C),l(C,ne),l(e,N),ie&&ie.m(e,null),l(e,M),l(e,F),l(F,J),l(J,te),l(F,X),l(F,$),l($,me),l(me,ye),l($,de),l($,ge),ae(ge,t[4]),l($,ke),l($,we),l(we,Ce),F.open=t[6],he||(be=[V(A,"input",t[13]),V(q,"input",t[14]),V(q,"keydown",t[11]),V(C,"click",t[9]),V(ge,"input",t[15]),V(we,"click",t[10]),V(F,"toggle",t[16])],he=!0)},p(z,Q){Q&1&&o!==(o=z[0].brand+"")&&w(a,o),Q&1&&_!==(_=z[0].tagline+"")&&w(d,_),Q&1&&k!==(k=z[0].server_addr+"")&&w(g,k),Q&128&&y!==(y=!!z[7].serverAddr)&&s(A,"aria-invalid",y),Q&128&&S!==(S=z[7].serverAddr?"server-err":void 0)&&s(A,"aria-describedby",S),Q&4&&A.value!==z[2]&&ae(A,z[2]),Q&128&&Ee(A,"invalid",z[7].serverAddr),z[7].serverAddr?fe?fe.p(z,Q):(fe=ri(z),fe.c(),fe.m(p,null)):fe&&(fe.d(1),fe=null),Q&1&&D!==(D=z[0].nickname+"")&&w(K,D),Q&128&&H!==(H=!!z[7].nickname)&&s(q,"aria-invalid",H),Q&128&&T!==(T=z[7].nickname?"nick-err":void 0)&&s(q,"aria-describedby",T),Q&8&&q.value!==z[3]&&ae(q,z[3]),Q&128&&Ee(q,"invalid",z[7].nickname),z[7].nickname?ue?ue.p(z,Q):(ue=ci(z),ue.c(),ue.m(U,null)):ue&&(ue.d(1),ue=null),Q&33&&W!==(W=(z[5]?z[0].connecting:z[0].connect)+"")&&w(ne,W),Q&32&&(C.disabled=z[5]),z[5]||z[1].phase==="dialing"||z[1].phase==="auth"?ie?ie.p(z,Q):(ie=ui(z),ie.c(),ie.m(e,M)):ie&&(ie.d(1),ie=null),Q&1&&se!==(se=z[0].paste_invite+"")&&w(te,se),Q&1&&Se!==(Se=z[0].paste_invite+"")&&w(ye,Se),Q&1&&je!==(je=z[0].invite_placeholder)&&s(ge,"placeholder",je),Q&16&&ge.value!==z[4]&&ae(ge,z[4]),Q&1&&ce!==(ce=z[0].join+"")&&w(Ce,ce),Q&32&&(we.disabled=z[5]),Q&64&&(F.open=z[6])},d(z){z&&B(e),fe&&fe.d(),ue&&ue.d(),ie&&ie.d(),he=!1,Pe(be)}}}function bo(t){let e,n,i,o,a=t[0].connected+"",r;return{c(){e=c("div"),n=c("span"),i=m(),o=c("span"),r=h(a),s(n,"class","sq sq-green svelte-1br9j49"),s(n,"aria-hidden","true"),s(e,"class","connected-line svelte-1br9j49"),s(e,"role","status")},m(u,_){G(u,e,_),l(e,n),l(e,i),l(e,o),l(o,r)},p(u,_){_&1&&a!==(a=u[0].connected+"")&&w(r,a)},d(u){u&&B(e)}}}function yo(t){let e,n,i,o,a=t[0].reconnecting+"",r;return{c(){e=c("div"),n=c("span"),i=m(),o=c("span"),r=h(a),s(n,"class","sq sq-warn svelte-1br9j49"),s(n,"aria-hidden","true"),s(e,"class","connected-line svelte-1br9j49"),s(e,"role","status")},m(u,_){G(u,e,_),l(e,n),l(e,i),l(e,o),l(o,r)},p(u,_){_&1&&a!==(a=u[0].reconnecting+"")&&w(r,a)},d(u){u&&B(e)}}}function ri(t){let e,n=t[7].serverAddr+"",i;return{c(){e=c("span"),i=h(n),s(e,"id","server-err"),s(e,"class","field-error svelte-1br9j49"),s(e,"role","alert")},m(o,a){G(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].serverAddr+"")&&w(i,n)},d(o){o&&B(e)}}}function ci(t){let e,n=t[7].nickname+"",i;return{c(){e=c("span"),i=h(n),s(e,"id","nick-err"),s(e,"class","field-error svelte-1br9j49"),s(e,"role","alert")},m(o,a){G(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].nickname+"")&&w(i,n)},d(o){o&&B(e)}}}function ui(t){let e,n=(t[8]||t[0].connecting)+"",i;return{c(){e=c("div"),i=h(n),s(e,"class","phase svelte-1br9j49"),s(e,"role","status")},m(o,a){G(o,e,a),l(e,i)},p(o,a){a&257&&n!==(n=(o[8]||o[0].connecting)+"")&&w(i,n)},d(o){o&&B(e)}}}function jo(t){let e;function n(a,r){return a[1].connected?ko:wo}let i=n(t),o=i(t);return{c(){e=c("div"),o.c(),s(e,"class","connect-view svelte-1br9j49")},m(a,r){G(a,e,r),o.m(e,null)},p(a,[r]){i===(i=n(a))&&o?o.p(a,r):(o.d(1),o=i(a),o&&(o.c(),o.m(e,null)))},i:ve,o:ve,d(a){a&&B(e),o.d()}}}function So(t,e,n){let i,o,a,r;pe(t,ft,b=>n(0,o=b)),pe(t,De,b=>n(1,a=b)),pe(t,Ke,b=>n(17,r=b));let u="",_="",d="",f=!1,p=!1,v={};on(async()=>{const b=await window.go.main.App.LoadConfig();b.serverAddr&&n(2,u=b.serverAddr),b.nickname&&n(3,_=b.nickname),b&&Ke.set({...r,...b}),b.autoConnect&&b.serverAddr&&b.nickname&&g()});function k(){const b={};return u.trim()||(b.serverAddr=o.field_required),_.trim()||(b.nickname=o.field_required),n(7,v=b),Object.keys(b).length===0}async function g(){if(!f&&k()){n(5,f=!0),ln();try{const b=await window.go.main.App.Connect(u,_);De.set(b),Ae.set("network"),le(re(o.notif_connected,{addr:u})),n(7,v={})}catch(b){le(re(o.error_connect,{err:b}),"error")}finally{n(5,f=!1)}}}async function P(){if(d.trim()){ln();try{const b=await window.go.main.App.ParseInvite(d.trim());if(!b.server||!b.room){le(o.error_invalid_invite,"error");return}if(n(2,u=b.server),!a.connected){if(!_.trim()){n(7,v={...v,nickname:o.field_required}),le(o.notif_need_config,"error");return}n(5,f=!0);const D=await window.go.main.App.Connect(u,_);De.set(D),n(5,f=!1)}await window.go.main.App.JoinRoom(b.room,b.password||""),le(re(o.notif_joined,{name:b.room})),Ae.set("network")}catch(b){le(re(o.error_join,{err:b}),"error"),n(5,f=!1)}}}function A(b){b.key==="Enter"&&(b.preventDefault(),g())}async function y(){if(confirm(o.confirm_disconnect))try{await window.go.main.App.Disconnect(),De.set({connected:!1,reconnecting:!1,server:"",room:"",virtualIP:"",peerCount:0,isOwner:!1,phase:"idle"}),Ae.set("connect"),le(o.notif_disconnected)}catch(b){le(re(o.error_disconnect,{err:b}),"error")}}function S(){u=this.value,n(2,u)}function E(){_=this.value,n(3,_)}function R(){d=this.value,n(4,d)}function U(){p=this.open,n(6,p)}return t.$$.update=()=>{t.$$.dirty&3&&n(8,i=a.phase==="dialing"?o.phase_dialing:a.phase==="auth"?o.phase_auth:a.phase==="ready"?o.phase_ready:a.phase==="error"?o.phase_error:"")},[o,a,u,_,d,f,p,v,i,g,P,A,y,S,E,R,U]}class qo extends dt{constructor(e){super(),_t(this,e,So,jo,lt,{})}}function _i(t,e,n){const i=t.slice();return i[23]=e[n],i[25]=n,i}function di(t){let e,n,i=t[0].no_messages+"",o,a,r,u=t[0].no_messages_desc+"",_;return{c(){e=c("div"),n=c("div"),o=h(i),a=m(),r=c("div"),_=h(u),s(n,"class","empty-chat-label svelte-dxth9d"),s(r,"class","empty-chat-desc svelte-dxth9d"),s(e,"class","empty-chat svelte-dxth9d")},m(d,f){G(d,e,f),l(e,n),l(n,o),l(e,a),l(e,r),l(r,_)},p(d,f){f&1&&i!==(i=d[0].no_messages+"")&&w(o,i),f&1&&u!==(u=d[0].no_messages_desc+"")&&w(_,u)},d(d){d&&B(e)}}}function fi(t){let e,n=t[12](t[23].timestamp)+"",i;return{c(){e=c("div"),i=h(n),s(e,"class","date-sep svelte-dxth9d")},m(o,a){G(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[12](o[23].timestamp)+"")&&w(i,n)},d(o){o&&B(e)}}}function Ao(t){let e,n,i,o=(t[23].isSelf?t[6].nickname||t[0].you_self:t[23].nickname)+"",a,r,u,_,d,f=t[23].message+"",p,v,k=t[23].status==="pending"&&pi(),g=t[23].status==="failed"&&vi(t);return{c(){e=c("div"),n=c("div"),i=c("span"),a=h(o),r=m(),k&&k.c(),u=m(),g&&g.c(),_=m(),d=c("div"),p=h(f),v=m(),s(i,"class","msg-nick"),s(n,"class","msg-meta svelte-dxth9d"),s(d,"class","msg-body svelte-dxth9d"),s(e,"class","msg svelte-dxth9d"),Ee(e,"self",t[23].isSelf)},m(P,A){G(P,e,A),l(e,n),l(n,i),l(i,a),l(n,r),k&&k.m(n,null),l(n,u),g&&g.m(n,null),l(e,_),l(e,d),l(d,p),l(e,v)},p(P,A){A&193&&o!==(o=(P[23].isSelf?P[6].nickname||P[0].you_self:P[23].nickname)+"")&&w(a,o),P[23].status==="pending"?k||(k=pi(),k.c(),k.m(n,u)):k&&(k.d(1),k=null),P[23].status==="failed"?g?g.p(P,A):(g=vi(P),g.c(),g.m(n,null)):g&&(g.d(1),g=null),A&128&&f!==(f=P[23].message+"")&&w(p,f),A&128&&Ee(e,"self",P[23].isSelf)},d(P){P&&B(e),k&&k.d(),g&&g.d()}}}function Eo(t){let e,n=t[23].message+"",i;return{c(){e=c("div"),i=h(n),s(e,"class","system-line svelte-dxth9d")},m(o,a){G(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[23].message+"")&&w(i,n)},d(o){o&&B(e)}}}function pi(t){let e;return{c(){e=c("span"),e.textContent="…",s(e,"class","msg-status")},m(n,i){G(n,e,i)},d(n){n&&B(e)}}}function vi(t){let e,n=t[0].retry+"",i,o,a;function r(){return t[18](t[23])}return{c(){e=c("button"),i=h(n),s(e,"class","retry-btn svelte-dxth9d")},m(u,_){G(u,e,_),l(e,i),o||(a=V(e,"click",r),o=!0)},p(u,_){t=u,_&1&&n!==(n=t[0].retry+"")&&w(i,n)},d(u){u&&B(e),o=!1,a()}}}function mi(t,e){let n,i=hi(e[23],e[25],e[7]),o,a,r=i&&fi(e);function u(f,p){return f[23].system?Eo:Ao}let _=u(e),d=_(e);return{key:t,first:null,c(){n=Rl(),r&&r.c(),o=m(),d.c(),a=Rl(),this.first=n},m(f,p){G(f,n,p),r&&r.m(f,p),G(f,o,p),d.m(f,p),G(f,a,p)},p(f,p){e=f,p&128&&(i=hi(e[23],e[25],e[7])),i?r?r.p(e,p):(r=fi(e),r.c(),r.m(o.parentNode,o)):r&&(r.d(1),r=null),_===(_=u(e))&&d?d.p(e,p):(d.d(1),d=_(e),d&&(d.c(),d.m(a.parentNode,a)))},d(f){f&&(B(n),B(o),B(a)),r&&r.d(f),d.d(f)}}}function Co(t){let e,n,i,o,a,r,u,_,d,f,p,v,k,g=[],P=new Map,A,y,S,E,R,U,b,D=t[0].send+"",K,j,q,H,T=t[7].length===0&&di(t),O=ut(t[7]);const Z=C=>C[23].id;for(let C=0;Cn(15,a=q)),pe(t,ft,q=>n(0,r=q)),pe(t,nn,q=>n(16,u=q)),pe(t,Ke,q=>n(6,_=q)),pe(t,Ae,q=>n(17,d=q)),pe(t,Xi,q=>n(7,f=q));let p="",v,k,g=!0;Ri(()=>{v&&g&&n(2,v.scrollTop=v.scrollHeight,v)});function P(){if(!v)return;g=v.scrollHeight-v.scrollTop-v.clientHeight<60}async function A(){const q=p.trim();if(!q)return;if(!a.connected){le(r.error_not_connected,"error");return}if(!a.room){le(r.send_disabled_no_room,"error");return}let H=q;const T=[...q];T.length>1e3&&(H=T.slice(0,1e3).join(""),le(r.msg_truncated,"info")),n(1,p=""),k&&n(3,k.style.height="auto",k);const O="local_"+Date.now()+"_"+Math.random().toString(36).slice(2,7);Hl(O,_.nickname||r.you_self,H,!0,"pending");try{u&&u.id?await window.go.main.App.SendChat(u.id,H):await window.go.main.App.BroadcastChat(H),Zt(O,"sent")}catch(Z){Zt(O,"failed"),le(re(r.error_send,{err:Z}),"error")}}async function y(q){Zt(q.id,"pending");try{u&&u.id?await window.go.main.App.SendChat(u.id,q.message):await window.go.main.App.BroadcastChat(q.message),Zt(q.id,"sent")}catch(H){Zt(q.id,"failed"),le(re(r.error_send,{err:H}),"error")}}function S(q){q.key==="Enter"&&!q.shiftKey&&(q.preventDefault(),A())}function E(q){const H=new Date(q),T=new Date,O=new Date(T.getFullYear(),T.getMonth(),T.getDate()),Z=new Date(O-864e5),C=new Date(H.getFullYear(),H.getMonth(),H.getDate());return C.getTime()===O.getTime()?r.today:C.getTime()===Z.getTime()?r.yesterday:H.toLocaleDateString([],{weekday:"long",month:"short",day:"numeric"})}function R(){k&&(n(3,k.style.height="auto",k),n(3,k.style.height=Math.min(k.scrollHeight,120)+"px",k))}function U(){nn.set(null),Ae.set("network")}const b=q=>y(q);function D(q){Ut[q?"unshift":"push"](()=>{v=q,n(2,v)})}function K(q){Ut[q?"unshift":"push"](()=>{k=q,n(3,k)})}function j(){p=this.value,n(1,p)}return t.$$.update=()=>{t.$$.dirty&131072&&d==="chat"&&Wl(sn()),t.$$.dirty&98305&&n(5,i=u?re(r.chat_with,{name:u.nickname}):re(r.room_chat_title,{room:a.room||r.network})),t.$$.dirty&32768&&n(4,o=a.connected&&!!a.room)},[r,p,v,k,o,i,_,f,P,A,y,S,E,R,U,a,u,d,b,D,K,j]}class No extends dt{constructor(e){super(),_t(this,e,Po,Co,lt,{})}}function gi(t){let e,n=t[7].notif_reconnect_required+"",i;return{c(){e=c("p"),i=h(n),s(e,"class","reconnect-banner svelte-51kqlv"),s(e,"role","status")},m(o,a){G(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].notif_reconnect_required+"")&&w(i,n)},d(o){o&&B(e)}}}function ki(t){let e,n=t[7].apply_update+"",i,o,a;return{c(){e=c("button"),i=h(n),s(e,"class","btn btn-update svelte-51kqlv"),s(e,"type","button"),e.disabled=t[3]},m(r,u){G(r,e,u),l(e,i),o||(a=V(e,"click",t[10]),o=!0)},p(r,u){u&128&&n!==(n=r[7].apply_update+"")&&w(i,n),u&8&&(e.disabled=r[3])},d(r){r&&B(e),o=!1,a()}}}function Do(t){let e,n=t[7].update_failed+"",i,o,a;return{c(){e=c("p"),i=h(n),o=h(": "),a=h(t[6]),s(e,"class","hint reconnect-hint svelte-51kqlv")},m(r,u){G(r,e,u),l(e,i),l(e,o),l(e,a)},p(r,u){u&128&&n!==(n=r[7].update_failed+"")&&w(i,n),u&64&&w(a,r[6])},d(r){r&&B(e)}}}function Lo(t){let e,n=t[7].update_downloading+"",i;return{c(){e=c("p"),i=h(n),s(e,"class","hint svelte-51kqlv")},m(o,a){G(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].update_downloading+"")&&w(i,n)},d(o){o&&B(e)}}}function zo(t){let e,n=re(t[7].update_available,{v:t[5]})+"",i;return{c(){e=c("p"),i=h(n),s(e,"class","hint svelte-51kqlv")},m(o,a){G(o,e,a),l(e,i)},p(o,a){a&160&&n!==(n=re(o[7].update_available,{v:o[5]})+"")&&w(i,n)},d(o){o&&B(e)}}}function Io(t){let e,n=t[7].update_latest+"",i;return{c(){e=c("p"),i=h(n),s(e,"class","hint svelte-51kqlv")},m(o,a){G(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].update_latest+"")&&w(i,n)},d(o){o&&B(e)}}}function Ro(t){let e,n=t[7].update_checking+"",i;return{c(){e=c("p"),i=h(n),s(e,"class","hint svelte-51kqlv")},m(o,a){G(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].update_checking+"")&&w(i,n)},d(o){o&&B(e)}}}function To(t){let e,n,i=t[7].settings_title+"",o,a,r,u,_,d,f=t[7].section_connection+"",p,v,k,g,P=t[7].server_addr+"",A,y,S,E,R,U,b=t[7].nickname+"",D,K,j,q,H,T,O=t[7].server_token+"",Z,C,W,ne,N,M,F=t[7].reconnect_apply+"",J,se,te,X,$=t[7].auto_connect+"",me,Se,ye,de,ge,je=t[7].auto_connect_desc+"",ke,we,ce,Ce,he=t[7].auto_join+"",be,fe,ue,ie,z,Q=t[7].auto_join_desc+"",st,xe,_e,et,qe=t[7].section_network+"",Me,L,x,ee=t[7].advanced_warn+"",oe,Ne,ht,Wt,an=t[7].connection_mode+"",nl,Ql,Xe,gt,rn=t[7].connection_direct+"",ll,kt,cn=t[7].connection_relay+"",sl,Zl,un,_n=t[7].connection_mode_desc+"",il,$l,wt,Ft,dn=t[7].mtu+"",ol,xl,Ue,es,fn,pn=t[7].mtu_desc+"",al,ts,bt,Kt,vn=t[7].dns_server+"",rl,ns,Qe,ls,mn,hn=t[7].dns_desc+"",cl,ss,yt,Vt,gn=t[7].socks5+"",ul,is,Ve,kn,os,wn,bn=t[7].socks5_desc+"",_l,as,jt,Jt,yn=t[7].stun_server+"",dl,rs,Ze,cs,jn,Sn=t[7].stun_desc+"",fl,us,Je,qn,An=t[7].section_system+"",pl,_s,St,En,Cn=t[7].start_windows+"",vl,ds,pt,fs,tt,Pn,Nn=t[7].updates+"",ml,ps,it,Dn=t[7].check_updates+"",hl,vs,ms,hs,We,Ln,zn=t[7].section_appearance+"",gl,gs,ot,Bt,In=t[7].ui_scale+"",kl,ks,Be,Rn,ws,Gt,Tn=(t[0].uiScale??100)+"",wl,bs,ys,On,Mn=t[7].ui_scale_desc+"",bl,js,qt,Un,Wn=t[7].theme+"",yl,Ss,nt,At,Re,qs,Fn=t[7].theme_dark+"",jl,As,Et,Te,Es,Kn=t[7].theme_light+"",Sl,Vn,Cs,Ct,Ht,Jn=t[7].language+"",ql,Ps,$e,Pt,Bn=t[7].language_en+"",Al,Nt,Gn=t[7].language_ru+"",El,Dt,Hn=t[7].language_zh+"",Cl,Ns,Ds,at,Yt,Yn=t[7].save+"",Pl,Ls,Xt,Xn=t[7].reset+"",Nl,zs,Qt,Is,Dl,Ll,zl,Rs,Le=t[2]&&gi(t),ze=t[4]==="available"&&ki(t);function Ts(I,Y){if(I[4]==="checking")return Ro;if(I[4]==="latest")return Io;if(I[4]==="available")return zo;if(I[4]==="downloading")return Lo;if(I[4]==="error"&&I[6])return Do}let Lt=Ts(t),Ie=Lt&&Lt(t);return Ll=Li(t[28][0]),{c(){e=c("div"),n=c("h2"),o=h(i),a=m(),r=c("div"),Le&&Le.c(),u=m(),_=c("div"),d=c("div"),p=h(f),v=m(),k=c("div"),g=c("label"),A=h(P),y=m(),S=c("input"),E=m(),R=c("div"),U=c("label"),D=h(b),K=m(),j=c("input"),q=m(),H=c("div"),T=c("label"),Z=h(O),C=m(),W=c("input"),N=m(),M=c("p"),J=h(F),se=m(),te=c("label"),X=c("span"),me=h($),Se=m(),ye=c("input"),de=m(),ge=c("span"),ke=h(je),we=m(),ce=c("label"),Ce=c("span"),be=h(he),fe=m(),ue=c("input"),ie=m(),z=c("span"),st=h(Q),xe=m(),_e=c("div"),et=c("div"),Me=h(qe),L=m(),x=c("p"),oe=h(ee),Ne=m(),ht=c("div"),Wt=c("label"),nl=h(an),Ql=m(),Xe=c("select"),gt=c("option"),ll=h(rn),kt=c("option"),sl=h(cn),Zl=m(),un=c("p"),il=h(_n),$l=m(),wt=c("div"),Ft=c("label"),ol=h(dn),xl=m(),Ue=c("input"),es=m(),fn=c("p"),al=h(pn),ts=m(),bt=c("div"),Kt=c("label"),rl=h(vn),ns=m(),Qe=c("input"),ls=m(),mn=c("p"),cl=h(hn),ss=m(),yt=c("div"),Vt=c("label"),ul=h(gn),is=m(),Ve=c("input"),os=m(),wn=c("p"),_l=h(bn),as=m(),jt=c("div"),Jt=c("label"),dl=h(yn),rs=m(),Ze=c("input"),cs=m(),jn=c("p"),fl=h(Sn),us=m(),Je=c("div"),qn=c("div"),pl=h(An),_s=m(),St=c("label"),En=c("span"),vl=h(Cn),ds=m(),pt=c("input"),fs=m(),tt=c("div"),Pn=c("span"),ml=h(Nn),ps=m(),it=c("button"),hl=h(Dn),vs=m(),ze&&ze.c(),ms=m(),Ie&&Ie.c(),hs=m(),We=c("div"),Ln=c("div"),gl=h(zn),gs=m(),ot=c("div"),Bt=c("label"),kl=h(In),ks=m(),Be=c("input"),ws=m(),Gt=c("span"),wl=h(Tn),bs=h("%"),ys=m(),On=c("p"),bl=h(Mn),js=m(),qt=c("div"),Un=c("span"),yl=h(Wn),Ss=m(),nt=c("div"),At=c("label"),Re=c("input"),qs=m(),jl=h(Fn),As=m(),Et=c("label"),Te=c("input"),Es=m(),Sl=h(Kn),Cs=m(),Ct=c("div"),Ht=c("label"),ql=h(Jn),Ps=m(),$e=c("select"),Pt=c("option"),Al=h(Bn),Nt=c("option"),El=h(Gn),Dt=c("option"),Cl=h(Hn),Ds=m(),at=c("div"),Yt=c("button"),Pl=h(Yn),Ls=m(),Xt=c("button"),Nl=h(Xn),zs=m(),Qt=c("div"),Is=h("v"),Dl=h(t[1]),s(n,"class","settings-title svelte-51kqlv"),s(d,"class","section-title svelte-51kqlv"),s(g,"class","setting-label svelte-51kqlv"),s(g,"for","cfg-server"),s(S,"id","cfg-server"),s(S,"type","text"),s(S,"placeholder","vps.example.com:8080"),s(S,"class","svelte-51kqlv"),s(k,"class","setting-row svelte-51kqlv"),s(U,"class","setting-label svelte-51kqlv"),s(U,"for","cfg-nick"),s(j,"id","cfg-nick"),s(j,"type","text"),s(j,"placeholder","Your nickname"),s(j,"class","svelte-51kqlv"),s(R,"class","setting-row svelte-51kqlv"),s(T,"class","setting-label svelte-51kqlv"),s(T,"for","cfg-token"),s(W,"id","cfg-token"),s(W,"type","password"),s(W,"placeholder",ne=t[7].server_token_desc),s(W,"class","svelte-51kqlv"),s(H,"class","setting-row svelte-51kqlv"),s(M,"class","hint reconnect-hint svelte-51kqlv"),s(X,"class","setting-label svelte-51kqlv"),s(ye,"type","checkbox"),s(ye,"class","svelte-51kqlv"),s(ge,"class","toggle-label svelte-51kqlv"),s(te,"class","setting-row toggle-row svelte-51kqlv"),s(Ce,"class","setting-label svelte-51kqlv"),s(ue,"type","checkbox"),s(ue,"class","svelte-51kqlv"),s(z,"class","toggle-label svelte-51kqlv"),s(ce,"class","setting-row toggle-row svelte-51kqlv"),s(_,"class","section svelte-51kqlv"),s(et,"class","section-title svelte-51kqlv"),s(x,"class","hint svelte-51kqlv"),s(Wt,"class","setting-label svelte-51kqlv"),s(Wt,"for","cfg-conn"),gt.__value="direct",ae(gt,gt.__value),kt.__value="relay",ae(kt,kt.__value),s(Xe,"id","cfg-conn"),s(Xe,"class","svelte-51kqlv"),t[0].connectionMode===void 0&&$n(()=>t[21].call(Xe)),s(ht,"class","setting-row svelte-51kqlv"),s(un,"class","hint svelte-51kqlv"),s(Ft,"class","setting-label svelte-51kqlv"),s(Ft,"for","cfg-mtu"),s(Ue,"id","cfg-mtu"),s(Ue,"type","number"),s(Ue,"min","576"),s(Ue,"max","9000"),s(Ue,"placeholder","1500"),s(Ue,"class","svelte-51kqlv"),s(wt,"class","setting-row svelte-51kqlv"),s(fn,"class","hint svelte-51kqlv"),s(Kt,"class","setting-label svelte-51kqlv"),s(Kt,"for","cfg-dns"),s(Qe,"id","cfg-dns"),s(Qe,"type","text"),s(Qe,"placeholder","system default"),s(Qe,"class","svelte-51kqlv"),s(bt,"class","setting-row svelte-51kqlv"),s(mn,"class","hint svelte-51kqlv"),s(Vt,"class","setting-label svelte-51kqlv"),s(Vt,"for","cfg-socks"),s(Ve,"id","cfg-socks"),s(Ve,"type","text"),s(Ve,"placeholder",kn=t[7].socks5_placeholder),s(Ve,"class","svelte-51kqlv"),s(yt,"class","setting-row svelte-51kqlv"),s(wn,"class","hint reconnect-hint svelte-51kqlv"),s(Jt,"class","setting-label svelte-51kqlv"),s(Jt,"for","cfg-stun"),s(Ze,"id","cfg-stun"),s(Ze,"type","text"),s(Ze,"placeholder","stun.l.google.com:19302"),s(Ze,"class","svelte-51kqlv"),s(jt,"class","setting-row svelte-51kqlv"),s(jn,"class","hint reconnect-hint svelte-51kqlv"),s(_e,"class","section svelte-51kqlv"),s(qn,"class","section-title svelte-51kqlv"),s(En,"class","setting-label svelte-51kqlv"),s(pt,"type","checkbox"),s(pt,"class","svelte-51kqlv"),s(St,"class","setting-row toggle-row svelte-51kqlv"),s(Pn,"class","setting-label svelte-51kqlv"),s(it,"class","btn btn-check svelte-51kqlv"),s(it,"type","button"),it.disabled=t[3],s(tt,"class","setting-row update-row svelte-51kqlv"),s(Je,"class","section svelte-51kqlv"),s(Ln,"class","section-title svelte-51kqlv"),s(Bt,"class","setting-label svelte-51kqlv"),s(Bt,"for","cfg-scale"),s(Be,"id","cfg-scale"),s(Be,"type","range"),s(Be,"min","75"),s(Be,"max","150"),s(Be,"step","5"),Be.value=Rn=t[0].uiScale??100,s(Be,"class","svelte-51kqlv"),s(Gt,"class","scale-value svelte-51kqlv"),s(ot,"class","setting-row scale-row svelte-51kqlv"),s(On,"class","hint svelte-51kqlv"),s(Un,"class","setting-label svelte-51kqlv"),s(Re,"type","radio"),Re.__value="dark",ae(Re,Re.__value),s(At,"class","radio-option svelte-51kqlv"),s(Te,"type","radio"),Te.__value="light",ae(Te,Te.__value),s(Et,"class","radio-option svelte-51kqlv"),s(nt,"class","radio-group svelte-51kqlv"),s(nt,"role","radiogroup"),s(nt,"aria-label",Vn=t[7].theme),s(qt,"class","setting-row radio-row svelte-51kqlv"),s(Ht,"class","setting-label svelte-51kqlv"),s(Ht,"for","cfg-lang"),Pt.__value="en",ae(Pt,Pt.__value),Nt.__value="ru",ae(Nt,Nt.__value),Dt.__value="zh",ae(Dt,Dt.__value),s($e,"id","cfg-lang"),s($e,"class","svelte-51kqlv"),s(Ct,"class","setting-row svelte-51kqlv"),s(We,"class","section svelte-51kqlv"),s(Yt,"class","btn btn-save svelte-51kqlv"),s(Xt,"class","btn btn-reset svelte-51kqlv"),s(Qt,"class","ver svelte-51kqlv"),s(at,"class","section actions-section svelte-51kqlv"),s(r,"class","settings-content svelte-51kqlv"),s(e,"class","settings-view svelte-51kqlv"),Ll.p(Re,Te)},m(I,Y){G(I,e,Y),l(e,n),l(n,o),l(e,a),l(e,r),Le&&Le.m(r,null),l(r,u),l(r,_),l(_,d),l(d,p),l(_,v),l(_,k),l(k,g),l(g,A),l(k,y),l(k,S),ae(S,t[0].serverAddr),l(_,E),l(_,R),l(R,U),l(U,D),l(R,K),l(R,j),ae(j,t[0].nickname),l(_,q),l(_,H),l(H,T),l(T,Z),l(H,C),l(H,W),ae(W,t[0].serverToken),l(_,N),l(_,M),l(M,J),l(_,se),l(_,te),l(te,X),l(X,me),l(te,Se),l(te,ye),ye.checked=t[0].autoConnect,l(te,de),l(te,ge),l(ge,ke),l(_,we),l(_,ce),l(ce,Ce),l(Ce,be),l(ce,fe),l(ce,ue),ue.checked=t[0].autoJoinLastRoom,l(ce,ie),l(ce,z),l(z,st),l(r,xe),l(r,_e),l(_e,et),l(et,Me),l(_e,L),l(_e,x),l(x,oe),l(_e,Ne),l(_e,ht),l(ht,Wt),l(Wt,nl),l(ht,Ql),l(ht,Xe),l(Xe,gt),l(gt,ll),l(Xe,kt),l(kt,sl),Qn(Xe,t[0].connectionMode,!0),l(_e,Zl),l(_e,un),l(un,il),l(_e,$l),l(_e,wt),l(wt,Ft),l(Ft,ol),l(wt,xl),l(wt,Ue),ae(Ue,t[0].mtu),l(_e,es),l(_e,fn),l(fn,al),l(_e,ts),l(_e,bt),l(bt,Kt),l(Kt,rl),l(bt,ns),l(bt,Qe),ae(Qe,t[0].dnsServer),l(_e,ls),l(_e,mn),l(mn,cl),l(_e,ss),l(_e,yt),l(yt,Vt),l(Vt,ul),l(yt,is),l(yt,Ve),ae(Ve,t[0].socks5Proxy),l(_e,os),l(_e,wn),l(wn,_l),l(_e,as),l(_e,jt),l(jt,Jt),l(Jt,dl),l(jt,rs),l(jt,Ze),ae(Ze,t[0].stunServer),l(_e,cs),l(_e,jn),l(jn,fl),l(r,us),l(r,Je),l(Je,qn),l(qn,pl),l(Je,_s),l(Je,St),l(St,En),l(En,vl),l(St,ds),l(St,pt),pt.checked=t[0].startWithWindows,l(Je,fs),l(Je,tt),l(tt,Pn),l(Pn,ml),l(tt,ps),l(tt,it),l(it,hl),l(tt,vs),ze&&ze.m(tt,null),l(Je,ms),Ie&&Ie.m(Je,null),l(r,hs),l(r,We),l(We,Ln),l(Ln,gl),l(We,gs),l(We,ot),l(ot,Bt),l(Bt,kl),l(ot,ks),l(ot,Be),l(ot,ws),l(ot,Gt),l(Gt,wl),l(Gt,bs),l(We,ys),l(We,On),l(On,bl),l(We,js),l(We,qt),l(qt,Un),l(Un,yl),l(qt,Ss),l(qt,nt),l(nt,At),l(At,Re),Re.checked=Re.__value===t[0].theme,l(At,qs),l(At,jl),l(nt,As),l(nt,Et),l(Et,Te),Te.checked=Te.__value===t[0].theme,l(Et,Es),l(Et,Sl),l(We,Cs),l(We,Ct),l(Ct,Ht),l(Ht,ql),l(Ct,Ps),l(Ct,$e),l($e,Pt),l(Pt,Al),l($e,Nt),l(Nt,El),l($e,Dt),l(Dt,Cl),Qn($e,t[0].lang||t[8]),l(r,Ds),l(r,at),l(at,Yt),l(Yt,Pl),l(at,Ls),l(at,Xt),l(Xt,Nl),l(at,zs),l(at,Qt),l(Qt,Is),l(Qt,Dl),zl||(Rs=[V(S,"input",t[16]),V(j,"input",t[17]),V(W,"input",t[18]),V(ye,"change",t[19]),V(ue,"change",t[20]),V(Xe,"change",t[21]),V(Ue,"input",t[22]),V(Qe,"input",t[23]),V(Ve,"input",t[24]),V(Ze,"input",t[25]),V(pt,"change",t[26]),V(it,"click",t[9]),V(Be,"input",t[13]),V(Re,"change",t[27]),V(Re,"change",t[15]),V(Te,"change",t[29]),V(Te,"change",t[15]),V($e,"change",t[14]),V(Yt,"click",t[11]),V(Xt,"click",t[12])],zl=!0)},p(I,[Y]){Y&128&&i!==(i=I[7].settings_title+"")&&w(o,i),I[2]?Le?Le.p(I,Y):(Le=gi(I),Le.c(),Le.m(r,u)):Le&&(Le.d(1),Le=null),Y&128&&f!==(f=I[7].section_connection+"")&&w(p,f),Y&128&&P!==(P=I[7].server_addr+"")&&w(A,P),Y&1&&S.value!==I[0].serverAddr&&ae(S,I[0].serverAddr),Y&128&&b!==(b=I[7].nickname+"")&&w(D,b),Y&1&&j.value!==I[0].nickname&&ae(j,I[0].nickname),Y&128&&O!==(O=I[7].server_token+"")&&w(Z,O),Y&128&&ne!==(ne=I[7].server_token_desc)&&s(W,"placeholder",ne),Y&1&&W.value!==I[0].serverToken&&ae(W,I[0].serverToken),Y&128&&F!==(F=I[7].reconnect_apply+"")&&w(J,F),Y&128&&$!==($=I[7].auto_connect+"")&&w(me,$),Y&1&&(ye.checked=I[0].autoConnect),Y&128&&je!==(je=I[7].auto_connect_desc+"")&&w(ke,je),Y&128&&he!==(he=I[7].auto_join+"")&&w(be,he),Y&1&&(ue.checked=I[0].autoJoinLastRoom),Y&128&&Q!==(Q=I[7].auto_join_desc+"")&&w(st,Q),Y&128&&qe!==(qe=I[7].section_network+"")&&w(Me,qe),Y&128&&ee!==(ee=I[7].advanced_warn+"")&&w(oe,ee),Y&128&&an!==(an=I[7].connection_mode+"")&&w(nl,an),Y&128&&rn!==(rn=I[7].connection_direct+"")&&w(ll,rn),Y&128&&cn!==(cn=I[7].connection_relay+"")&&w(sl,cn),Y&1&&Qn(Xe,I[0].connectionMode),Y&128&&_n!==(_n=I[7].connection_mode_desc+"")&&w(il,_n),Y&128&&dn!==(dn=I[7].mtu+"")&&w(ol,dn),Y&1&&Ai(Ue.value)!==I[0].mtu&&ae(Ue,I[0].mtu),Y&128&&pn!==(pn=I[7].mtu_desc+"")&&w(al,pn),Y&128&&vn!==(vn=I[7].dns_server+"")&&w(rl,vn),Y&1&&Qe.value!==I[0].dnsServer&&ae(Qe,I[0].dnsServer),Y&128&&hn!==(hn=I[7].dns_desc+"")&&w(cl,hn),Y&128&&gn!==(gn=I[7].socks5+"")&&w(ul,gn),Y&128&&kn!==(kn=I[7].socks5_placeholder)&&s(Ve,"placeholder",kn),Y&1&&Ve.value!==I[0].socks5Proxy&&ae(Ve,I[0].socks5Proxy),Y&128&&bn!==(bn=I[7].socks5_desc+"")&&w(_l,bn),Y&128&&yn!==(yn=I[7].stun_server+"")&&w(dl,yn),Y&1&&Ze.value!==I[0].stunServer&&ae(Ze,I[0].stunServer),Y&128&&Sn!==(Sn=I[7].stun_desc+"")&&w(fl,Sn),Y&128&&An!==(An=I[7].section_system+"")&&w(pl,An),Y&128&&Cn!==(Cn=I[7].start_windows+"")&&w(vl,Cn),Y&1&&(pt.checked=I[0].startWithWindows),Y&128&&Nn!==(Nn=I[7].updates+"")&&w(ml,Nn),Y&128&&Dn!==(Dn=I[7].check_updates+"")&&w(hl,Dn),Y&8&&(it.disabled=I[3]),I[4]==="available"?ze?ze.p(I,Y):(ze=ki(I),ze.c(),ze.m(tt,null)):ze&&(ze.d(1),ze=null),Lt===(Lt=Ts(I))&&Ie?Ie.p(I,Y):(Ie&&Ie.d(1),Ie=Lt&&Lt(I),Ie&&(Ie.c(),Ie.m(Je,null))),Y&128&&zn!==(zn=I[7].section_appearance+"")&&w(gl,zn),Y&128&&In!==(In=I[7].ui_scale+"")&&w(kl,In),Y&1&&Rn!==(Rn=I[0].uiScale??100)&&(Be.value=Rn),Y&1&&Tn!==(Tn=(I[0].uiScale??100)+"")&&w(wl,Tn),Y&128&&Mn!==(Mn=I[7].ui_scale_desc+"")&&w(bl,Mn),Y&128&&Wn!==(Wn=I[7].theme+"")&&w(yl,Wn),Y&1&&(Re.checked=Re.__value===I[0].theme),Y&128&&Fn!==(Fn=I[7].theme_dark+"")&&w(jl,Fn),Y&1&&(Te.checked=Te.__value===I[0].theme),Y&128&&Kn!==(Kn=I[7].theme_light+"")&&w(Sl,Kn),Y&128&&Vn!==(Vn=I[7].theme)&&s(nt,"aria-label",Vn),Y&128&&Jn!==(Jn=I[7].language+"")&&w(ql,Jn),Y&128&&Bn!==(Bn=I[7].language_en+"")&&w(Al,Bn),Y&128&&Gn!==(Gn=I[7].language_ru+"")&&w(El,Gn),Y&128&&Hn!==(Hn=I[7].language_zh+"")&&w(Cl,Hn),Y&257&&Ns!==(Ns=I[0].lang||I[8])&&Qn($e,I[0].lang||I[8]),Y&128&&Yn!==(Yn=I[7].save+"")&&w(Pl,Yn),Y&128&&Xn!==(Xn=I[7].reset+"")&&w(Nl,Xn),Y&2&&w(Dl,I[1])},i:ve,o:ve,d(I){I&&B(e),Le&&Le.d(),ze&&ze.d(),Ie&&Ie.d(),Ll.r(),zl=!1,Pe(Rs)}}}function Oo(t,e,n){let i,o,a;pe(t,Ke,N=>n(30,i=N)),pe(t,ft,N=>n(7,o=N)),pe(t,Xl,N=>n(8,a=N));let r={...i},u="1.0.0",_=!1,d=!1,f="",p="",v="";async function k(){n(3,d=!0),n(4,f="checking"),n(6,v=""),n(5,p="");try{const N=await window.go.main.App.CheckForUpdate();N?.available?(n(4,f="available"),n(5,p=N.latest||"")):n(4,f="latest")}catch(N){n(4,f="error"),n(6,v=String(N)),le(o.error_update_check+N,"error")}finally{n(3,d=!1)}}async function g(){if(confirm(o.confirm_update)){n(3,d=!0),n(4,f="downloading"),n(6,v="");try{await window.go.main.App.ApplyUpdate(),le(o.notif_updating,"info")}catch(N){n(4,f="error"),n(6,v=String(N)),n(3,d=!1),le(o.error_update+N,"error")}}}async function P(){Ge(Ke,i={...r},i);try{n(2,_=!!await window.go.main.App.SaveSettings(r)),r.lang&&$t(r.lang),le(o.notif_settings_saved,"info"),_&&le(o.notif_reconnect_required,"info")}catch(N){le(o.error_save+N,"error")}}async function A(){if(confirm(o.confirm_reset))try{n(0,r=await window.go.main.App.ResetSettings()),Ge(Ke,i={...r},i),n(2,_=!1),r.lang&&$t(r.lang),le(o.notif_settings_saved,"info")}catch(N){le(o.error_save+N,"error")}}function y(N){const M=Math.min(150,Math.max(75,Number(N.target.value)||100));n(0,r.uiScale=M,r),Ge(Ke,i={...i,uiScale:M},i)}function S(N){n(0,r.lang=N.target.value,r),$t(N.target.value)}function E(){Ge(Ke,i={...i,theme:r.theme},i)}on(async()=>{try{const N=await window.go.main.App.GetSettings();N&&(n(0,r={...r,...N}),r.connectionMode||n(0,r.connectionMode="direct",r),Ge(Ke,i=r,i),r.lang&&$t(r.lang)),window.go.main.App.GetVersion&&n(1,u=await window.go.main.App.GetVersion())}catch{}});const R=[[]];function U(){r.serverAddr=this.value,n(0,r)}function b(){r.nickname=this.value,n(0,r)}function D(){r.serverToken=this.value,n(0,r)}function K(){r.autoConnect=this.checked,n(0,r)}function j(){r.autoJoinLastRoom=this.checked,n(0,r)}function q(){r.connectionMode=Ii(this),n(0,r)}function H(){r.mtu=Ai(this.value),n(0,r)}function T(){r.dnsServer=this.value,n(0,r)}function O(){r.socks5Proxy=this.value,n(0,r)}function Z(){r.stunServer=this.value,n(0,r)}function C(){r.startWithWindows=this.checked,n(0,r)}function W(){r.theme=this.__value,n(0,r)}function ne(){r.theme=this.__value,n(0,r)}return[r,u,_,d,f,p,v,o,a,k,g,P,A,y,S,E,U,b,D,K,j,q,H,T,O,Z,C,W,R,ne]}class Mo extends dt{constructor(e){super(),_t(this,e,Oo,To,lt,{})}}function Uo(t){let e,n,i=t[1].brand+"",o,a,r,u,_,d=t[1].header_room+"",f,p,v,k=(t[3].room||t[1].na)+"",g,P,A,y,S=t[1].header_vip+"",E,R,U,b=(t[3].virtualIP||t[1].na)+"",D,K,j,q,H,T=t[1].header_path+"",O,Z,C,W,ne,N,M,F,J,se,te,X=t[1].header_peers+"",$,me,Se,ye=re(t[1].peer_count,{n:t[3].peerCount??0})+"",de,ge,je,ke,we=t[1].settings+"",ce,Ce,he,be=t[1].disconnect+"",fe,ue,ie;return{c(){e=c("header"),n=c("span"),o=h(i),a=m(),r=c("div"),u=c("div"),_=c("span"),f=h(d),p=m(),v=c("span"),g=h(k),P=m(),A=c("div"),y=c("span"),E=h(S),R=m(),U=c("button"),D=h(b),j=m(),q=c("div"),H=c("span"),O=h(T),Z=m(),C=c("span"),W=c("span"),N=m(),M=c("span"),F=h(t[2]),J=m(),se=c("div"),te=c("span"),$=h(X),me=m(),Se=c("span"),de=h(ye),ge=m(),je=c("div"),ke=c("button"),ce=h(we),Ce=m(),he=c("button"),fe=h(be),s(n,"class","wordmark svelte-s9thm6"),s(_,"class","cap svelte-s9thm6"),s(v,"class","val svelte-s9thm6"),s(u,"class","fact svelte-s9thm6"),s(y,"class","cap svelte-s9thm6"),s(U,"type","button"),s(U,"class","val mono vip svelte-s9thm6"),s(U,"title",K=t[1].virtual_ip),s(A,"class","fact svelte-s9thm6"),s(H,"class","cap svelte-s9thm6"),s(W,"class",ne="path-dot "+t[0]+" svelte-s9thm6"),s(W,"aria-hidden","true"),s(M,"class","val mono svelte-s9thm6"),s(C,"class","path-row svelte-s9thm6"),s(q,"class","fact path-fact svelte-s9thm6"),s(te,"class","cap svelte-s9thm6"),s(Se,"class","val svelte-s9thm6"),s(se,"class","fact svelte-s9thm6"),s(r,"class","facts svelte-s9thm6"),s(ke,"type","button"),s(ke,"class","btn"),s(he,"type","button"),s(he,"class","btn danger"),s(je,"class","actions svelte-s9thm6"),s(e,"class","band svelte-s9thm6")},m(z,Q){G(z,e,Q),l(e,n),l(n,o),l(e,a),l(e,r),l(r,u),l(u,_),l(_,f),l(u,p),l(u,v),l(v,g),l(r,P),l(r,A),l(A,y),l(y,E),l(A,R),l(A,U),l(U,D),l(r,j),l(r,q),l(q,H),l(H,O),l(q,Z),l(q,C),l(C,W),l(C,N),l(C,M),l(M,F),l(r,J),l(r,se),l(se,te),l(te,$),l(se,me),l(se,Se),l(Se,de),l(e,ge),l(e,je),l(je,ke),l(ke,ce),l(je,Ce),l(je,he),l(he,fe),ue||(ie=[V(U,"click",t[4]),V(ke,"click",t[6]),V(he,"click",t[5])],ue=!0)},p(z,[Q]){Q&2&&i!==(i=z[1].brand+"")&&w(o,i),Q&2&&d!==(d=z[1].header_room+"")&&w(f,d),Q&10&&k!==(k=(z[3].room||z[1].na)+"")&&w(g,k),Q&2&&S!==(S=z[1].header_vip+"")&&w(E,S),Q&10&&b!==(b=(z[3].virtualIP||z[1].na)+"")&&w(D,b),Q&2&&K!==(K=z[1].virtual_ip)&&s(U,"title",K),Q&2&&T!==(T=z[1].header_path+"")&&w(O,T),Q&1&&ne!==(ne="path-dot "+z[0]+" svelte-s9thm6")&&s(W,"class",ne),Q&4&&w(F,z[2]),Q&2&&X!==(X=z[1].header_peers+"")&&w($,X),Q&10&&ye!==(ye=re(z[1].peer_count,{n:z[3].peerCount??0})+"")&&w(de,ye),Q&2&&we!==(we=z[1].settings+"")&&w(ce,we),Q&2&&be!==(be=z[1].disconnect+"")&&w(fe,be)},i:ve,o:ve,d(z){z&&B(e),ue=!1,Pe(ie)}}}function Wo(t,e,n){let i,o,a;pe(t,ft,f=>n(1,o=f)),pe(t,De,f=>n(3,a=f));let{pathAggregate:r="disconnected"}=e;async function u(){const f=a.virtualIP;if(f)try{await window.go.main.App.CopyText(f),le(o.copied)}catch{}}async function _(){if(confirm(o.confirm_disconnect))try{await window.go.main.App.Disconnect(),De.set({connected:!1,reconnecting:!1,server:"",room:"",virtualIP:"",peerCount:0,isOwner:!1,phase:"idle"}),Ae.set("connect"),le(o.notif_disconnected)}catch(f){le(re(o.error_disconnect,{err:f}),"error")}}const d=()=>Ae.set("settings");return t.$$set=f=>{"pathAggregate"in f&&n(0,r=f.pathAggregate)},t.$$.update=()=>{t.$$.dirty&3&&n(2,i=r==="direct"?o.path_p2p:r==="relay"?o.path_relay:r==="reconnecting"?o.status_reconnecting:o.status_disconnected)},[r,o,i,a,u,_,d]}class Fo extends dt{constructor(e){super(),_t(this,e,Wo,Uo,lt,{pathAggregate:0})}}function wi(t,e,n){const i=t.slice();return i[16]=e[n],i}function bi(t){let e,n,i;return{c(){e=c("div"),n=m(),i=c("div"),s(e,"class","space-bg"),s(e,"aria-hidden","true"),s(i,"class","space-dust"),s(i,"aria-hidden","true")},m(o,a){G(o,e,a),G(o,n,a),G(o,i,a)},d(o){o&&(B(e),B(n),B(i))}}}function Ko(t){let e,n,i,o,a,r,u,_,d,f,p,v,k,g,P,A,y,S;n=new Fo({props:{pathAggregate:t[3]}}),r=new oo({});const E=[Ho,Go,Bo,Jo],R=[];function U(b,D){return b[0]==="network"?0:b[0]==="chat"?1:b[0]==="settings"?2:3}return v=U(t),k=R[v]=E[v](t),P=new go({props:{pathAggregate:t[3]}}),{c(){e=c("div"),mt(n.$$.fragment),i=m(),o=c("div"),a=c("div"),mt(r.$$.fragment),u=m(),_=c("div"),d=m(),f=c("main"),p=c("div"),k.c(),g=m(),mt(P.$$.fragment),s(_,"class","drag-handle svelte-rf9j86"),Ee(_,"active",t[2]),s(a,"class","sidebar-wrapper svelte-rf9j86"),Ms(a,"width",t[1]+"px"),s(p,"class","view-fade svelte-rf9j86"),s(p,"key",t[0]),s(f,"class","main-area svelte-rf9j86"),s(o,"class","layout svelte-rf9j86"),s(e,"class","shell connected-shell svelte-rf9j86")},m(b,D){G(b,e,D),rt(n,e,null),l(e,i),l(e,o),l(o,a),rt(r,a,null),l(a,u),l(a,_),l(o,d),l(o,f),l(f,p),R[v].m(p,null),l(e,g),rt(P,e,null),A=!0,y||(S=V(_,"mousedown",t[7]),y=!0)},p(b,D){const K={};D&8&&(K.pathAggregate=b[3]),n.$set(K),(!A||D&4)&&Ee(_,"active",b[2]),(!A||D&2)&&Ms(a,"width",b[1]+"px");let j=v;v=U(b),v===j?R[v].p(b,D):(Pi(),He(R[j],1,1,()=>{R[j]=null}),Ni(),k=R[v],k?k.p(b,D):(k=R[v]=E[v](b),k.c()),Oe(k,1),k.m(p,null)),(!A||D&1)&&s(p,"key",b[0]);const q={};D&8&&(q.pathAggregate=b[3]),P.$set(q)},i(b){A||(Oe(n.$$.fragment,b),Oe(r.$$.fragment,b),Oe(k),Oe(P.$$.fragment,b),A=!0)},o(b){He(n.$$.fragment,b),He(r.$$.fragment,b),He(k),He(P.$$.fragment,b),A=!1},d(b){b&&B(e),ct(n),ct(r),R[v].d(),ct(P),y=!1,S()}}}function Vo(t){let e,n,i,o;return i=new qo({}),{c(){e=c("div"),n=c("div"),mt(i.$$.fragment),s(n,"class","fullscreen-connect svelte-rf9j86"),s(e,"class","shell connect-shell svelte-rf9j86")},m(a,r){G(a,e,r),l(e,n),rt(i,n,null),o=!0},p:ve,i(a){o||(Oe(i.$$.fragment,a),o=!0)},o(a){He(i.$$.fragment,a),o=!1},d(a){a&&B(e),ct(i)}}}function Jo(t){let e,n,i;return{c(){e=c("div"),n=h("Unknown view: "),i=h(t[0]),s(e,"class","unknown-view svelte-rf9j86")},m(o,a){G(o,e,a),l(e,n),l(e,i)},p(o,a){a&1&&w(i,o[0])},i:ve,o:ve,d(o){o&&B(e)}}}function Bo(t){let e,n;return e=new Mo({}),{c(){mt(e.$$.fragment)},m(i,o){rt(e,i,o),n=!0},p:ve,i(i){n||(Oe(e.$$.fragment,i),n=!0)},o(i){He(e.$$.fragment,i),n=!1},d(i){ct(e,i)}}}function Go(t){let e,n;return e=new No({}),{c(){mt(e.$$.fragment)},m(i,o){rt(e,i,o),n=!0},p:ve,i(i){n||(Oe(e.$$.fragment,i),n=!0)},o(i){He(e.$$.fragment,i),n=!1},d(i){ct(e,i)}}}function Ho(t){let e,n;return e=new vo({}),{c(){mt(e.$$.fragment)},m(i,o){rt(e,i,o),n=!0},p:ve,i(i){n||(Oe(e.$$.fragment,i),n=!0)},o(i){He(e.$$.fragment,i),n=!1},d(i){ct(e,i)}}}function yi(t){let e,n,i=t[5].msg+"",o,a,r,u=t[4].dismiss_error+"",_,d,f,p;return{c(){e=c("div"),n=c("span"),o=h(i),a=m(),r=c("button"),_=h(u),s(n,"class","error-strip-msg svelte-rf9j86"),s(r,"type","button"),s(r,"class","error-strip-dismiss svelte-rf9j86"),s(r,"aria-label",d=t[4].dismiss_error),s(e,"class","error-strip svelte-rf9j86"),s(e,"role","alert")},m(v,k){G(v,e,k),l(e,n),l(n,o),l(e,a),l(e,r),l(r,_),f||(p=V(r,"click",ln),f=!0)},p(v,k){k&32&&i!==(i=v[5].msg+"")&&w(o,i),k&16&&u!==(u=v[4].dismiss_error+"")&&w(_,u),k&16&&d!==(d=v[4].dismiss_error)&&s(r,"aria-label",d)},d(v){v&&B(e),f=!1,p()}}}function ji(t,e){let n,i,o=e[16].type==="error"?"!":">",a,r,u=e[16].msg+"",_,d,f;return{key:t,first:null,c(){n=c("div"),i=c("span"),a=h(o),r=m(),_=h(u),d=m(),s(i,"class","notif-icon svelte-rf9j86"),s(n,"class",f="notification "+e[16].type+" svelte-rf9j86"),s(n,"role","status"),this.first=n},m(p,v){G(p,n,v),l(n,i),l(i,a),l(n,r),l(n,_),l(n,d)},p(p,v){e=p,v&64&&o!==(o=e[16].type==="error"?"!":">")&&w(a,o),v&64&&u!==(u=e[16].msg+"")&&w(_,u),v&64&&f!==(f="notification "+e[16].type+" svelte-rf9j86")&&s(n,"class",f)},d(p){p&&B(n)}}}function Yo(t){let e,n,i,o,a,r=[],u=new Map,_,d,f=t[0]==="connect"&&bi();const p=[Vo,Ko],v=[];function k(y,S){return y[0]==="connect"?0:1}n=k(t),i=v[n]=p[n](t);let g=t[5]&&yi(t),P=ut(t[6]);const A=y=>y[16].id;for(let y=0;y{v[E]=null}),Ni(),i=v[n],i?i.p(y,S):(i=v[n]=p[n](y),i.c()),Oe(i,1),i.m(o.parentNode,o)),y[5]?g?g.p(y,S):(g=yi(y),g.c(),g.m(a.parentNode,a)):g&&(g.d(1),g=null),S&64&&(P=ut(y[6]),r=tl(r,S,A,1,y,P,u,_.parentNode,el,ji,_,wi))},i(y){d||(Oe(i),d=!0)},o(y){He(i),d=!1},d(y){y&&(B(e),B(o),B(a),B(_)),f&&f.d(y),v[n].d(y),g&&g.d(y);for(let S=0;Sn(4,o=E)),pe(t,Ke,E=>n(8,a=E)),pe(t,Ol,E=>n(9,r=E)),pe(t,De,E=>n(10,u=E)),pe(t,Ae,E=>n(0,_=E)),pe(t,xn,E=>n(5,d=E)),pe(t,Ml,E=>n(6,f=E));let p=220,v=!1,k,g,P=!0;function A(E){n(2,v=!0),k=E.clientX,g=p,document.addEventListener("mousemove",y),document.addEventListener("mouseup",S),E.preventDefault()}function y(E){if(!v)return;const R=g+(E.clientX-k);n(1,p=Math.max(140,Math.min(400,R)))}function S(){n(2,v=!1),document.removeEventListener("mousemove",y),document.removeEventListener("mouseup",S)}return on(async()=>{window.addEventListener("keydown",Si);try{const E=await window.go.main.App.LoadConfig();E&&(Ke.set({...a,...E}),E.lang&&$t(E.lang))}catch{}window.runtime?.EventsOn&&(window.runtime.EventsOn("status_changed",E=>{P&&(De.set(E),!E.connected&&!E.reconnecting&&Ae.set("connect"))}),window.runtime.EventsOn("peers_changed",E=>{P&&Ol.set(E||[])}),window.runtime.EventsOn("error",E=>{P&&le(E,"error")}),window.runtime.EventsOn("chat_message",E=>{P&&Hl(E.fromID,E.nickname,E.message,!1,"sent",!1,!!E.isDM)}),window.runtime.EventsOn("system_chat",E=>{P&&Yi(E.message||"")}),window.runtime.EventsOn("room_deleted",E=>{P&&(le(o.notif_room_deleted,"error"),Ae.set("network"))}),window.runtime.EventsOn("auto_join_skipped",E=>{if(!P)return;const R=E?.room||"";le(re(o.notif_auto_join_skipped,{name:R}),"info")}))}),Ei(()=>{P=!1,window.removeEventListener("keydown",Si),document.removeEventListener("mousemove",y),document.removeEventListener("mouseup",S),window.runtime?.EventsOff&&(window.runtime.EventsOff("status_changed"),window.runtime.EventsOff("peers_changed"),window.runtime.EventsOff("error"),window.runtime.EventsOff("chat_message"),window.runtime.EventsOff("system_chat"),window.runtime.EventsOff("room_deleted"),window.runtime.EventsOff("auto_join_skipped"))}),t.$$.update=()=>{if(t.$$.dirty&256){const E=Xo(a.uiScale)/100;document.documentElement.style.zoom=String(E)}t.$$.dirty&256&&(a.theme==="light"?document.documentElement.classList.add("light-theme"):document.documentElement.classList.remove("light-theme")),t.$$.dirty&1&&document.documentElement.setAttribute("data-app",_==="connect"?"connect":"connected"),t.$$.dirty&1536&&n(3,i=xi(u,r))},[_,p,v,i,o,d,f,A,a,r,u]}class Zo extends dt{constructor(e){super(),_t(this,e,Qo,Yo,lt,{})}}new Zo({target:document.getElementById("app")}); diff --git a/client/frontend/dist/index.html b/client/frontend/dist/index.html index da5e5ee..626b484 100644 --- a/client/frontend/dist/index.html +++ b/client/frontend/dist/index.html @@ -7,8 +7,8 @@ Entangled VPN - - + +
diff --git a/client/frontend/src/App.svelte b/client/frontend/src/App.svelte index 5c46983..203c489 100644 --- a/client/frontend/src/App.svelte +++ b/client/frontend/src/App.svelte @@ -2,12 +2,14 @@ import { onMount, onDestroy } from 'svelte' import { status, peers, view, settings, notifications, durableError, clearDurableError, addNotification, addChatMessage, addSystemChat } from './lib/stores/app.js' import { currentLang, setLang, t, fmt } from './lib/locales/index.js' + import { derivePathAggregate } from './lib/path.js' import Sidebar from './lib/components/Sidebar.svelte' import PeerList from './lib/components/PeerList.svelte' import StatusBar from './lib/components/StatusBar.svelte' import ConnectView from './lib/components/ConnectView.svelte' import ChatView from './lib/components/ChatView.svelte' import SettingsView from './lib/components/SettingsView.svelte' + import ConnectedHeader from './lib/components/ConnectedHeader.svelte' function clampScale(n) { const v = Number(n) || 100 @@ -27,6 +29,13 @@ } } + $: document.documentElement.setAttribute( + 'data-app', + $view === 'connect' ? 'connect' : 'connected', + ) + + $: pathAggregate = derivePathAggregate($status, $peers) + let sidebarWidth = 220 let isDragging = false let startX, startWidth @@ -127,8 +136,10 @@ }) - - +{#if $view === 'connect'} + + +{/if} {#if $view === 'connect'}
@@ -137,7 +148,16 @@
{:else} -
+
+ +
- +
{/if} @@ -197,6 +217,9 @@ .connect-shell { z-index: 1; } + .connected-shell { + background: var(--bg-primary); + } .layout { display: flex; flex: 1; diff --git a/client/frontend/src/app.css b/client/frontend/src/app.css index 8e245a1..c599898 100644 --- a/client/frontend/src/app.css +++ b/client/frontend/src/app.css @@ -1,4 +1,5 @@ @import './space.css'; +@import './connected.css'; @font-face { font-family: 'Bungee'; diff --git a/client/frontend/src/connected.css b/client/frontend/src/connected.css new file mode 100644 index 0000000..f7ce2aa --- /dev/null +++ b/client/frontend/src/connected.css @@ -0,0 +1,158 @@ +/* Connected Operate shell. Intro keeps :root / Bungee / space.css. */ + +html[data-app="connected"] { + --bg-deep: #0a0a0a; + --bg-primary: #0a0a0a; + --bg-surface: #111111; + --bg-raised: #181818; + --bg-hover: #1c1c1c; + --bg-active: #222222; + --border-deep: #1a1a1a; + --border: #2a2a2a; + --border-light: #3a3a3a; + --border-hover: #4a4a4a; + --text-bright: #f0f0f0; + --text-primary: #f0f0f0; + --text-secondary: #8a8a8a; + --text-muted: #8a8a8a; + --text-dim: #5c5c5c; + --accent: #ffffff; + --accent-hover: #f0f0f0; + --accent-ink: #0a0a0a; + --live: #2fbf62; + --fault: #e23d3d; + --success: #8a8a8a; + --warning: #8a8a8a; + --error: #e23d3d; + --focus-ring: #f0f0f0; + --font-sans: ui-sans-serif, 'Segoe UI', system-ui, sans-serif; + --font-mono: ui-monospace, 'Cascadia Code', Consolas, monospace; + --font-size: 13px; + --font-size-sm: 12px; + --font-size-xs: 10px; + --line-height: 1.45; + --radius-sm: 4px; + --radius-md: 6px; + --statusbar-height: 26px; +} + +html[data-app="connected"].light-theme { + --bg-deep: #f5f5f5; + --bg-primary: #f5f5f5; + --bg-surface: #ececec; + --bg-raised: #e4e4e4; + --bg-hover: #dedede; + --bg-active: #d6d6d6; + --border-deep: #e0e0e0; + --border: #d0d0d0; + --border-light: #c4c4c4; + --border-hover: #999999; + --text-bright: #111111; + --text-primary: #111111; + --text-secondary: #5c5c5c; + --text-muted: #6a6a6a; + --text-dim: #8a8a8a; + --accent: #111111; + --accent-hover: #000000; + --accent-ink: #f5f5f5; + --live: #1a8f45; + --fault: #c41e1e; + --success: #6a6a6a; + --warning: #6a6a6a; + --error: #c41e1e; + --focus-ring: #111111; +} + +html[data-app="connected"], +html[data-app="connected"] body, +html[data-app="connected"] #app { + color: var(--text-primary); + font-family: var(--font-sans); + font-size: var(--font-size); + line-height: var(--line-height); + background: var(--bg-deep); +} + +html[data-app="connected"] input, +html[data-app="connected"] textarea, +html[data-app="connected"] button, +html[data-app="connected"] select { + font-family: inherit; +} + +html[data-app="connected"] .btn { + padding: 6px 12px; + min-height: 32px; + height: 32px; + border: 1px solid var(--border); + border-radius: var(--radius-md); + background: transparent; + color: var(--text-primary); + cursor: pointer; + font-size: var(--font-size-sm); + text-align: center; + font-family: var(--font-sans); + transition: background 0.12s ease, border-color 0.12s ease, opacity 0.12s ease; +} + +html[data-app="connected"] .btn:hover:not(:disabled) { + background: var(--bg-hover); + border-color: var(--border-hover); +} + +html[data-app="connected"] .btn.primary, +html[data-app="connected"] .btn-save { + background: var(--accent); + border-color: var(--accent); + color: var(--accent-ink); + font-weight: 500; +} + +html[data-app="connected"] .btn.primary:hover, +html[data-app="connected"] .btn-save:hover { + background: var(--accent-hover); +} + +html[data-app="connected"] .btn:disabled { + opacity: 0.4; + cursor: not-allowed; +} + +html[data-app="connected"] .btn.danger { + color: var(--fault); + border-color: var(--fault); +} + +html[data-app="connected"] .path-dot { + width: 8px; + height: 8px; + border-radius: 50%; + display: inline-block; + flex-shrink: 0; + background: var(--text-dim); +} + +html[data-app="connected"] .path-dot.direct { + background: var(--live); +} + +html[data-app="connected"] .path-dot.relay, +html[data-app="connected"] .path-dot.reconnecting, +html[data-app="connected"] .path-dot.disconnected { + background: var(--fault); +} + +html[data-app="connected"] .unread-badge { + background: var(--fault); + color: #fff; +} + +@media (prefers-reduced-motion: reduce) { + html[data-app="connected"] *, + html[data-app="connected"] *::before, + html[data-app="connected"] *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } +} diff --git a/client/frontend/src/lib/components/ChatView.svelte b/client/frontend/src/lib/components/ChatView.svelte index e2a6055..b0d48e8 100644 --- a/client/frontend/src/lib/components/ChatView.svelte +++ b/client/frontend/src/lib/components/ChatView.svelte @@ -128,14 +128,17 @@
- + {title}
{#if $chatMessages.length === 0}
-
[ . . . ]
{$t.no_messages}
{$t.no_messages_desc}
@@ -197,9 +200,9 @@ justify-content: center; background: transparent; border: 1px solid var(--border); + border-radius: var(--radius-sm, 4px); color: var(--text-secondary); cursor: pointer; - font-family: var(--font-mono); } .chat-title { color: var(--text-bright); @@ -245,6 +248,7 @@ padding: 8px 10px; background: var(--bg-raised); border: 1px solid var(--border); + border-radius: var(--radius-sm, 4px); color: var(--text-primary); white-space: pre-wrap; word-break: break-word; @@ -273,9 +277,10 @@ resize: none; background: var(--bg-raised); border: 1px solid var(--border); + border-radius: var(--radius-sm, 4px); color: var(--text-primary); padding: 8px 10px; - font-family: var(--font-mono); + font-family: inherit; font-size: var(--font-size); min-height: 36px; } @@ -284,9 +289,10 @@ background: var(--accent); color: var(--accent-ink); border: none; + border-radius: var(--radius-md, 6px); padding: 0 16px; cursor: pointer; - font-family: var(--font-mono); + font-family: inherit; text-transform: uppercase; } .send-btn:disabled { opacity: 0.4; cursor: not-allowed; } diff --git a/client/frontend/src/lib/components/ConnectedHeader.svelte b/client/frontend/src/lib/components/ConnectedHeader.svelte new file mode 100644 index 0000000..3997614 --- /dev/null +++ b/client/frontend/src/lib/components/ConnectedHeader.svelte @@ -0,0 +1,150 @@ + + +
+ {$t.brand} + +
+
+ {$t.header_room} + {$status.room || $t.na} +
+
+ {$t.header_vip} + +
+
+ {$t.header_path} + + + {pathLabel} + +
+
+ {$t.header_peers} + {fmt($t.peer_count, { n: $status.peerCount ?? 0 })} +
+
+ +
+ + +
+
+ + diff --git a/client/frontend/src/lib/components/PeerList.svelte b/client/frontend/src/lib/components/PeerList.svelte index 8107a91..0f3d3cf 100644 --- a/client/frontend/src/lib/components/PeerList.svelte +++ b/client/frontend/src/lib/components/PeerList.svelte @@ -6,7 +6,6 @@ $: sortedPeers = [...$peers].sort((a, b) => (a.nickname || '').localeCompare(b.nickname || '')) $: roomUnread = $unread['room:' + ($status.room || 'network')] || 0 - $: anyRelay = $peers.some(p => p.path === 'relay' || p.path === 'ws') function openPeerChat(peer) { chatTarget.set({ id: peer.id, nickname: peer.nickname || peer.id }) @@ -56,6 +55,12 @@ return $t.path_unknown } + function pathTone(path) { + if (path === 'p2p') return 'direct' + if (path === 'relay' || path === 'ws') return 'relay' + return '' + } + function pathTip(path) { if (path === 'p2p') return $t.path_p2p_tip if (path === 'relay') return $t.path_relay_tip @@ -73,19 +78,13 @@
-

{$status.room || $t.network}

- +

{$t.header_peers}

{#if $status.room} {/if} - {#if anyRelay} - {$t.status_relay_degraded} - {/if}
@@ -127,7 +126,7 @@ {peer.nickname || peer.id} - {#if peerUnread(peer.id) > 0}{peerUnread(peer.id)}{/if} + {#if peerUnread(peer.id) > 0}{peerUnread(peer.id)}{/if} {peer.path ? pathLabel(peer.path) : $t.path_unknown} + > + {#if peer.path} + + {pathLabel(peer.path)} + {:else} + {$t.path_unknown} + {/if} + + > + + + > + +
{:else}
-
[ . . . ]
{$t.no_peers}
{$t.no_peers_desc}
@@ -192,29 +207,19 @@ flex-wrap: wrap; } .peer-header h2 { - font-size: var(--font-size); - font-weight: 500; - color: var(--text-bright); + font-size: 10px; + font-weight: 600; + color: var(--text-dim); text-transform: uppercase; - letter-spacing: 0.5px; + letter-spacing: 0.08em; } - .ip-badge { - padding: 4px 8px; - min-height: 28px; - background: var(--bg-raised); - font-size: var(--font-size-xs); - font-family: var(--font-mono); - color: var(--text-secondary); - border: 1px solid var(--border); - cursor: pointer; - } - .ip-badge:hover { border-color: var(--border-hover); color: var(--text-bright); } .room-chat-btn { margin-left: auto; background: transparent; border: 1px solid var(--border); + border-radius: var(--radius-md, 6px); color: var(--text-secondary); - font-family: var(--font-mono); + font-family: inherit; font-size: var(--font-size-xs); padding: 6px 10px; min-height: 32px; @@ -222,17 +227,13 @@ position: relative; } .room-chat-btn:hover { color: var(--text-bright); border-color: var(--border-hover); } - .relay-hint { - font-size: var(--font-size-xs); - color: var(--text-muted); - } .badge { display: inline-block; min-width: 14px; padding: 0 4px; margin-left: 4px; - background: var(--accent); - color: var(--accent-ink); + background: var(--fault, var(--error)); + color: #fff; font-size: 10px; line-height: 14px; text-align: center; @@ -245,7 +246,7 @@ } .table-row { display: grid; - grid-template-columns: minmax(56px, 72px) minmax(72px, 1fr) minmax(88px, 110px) minmax(48px, 70px) minmax(52px, 72px) minmax(64px, 80px); + grid-template-columns: minmax(56px, 72px) minmax(72px, 1fr) minmax(88px, 110px) minmax(48px, 70px) minmax(72px, 96px) minmax(64px, 80px); gap: 8px; align-items: center; padding: 10px 16px; @@ -258,7 +259,7 @@ color: var(--text-muted); text-transform: uppercase; font-size: var(--font-size-xs); - letter-spacing: 0.4px; + letter-spacing: 0.08em; } .self-row { background: var(--bg-surface); } .nickname { color: var(--text-bright); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } @@ -271,6 +272,11 @@ font-family: var(--font-mono); color: var(--text-secondary); } + .col-path { + display: flex; + align-items: center; + gap: 6px; + } .col-ping.probing { color: var(--text-bright); } .clickable { cursor: pointer; } .clickable:hover { color: var(--text-bright); } @@ -286,10 +292,11 @@ .sq { width: 8px; height: 8px; + border-radius: 50%; display: inline-block; flex-shrink: 0; } - .sq-online { background: var(--success); } + .sq-online { background: var(--text-bright); } .sq-offline { background: var(--text-dim); } .col-action { display: flex; @@ -299,12 +306,15 @@ .row-btn { background: transparent; border: none; + border-radius: var(--radius-sm, 4px); color: var(--text-muted); cursor: pointer; - font-family: var(--font-mono); min-width: 32px; min-height: 32px; padding: 0; + display: flex; + align-items: center; + justify-content: center; } .row-btn:hover:not(:disabled) { color: var(--text-bright); } .row-btn:disabled { diff --git a/client/frontend/src/lib/components/SettingsView.svelte b/client/frontend/src/lib/components/SettingsView.svelte index 16909ea..a0113e7 100644 --- a/client/frontend/src/lib/components/SettingsView.svelte +++ b/client/frontend/src/lib/components/SettingsView.svelte @@ -114,7 +114,7 @@

{$t.notif_reconnect_required}

{/if}
-
─── {$t.section_connection} ───
+
{$t.section_connection}
@@ -146,7 +146,7 @@
-
─── {$t.section_network} ───
+
{$t.section_network}

{$t.advanced_warn}

@@ -184,7 +184,7 @@
-
─── {$t.section_system} ───
+
{$t.section_system}
-
─── {$t.section_appearance} ───
+
{$t.section_appearance}
@@ -279,11 +279,11 @@ height: 0; } .settings-title { - font-size: var(--font-size); - color: var(--text-bright); + font-size: 10px; + font-weight: 600; + color: var(--text-dim); text-transform: uppercase; - letter-spacing: 1px; - font-weight: 500; + letter-spacing: 0.08em; margin-bottom: 20px; } .reconnect-banner { @@ -296,9 +296,12 @@ } .section { margin-bottom: 24px; } .section-title { - font-size: var(--font-size-xs); - color: var(--text-muted); - letter-spacing: 1px; + font-size: 10px; + font-weight: 600; + color: var(--text-dim); + letter-spacing: 0.08em; + text-transform: uppercase; + margin-bottom: 10px; } .hint { font-size: var(--font-size-xs); @@ -327,9 +330,10 @@ flex: 1; background: var(--bg-raised); border: 1px solid var(--border); + border-radius: var(--radius-sm, 4px); color: var(--text-primary); padding: 8px 10px; - min-height: 36px; + min-height: 32px; font-family: var(--font-mono); font-size: var(--font-size-sm); } @@ -359,9 +363,9 @@ font-family: var(--font-mono); } .actions-section { display: flex; gap: 8px; align-items: center; } - .actions-section .btn { min-height: 36px; padding: 8px 14px; } + .actions-section .btn { min-height: 32px; padding: 6px 12px; } .update-row { flex-wrap: wrap; } - .update-row .btn { min-height: 36px; padding: 8px 14px; } + .update-row .btn { min-height: 32px; padding: 6px 12px; } .btn-check, .btn-update { background: var(--bg-raised); border: 1px solid var(--border); diff --git a/client/frontend/src/lib/components/Sidebar.svelte b/client/frontend/src/lib/components/Sidebar.svelte index 8eec7ea..6d0210f 100644 --- a/client/frontend/src/lib/components/Sidebar.svelte +++ b/client/frontend/src/lib/components/Sidebar.svelte @@ -296,7 +296,11 @@ aria-label={$t.more_actions} title={$t.more_actions} on:click={(e) => toggleMenu(e, room.name)} - >⋯ + > {#if menuOpen === room.name}
-
- {#if $view === 'network'} - - {:else if $view === 'chat'} - - {:else if $view === 'settings'} - - {:else} -
Unknown view: {$view}
- {/if} -
+ {#key $view} +
+ {#if $view === 'network'} + + {:else if $view === 'chat'} + + {:else if $view === 'settings'} + + {:else} +
Unknown view: {$view}
+ {/if} +
+ {/key}
@@ -266,17 +268,23 @@ min-width: 0; min-height: 0; } - .view-fade { + .view-pane { flex: 1; display: flex; flex-direction: column; min-height: 0; min-width: 0; - animation: viewIn 0.2s ease-out; + animation: viewIn 180ms var(--ease-out, ease-out) both; } @keyframes viewIn { - 0% { opacity: 0; transform: translateY(8px); } - 100% { opacity: 1; transform: translateY(0); } + from { + opacity: 0; + transform: translateY(4px); + } + to { + opacity: 1; + transform: translateY(0); + } } .unknown-view { padding: 40px; @@ -317,6 +325,10 @@ .error-strip-dismiss:hover { background: rgba(196, 92, 92, 0.12); } + @keyframes slideIn { + from { transform: translateX(12px); opacity: 0; } + to { transform: translateX(0); opacity: 1; } + } .notification { position: fixed; top: 12px; @@ -327,7 +339,7 @@ background: var(--bg-raised); border: 1px solid var(--border); color: var(--text-primary); - animation: slideIn 0.15s ease-out; + animation: slideIn 160ms var(--ease-out, ease-out) both; } .notification.error { border-color: var(--error); @@ -340,8 +352,4 @@ margin-right: 6px; font-weight: 700; } - @keyframes slideIn { - from { transform: translateX(100%); opacity: 0; } - to { transform: translateX(0); opacity: 1; } - } diff --git a/client/frontend/src/connected.css b/client/frontend/src/connected.css index f7ce2aa..30efdd6 100644 --- a/client/frontend/src/connected.css +++ b/client/frontend/src/connected.css @@ -34,6 +34,9 @@ html[data-app="connected"] { --radius-sm: 4px; --radius-md: 6px; --statusbar-height: 26px; + --ease-out: cubic-bezier(0.16, 1, 0.3, 1); + --dur-fast: 120ms; + --dur-mid: 180ms; } html[data-app="connected"].light-theme { @@ -92,7 +95,11 @@ html[data-app="connected"] .btn { font-size: var(--font-size-sm); text-align: center; font-family: var(--font-sans); - transition: background 0.12s ease, border-color 0.12s ease, opacity 0.12s ease; + transition: + background var(--dur-fast) ease, + border-color var(--dur-fast) ease, + opacity var(--dur-fast) ease, + transform var(--dur-fast) ease; } html[data-app="connected"] .btn:hover:not(:disabled) { @@ -100,6 +107,10 @@ html[data-app="connected"] .btn:hover:not(:disabled) { border-color: var(--border-hover); } +html[data-app="connected"] .btn:active:not(:disabled) { + transform: translateY(1px); +} + html[data-app="connected"] .btn.primary, html[data-app="connected"] .btn-save { background: var(--accent); @@ -137,17 +148,42 @@ html[data-app="connected"] .path-dot.direct { } html[data-app="connected"] .path-dot.relay, -html[data-app="connected"] .path-dot.reconnecting, -html[data-app="connected"] .path-dot.disconnected { +html[data-app="connected"] .path-dot.reconnecting { background: var(--fault); } +html[data-app="connected"] .path-dot.reconnecting { + animation: pathPulse 1.2s var(--ease-out) infinite; +} + +html[data-app="connected"] .path-dot.disconnected { + background: var(--text-dim); +} + html[data-app="connected"] .unread-badge { background: var(--fault); color: #fff; } +@keyframes pathPulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.35; } +} + +html[data-app="connected"] .connected-shell { + animation: shellIn var(--dur-mid) var(--ease-out) both; +} + +@keyframes shellIn { + from { opacity: 0; } + to { opacity: 1; } +} + @media (prefers-reduced-motion: reduce) { + html[data-app="connected"] { + --dur-fast: 0.01ms; + --dur-mid: 0.01ms; + } html[data-app="connected"] *, html[data-app="connected"] *::before, html[data-app="connected"] *::after { diff --git a/client/frontend/src/lib/components/ConnectedHeader.svelte b/client/frontend/src/lib/components/ConnectedHeader.svelte index 3997614..682ed13 100644 --- a/client/frontend/src/lib/components/ConnectedHeader.svelte +++ b/client/frontend/src/lib/components/ConnectedHeader.svelte @@ -4,12 +4,23 @@ export let pathAggregate = 'disconnected' + let prevView = 'network' + $: pathLabel = pathAggregate === 'direct' ? $t.path_p2p : pathAggregate === 'relay' ? $t.path_relay : pathAggregate === 'reconnecting' ? $t.status_reconnecting : $t.status_disconnected + function toggleSettings() { + if ($view === 'settings') { + view.set(prevView || 'network') + } else { + prevView = $view + view.set('settings') + } + } + async function copyVip() { const ip = $status.virtualIP if (!ip) return @@ -69,7 +80,12 @@
- +
@@ -147,4 +163,9 @@ flex-shrink: 0; margin-left: auto; } + .btn.active { + border-color: var(--border-hover); + background: var(--bg-hover); + color: var(--text-bright); + } diff --git a/client/frontend/src/lib/components/PeerList.svelte b/client/frontend/src/lib/components/PeerList.svelte index 0f3d3cf..a6e3112 100644 --- a/client/frontend/src/lib/components/PeerList.svelte +++ b/client/frontend/src/lib/components/PeerList.svelte @@ -254,6 +254,10 @@ border-bottom: 1px solid var(--border-deep); font-size: var(--font-size-sm); min-width: 520px; + transition: background var(--dur-fast, 120ms) ease; + } + .table-row:not(.table-header-row):hover { + background: var(--bg-hover); } .table-header-row { color: var(--text-muted); diff --git a/client/frontend/src/lib/components/Sidebar.svelte b/client/frontend/src/lib/components/Sidebar.svelte index 6d0210f..2bf3b80 100644 --- a/client/frontend/src/lib/components/Sidebar.svelte +++ b/client/frontend/src/lib/components/Sidebar.svelte @@ -17,7 +17,6 @@ let serverAddr = '' let nickname = '' let joining = '' - let prevView = 'network' let menuOpen = null let createDialog let joinDialog @@ -331,19 +330,6 @@ {/each}
- - {#if showCreate}