Improve frontend response time

This commit is contained in:
Jack Kingsman committed 2026-02-03 15:58:52 -08:00
1 parent c167e59a64
commit b302bd74ff
17 files changed
+1015 -777

No files matched your search

+14
View File
@@ -227,6 +227,20 @@ class BotConfig(BaseModel):
code: str = Field(default="", description="Python code for this bot")
class UnreadCounts(BaseModel):
"""Aggregated unread counts, mention flags, and last message times for all conversations."""
counts: dict[str, int] = Field(
default_factory=dict, description="Map of stateKey -> unread count"
)
mentions: dict[str, bool] = Field(
default_factory=dict, description="Map of stateKey -> has mention"
)
last_message_times: dict[str, int] = Field(
default_factory=dict, description="Map of stateKey -> last message timestamp"
)
class AppSettings(BaseModel):
"""Application settings stored in the database."""
+80
View File
@@ -550,6 +550,86 @@ class MessageRepository:
return result
@staticmethod
async def get_unread_counts(name: str | None = None) -> dict:
"""Get unread message counts, mention flags, and last message times for all conversations.
Args:
name: User's display name for @[name] mention detection. If None, mentions are skipped.
Returns:
Dict with 'counts', 'mentions', and 'last_message_times' keys.
"""
counts: dict[str, int] = {}
mention_flags: dict[str, bool] = {}
last_message_times: dict[str, int] = {}
mention_pattern = f"%@[{name}]%" if name else None
# Channel unreads
cursor = await db.conn.execute(
"""
SELECT m.conversation_key,
COUNT(*) as unread_count,
MAX(m.received_at) as last_message_time,
SUM(CASE WHEN m.text LIKE ? THEN 1 ELSE 0 END) > 0 as has_mention
FROM messages m
JOIN channels c ON m.conversation_key = c.key
WHERE m.type = 'CHAN' AND m.outgoing = 0
AND m.received_at > COALESCE(c.last_read_at, 0)
GROUP BY m.conversation_key
""",
(mention_pattern or "",),
)
rows = await cursor.fetchall()
for row in rows:
state_key = f"channel-{row['conversation_key']}"
counts[state_key] = row["unread_count"]
if mention_pattern and row["has_mention"]:
mention_flags[state_key] = True
# Contact unreads
cursor = await db.conn.execute(
"""
SELECT m.conversation_key,
COUNT(*) as unread_count,
MAX(m.received_at) as last_message_time,
SUM(CASE WHEN m.text LIKE ? THEN 1 ELSE 0 END) > 0 as has_mention
FROM messages m
JOIN contacts ct ON m.conversation_key = ct.public_key
WHERE m.type = 'PRIV' AND m.outgoing = 0
AND m.received_at > COALESCE(ct.last_read_at, 0)
GROUP BY m.conversation_key
""",
(mention_pattern or "",),
)
rows = await cursor.fetchall()
for row in rows:
state_key = f"contact-{row['conversation_key']}"
counts[state_key] = row["unread_count"]
if mention_pattern and row["has_mention"]:
mention_flags[state_key] = True
# Last message times for all conversations (including read ones)
cursor = await db.conn.execute(
"""
SELECT type, conversation_key, MAX(received_at) as last_message_time
FROM messages
GROUP BY type, conversation_key
"""
)
rows = await cursor.fetchall()
for row in rows:
prefix = "channel" if row["type"] == "CHAN" else "contact"
state_key = f"{prefix}-{row['conversation_key']}"
last_message_times[state_key] = row["last_message_time"]
return {
"counts": counts,
"mentions": mention_flags,
"last_message_times": last_message_times,
}
class RawPacketRepository:
@staticmethod
+16 -1
View File
@@ -3,14 +3,29 @@
import logging
import time
from fastapi import APIRouter
from fastapi import APIRouter, Query
from app.database import db
from app.models import UnreadCounts
from app.repository import MessageRepository
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/read-state", tags=["read-state"])
@router.get("/unreads", response_model=UnreadCounts)
async def get_unreads(
name: str | None = Query(default=None, description="User's name for @mention detection"),
) -> UnreadCounts:
"""Get unread counts, mention flags, and last message times for all conversations.
Computes unread counts server-side using last_read_at timestamps on
channels and contacts, avoiding the need to fetch bulk messages.
"""
data = await MessageRepository.get_unread_counts(name)
return UnreadCounts(**data)
@router.post("/mark-all-read")
async def mark_all_read() -> dict:
"""Mark all contacts and channels as read.
+7 -29
View File
@@ -7,7 +7,7 @@ from fastapi import APIRouter, WebSocket, WebSocketDisconnect
from app.config import settings
from app.radio import radio_manager
from app.repository import ChannelRepository, ContactRepository, RawPacketRepository
from app.repository import RawPacketRepository
from app.websocket import ws_manager
logger = logging.getLogger(__name__)
@@ -16,12 +16,15 @@ router = APIRouter()
@router.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket) -> None:
"""WebSocket endpoint for real-time updates."""
"""WebSocket endpoint for real-time updates.
Only sends health status on initial connect. Contacts and channels
are fetched via REST endpoints for faster parallel loading.
"""
await ws_manager.connect(websocket)
# Send initial state
# Send initial health status
try:
# Health status
db_size_mb = 0.0
try:
db_size_bytes = os.path.getsize(settings.database_path)
@@ -45,31 +48,6 @@ async def websocket_endpoint(websocket: WebSocket) -> None:
}
await ws_manager.send_personal(websocket, "health", health_data)
# Contacts - fetch all by paginating until exhausted
all_contacts = []
chunk_size = 500
offset = 0
while True:
chunk = await ContactRepository.get_all(limit=chunk_size, offset=offset)
all_contacts.extend(chunk)
if len(chunk) < chunk_size:
break
offset += chunk_size
await ws_manager.send_personal(
websocket,
"contacts",
[c.model_dump() for c in all_contacts],
)
# Channels
channels = await ChannelRepository.get_all()
await ws_manager.send_personal(
websocket,
"channels",
[c.model_dump() for c in channels],
)
except Exception as e:
logger.error("Error sending initial state: %s", e)
@@ -1,4 +1,4 @@
import{r as be,j as vr}from"./index-CL0FbnNJ.js";function wr(){return wr=Object.assign?Object.assign.bind():function(n){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var i in t)({}).hasOwnProperty.call(t,i)&&(n[i]=t[i])}return n},wr.apply(null,arguments)}function Tu(n,e){if(n==null)return{};var t={};for(var i in n)if({}.hasOwnProperty.call(n,i)){if(e.indexOf(i)!==-1)continue;t[i]=n[i]}return t}let Tr=[],dh=[];(()=>{let n="lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map(e=>e?parseInt(e,36):1);for(let e=0,t=0;e<n.length;e++)(e%2?dh:Tr).push(t=t+n[e])})();function Cu(n){if(n<768)return!1;for(let e=0,t=Tr.length;;){let i=e+t>>1;if(n<Tr[i])t=i;else if(n>=dh[i])e=i+1;else return!0;if(e==t)return!1}}function hl(n){return n>=127462&&n<=127487}const cl=8205;function Qu(n,e,t=!0,i=!0){return(t?ph:Au)(n,e,i)}function ph(n,e,t){if(e==n.length)return e;e&&mh(n.charCodeAt(e))&&gh(n.charCodeAt(e-1))&&e--;let i=Ls(n,e);for(e+=fl(i);e<n.length;){let s=Ls(n,e);if(i==cl||s==cl||t&&Cu(s))e+=fl(s),i=s;else if(hl(s)){let r=0,o=e-2;for(;o>=0&&hl(Ls(n,o));)r++,o-=2;if(r%2==0)break;e+=2}else break}return e}function Au(n,e,t){for(;e>0;){let i=ph(n,e-2,t);if(i<e)return i;e--}return 0}function Ls(n,e){let t=n.charCodeAt(e);if(!gh(t)||e+1==n.length)return t;let i=n.charCodeAt(e+1);return mh(i)?(t-55296<<10)+(i-56320)+65536:t}function mh(n){return n>=56320&&n<57344}function gh(n){return n>=55296&&n<56320}function fl(n){return n<65536?1:2}class V{lineAt(e){if(e<0||e>this.length)throw new RangeError(`Invalid position ${e} in document of length ${this.length}`);return this.lineInner(e,!1,1,0)}line(e){if(e<1||e>this.lines)throw new RangeError(`Invalid line number ${e} in ${this.lines}-line document`);return this.lineInner(e,!0,1,0)}replace(e,t,i){[e,t]=oi(this,e,t);let s=[];return this.decompose(0,e,s,2),i.length&&i.decompose(0,i.length,s,3),this.decompose(t,this.length,s,1),Ye.from(s,this.length-(t-e)+i.length)}append(e){return this.replace(this.length,this.length,e)}slice(e,t=this.length){[e,t]=oi(this,e,t);let i=[];return this.decompose(e,t,i,0),Ye.from(i,t-e)}eq(e){if(e==this)return!0;if(e.length!=this.length||e.lines!=this.lines)return!1;let t=this.scanIdentical(e,1),i=this.length-this.scanIdentical(e,-1),s=new Qi(this),r=new Qi(e);for(let o=t,l=t;;){if(s.next(o),r.next(o),o=0,s.lineBreak!=r.lineBreak||s.done!=r.done||s.value!=r.value)return!1;if(l+=s.value.length,s.done||l>=i)return!0}}iter(e=1){return new Qi(this,e)}iterRange(e,t=this.length){return new Oh(this,e,t)}iterLines(e,t){let i;if(e==null)i=this.iter();else{t==null&&(t=this.lines+1);let s=this.line(e).from;i=this.iterRange(s,Math.max(s,t==this.lines+1?this.length:t<=1?0:this.line(t-1).to))}return new yh(i)}toString(){return this.sliceString(0)}toJSON(){let e=[];return this.flatten(e),e}constructor(){}static of(e){if(e.length==0)throw new RangeError("A document must have at least one line");return e.length==1&&!e[0]?V.empty:e.length<=32?new Y(e):Ye.from(Y.split(e,[]))}}class Y extends V{constructor(e,t=Pu(e)){super(),this.text=e,this.length=t}get lines(){return this.text.length}get children(){return null}lineInner(e,t,i,s){for(let r=0;;r++){let o=this.text[r],l=s+o.length;if((t?i:l)>=e)return new Mu(s,l,i,o);s=l+1,i++}}decompose(e,t,i,s){let r=e<=0&&t>=this.length?this:new Y(ul(this.text,e,t),Math.min(t,this.length)-Math.max(0,e));if(s&1){let o=i.pop(),l=$n(r.text,o.text.slice(),0,r.length);if(l.length<=32)i.push(new Y(l,o.length+r.length));else{let a=l.length>>1;i.push(new Y(l.slice(0,a)),new Y(l.slice(a)))}}else i.push(r)}replace(e,t,i){if(!(i instanceof Y))return super.replace(e,t,i);[e,t]=oi(this,e,t);let s=$n(this.text,$n(i.text,ul(this.text,0,e)),t),r=this.length+i.length-(t-e);return sLine truncated
import{r as be,j as vr}from"./index-BrthzT77.js";function wr(){return wr=Object.assign?Object.assign.bind():function(n){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var i in t)({}).hasOwnProperty.call(t,i)&&(n[i]=t[i])}return n},wr.apply(null,arguments)}function Tu(n,e){if(n==null)return{};var t={};for(var i in n)if({}.hasOwnProperty.call(n,i)){if(e.indexOf(i)!==-1)continue;t[i]=n[i]}return t}let Tr=[],dh=[];(()=>{let n="lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map(e=>e?parseInt(e,36):1);for(let e=0,t=0;e<n.length;e++)(e%2?dh:Tr).push(t=t+n[e])})();function Cu(n){if(n<768)return!1;for(let e=0,t=Tr.length;;){let i=e+t>>1;if(n<Tr[i])t=i;else if(n>=dh[i])e=i+1;else return!0;if(e==t)return!1}}function hl(n){return n>=127462&&n<=127487}const cl=8205;function Qu(n,e,t=!0,i=!0){return(t?ph:Au)(n,e,i)}function ph(n,e,t){if(e==n.length)return e;e&&mh(n.charCodeAt(e))&&gh(n.charCodeAt(e-1))&&e--;let i=Ls(n,e);for(e+=fl(i);e<n.length;){let s=Ls(n,e);if(i==cl||s==cl||t&&Cu(s))e+=fl(s),i=s;else if(hl(s)){let r=0,o=e-2;for(;o>=0&&hl(Ls(n,o));)r++,o-=2;if(r%2==0)break;e+=2}else break}return e}function Au(n,e,t){for(;e>0;){let i=ph(n,e-2,t);if(i<e)return i;e--}return 0}function Ls(n,e){let t=n.charCodeAt(e);if(!gh(t)||e+1==n.length)return t;let i=n.charCodeAt(e+1);return mh(i)?(t-55296<<10)+(i-56320)+65536:t}function mh(n){return n>=56320&&n<57344}function gh(n){return n>=55296&&n<56320}function fl(n){return n<65536?1:2}class V{lineAt(e){if(e<0||e>this.length)throw new RangeError(`Invalid position ${e} in document of length ${this.length}`);return this.lineInner(e,!1,1,0)}line(e){if(e<1||e>this.lines)throw new RangeError(`Invalid line number ${e} in ${this.lines}-line document`);return this.lineInner(e,!0,1,0)}replace(e,t,i){[e,t]=oi(this,e,t);let s=[];return this.decompose(0,e,s,2),i.length&&i.decompose(0,i.length,s,3),this.decompose(t,this.length,s,1),Ye.from(s,this.length-(t-e)+i.length)}append(e){return this.replace(this.length,this.length,e)}slice(e,t=this.length){[e,t]=oi(this,e,t);let i=[];return this.decompose(e,t,i,0),Ye.from(i,t-e)}eq(e){if(e==this)return!0;if(e.length!=this.length||e.lines!=this.lines)return!1;let t=this.scanIdentical(e,1),i=this.length-this.scanIdentical(e,-1),s=new Qi(this),r=new Qi(e);for(let o=t,l=t;;){if(s.next(o),r.next(o),o=0,s.lineBreak!=r.lineBreak||s.done!=r.done||s.value!=r.value)return!1;if(l+=s.value.length,s.done||l>=i)return!0}}iter(e=1){return new Qi(this,e)}iterRange(e,t=this.length){return new Oh(this,e,t)}iterLines(e,t){let i;if(e==null)i=this.iter();else{t==null&&(t=this.lines+1);let s=this.line(e).from;i=this.iterRange(s,Math.max(s,t==this.lines+1?this.length:t<=1?0:this.line(t-1).to))}return new yh(i)}toString(){return this.sliceString(0)}toJSON(){let e=[];return this.flatten(e),e}constructor(){}static of(e){if(e.length==0)throw new RangeError("A document must have at least one line");return e.length==1&&!e[0]?V.empty:e.length<=32?new Y(e):Ye.from(Y.split(e,[]))}}class Y extends V{constructor(e,t=Pu(e)){super(),this.text=e,this.length=t}get lines(){return this.text.length}get children(){return null}lineInner(e,t,i,s){for(let r=0;;r++){let o=this.text[r],l=s+o.length;if((t?i:l)>=e)return new Mu(s,l,i,o);s=l+1,i++}}decompose(e,t,i,s){let r=e<=0&&t>=this.length?this:new Y(ul(this.text,e,t),Math.min(t,this.length)-Math.max(0,e));if(s&1){let o=i.pop(),l=$n(r.text,o.text.slice(),0,r.length);if(l.length<=32)i.push(new Y(l,o.length+r.length));else{let a=l.length>>1;i.push(new Y(l.slice(0,a)),new Y(l.slice(a)))}}else i.push(r)}replace(e,t,i){if(!(i instanceof Y))return super.replace(e,t,i);[e,t]=oi(this,e,t);let s=$n(this.text,$n(i.text,ul(this.text,0,e)),t),r=this.length+i.length-(t-e);return sLine truncated
`){[e,t]=oi(this,e,t);let s="";for(let r=0,o=0;r<=t&&o<this.text.length;o++){let l=this.text[o],a=r+l.length;r>e&&o&&(s+=i),e<a&&t>r&&(s+=l.slice(Math.max(0,e-r),t-r)),r=a+1}return s}flatten(e){for(let t of this.text)e.push(t)}scanIdentical(){return 0}static split(e,t){let i=[],s=-1;for(let r of e)i.push(r),s+=r.length+1,i.length==32&&(t.push(new Y(i,s)),i=[],s=-1);return s>-1&&t.push(new Y(i,s)),t}}class Ye extends V{constructor(e,t){super(),this.children=e,this.length=t,this.lines=0;for(let i of e)this.lines+=i.lines}lineInner(e,t,i,s){for(let r=0;;r++){let o=this.children[r],l=s+o.length,a=i+o.lines-1;if((t?a:l)>=e)return o.lineInner(e,t,i,s);s=l+1,i=a+1}}decompose(e,t,i,s){for(let r=0,o=0;o<=t&&r<this.children.length;r++){let l=this.children[r],a=o+l.length;if(e<=a&&t>=o){let h=s&((o<=e?1:0)|(a>=t?2:0));o>=e&&a<=t&&!h?i.push(l):l.decompose(e-o,t-o,i,h)}o=a+1}}replace(e,t,i){if([e,t]=oi(this,e,t),i.lines<this.lines)for(let s=0,r=0;s<this.children.length;s++){let o=this.children[s],l=r+o.length;if(e>=r&&t<=l){let a=o.replace(e-r,t-r,i),h=this.lines-o.lines+a.lines;if(a.lines<h>>4&&a.lines>h>>6){let c=this.children.slice();return c[s]=a,new Ye(c,this.length-(t-e)+i.length)}return super.replace(r,l,a)}r=l+1}return super.replace(e,t,i)}sliceString(e,t=this.length,i=`
`){[e,t]=oi(this,e,t);let s="";for(let r=0,o=0;r<this.children.length&&o<=t;r++){let l=this.children[r],a=o+l.length;o>e&&r&&(s+=i),e<a&&t>o&&(s+=l.sliceString(e-o,t-o,i)),o=a+1}return s}flatten(e){for(let t of this.children)t.flatten(e)}scanIdentical(e,t){if(!(e instanceof Ye))return 0;let i=0,[s,r,o,l]=t>0?[0,0,this.children.length,e.children.length]:[this.children.length-1,e.children.length-1,-1,-1];for(;;s+=t,r+=t){if(s==o||r==l)return i;let a=this.children[s],h=e.children[r];if(a!=h)return i+a.scanIdentical(h,t);i+=a.length+1}}static from(e,t=e.reduce((i,s)=>i+s.length+1,-1)){let i=0;for(let d of e)i+=d.lines;if(i<32){let d=[];for(let p of e)p.flatten(d);return new Y(d,t)}let s=Math.max(32,i>>5),r=s<<1,o=s>>1,l=[],a=0,h=-1,c=[];function f(d){let p;if(d.lines>r&&d instanceof Ye)for(let m of d.children)f(m);else d.lines>o&&(a>o||!a)?(u(),l.push(d)):d instanceof Y&&a&&(p=c[c.length-1])instanceof Y&&d.lines+p.lines<=32?(a+=d.lines,h+=d.length+1,c[c.length-1]=new Y(p.text.concat(d.text),p.length+1+d.length)):(a+d.lines>s&&u(),a+=d.lines,h+=d.length+1,c.push(d))}function u(){a!=0&&(l.push(c.length==1?c[0]:Ye.from(c,h)),h=-1,a=c.length=0)}for(let d of e)f(d);return u(),l.length==1?l[0]:new Ye(l,t)}}V.empty=new Y([""],0);function Pu(n){let e=-1;for(let t of n)e+=t.length+1;return e}function $n(n,e,t=0,i=1e9){for(let s=0,r=0,o=!0;r<n.length&&s<=i;r++){let l=n[r],a=s+l.length;a>=t&&(a>i&&(l=l.slice(0,i-s)),s<t&&(l=l.slice(t-s)),o?(e[e.length-1]+=l,o=!1):e.push(l)),s=a+1}return e}function ul(n,e,t){return $n(n,[""],e,t)}class Qi{constructor(e,t=1){this.dir=t,this.done=!1,this.lineBreak=!1,this.value="",this.nodes=[e],this.offsets=[t>0?1:(e instanceof Y?e.text.length:e.children.length)<<1]}nextInner(e,t){for(this.done=this.lineBreak=!1;;){let i=this.nodes.length-1,s=this.nodes[i],r=this.offsets[i],o=r>>1,l=s instanceof Y?s.text.length:s.children.length;if(o==(t>0?l:0)){if(i==0)return this.done=!0,this.value="",this;t>0&&this.offsets[i-1]++,this.nodes.pop(),this.offsets.pop()}else if((r&1)==(t>0?0:1)){if(this.offsets[i]+=t,e==0)return this.lineBreak=!0,this.value=`
`,this;e--}else if(s instanceof Y){let a=s.text[o+(t<0?-1:0)];if(this.offsets[i]+=t,a.length>Math.max(0,e))return this.value=e==0?a:t>0?a.slice(e):a.slice(0,a.length-e),this;e-=a.length}else{let a=s.children[o+(t<0?-1:0)];e>a.length?(e-=a.length,this.offsets[i]+=t):(t<0&&this.offsets[i]--,this.nodes.push(a),this.offsets.push(t>0?1:(a instanceof Y?a.text.length:a.children.length)<<1))}}}next(e=0){return e<0&&(this.nextInner(-e,-this.dir),e=this.value.length),this.nextInner(e,this.dir)}}class Oh{constructor(e,t,i){this.value="",this.done=!1,this.cursor=new Qi(e,t>i?-1:1),this.pos=t>i?e.length:0,this.from=Math.min(t,i),this.to=Math.max(t,i)}nextInner(e,t){if(t<0?this.pos<=this.from:this.pos>=this.to)return this.value="",this.done=!0,this;e+=Math.max(0,t<0?this.pos-this.to:this.from-this.pos);let i=t<0?this.pos-this.from:this.to-this.pos;e>i&&(e=i),i-=e;let{value:s}=this.cursor.next(e);return this.pos+=(s.length+e)*t,this.value=s.length<=i?s:t<0?s.slice(s.length-i):s.slice(0,i),this.done=!this.value,this}next(e=0){return e<0?e=Math.max(e,this.from-this.pos):e>0&&(e=Math.min(e,this.to-this.pos)),this.nextInner(e,this.cursor.dir)}get lineBreak(){return this.cursor.lineBreak&&this.value!=""}}class yh{constructor(e){this.inner=e,this.afterBreak=!0,this.value="",this.done=!1}next(e=0){let{done:t,lineBreak:i,value:s}=this.inner.next(e);return t&&this.afterBreak?(this.value="",this.afterBreak=!1):t?(this.done=!0,this.value=""):i?this.afterBreak?this.value="":(this.afterBreak=!0,this.next()):(this.value=s,this.afterBreak=!1),this}get lineBreak(){return!1}}typeof Symbol<"u"&&(V.prototype[Symbol.iterator]=function(){return this.iter()},Qi.prototype[Symbol.iterator]=Oh.prototype[Symbol.iterator]=yh.prototype[Symbol.iterator]=function(){return this});class Mu{constructor(e,t,i,s){this.from=e,this.to=t,this.number=i,this.text=s}get length(){return this.to-this.from}}function oi(n,e,t){return e=Math.max(0,Math.min(n.length,e)),[e,Math.max(e,Math.min(n.length,t))]}function re(n,e,t=!0,i=!0){return Qu(n,e,t,i)}function Ru(n){return n>=56320&&n<57344}function Eu(n){return n>=55296&&n<56320}function ke(n,e){let t=n.charCodeAt(e);if(!Eu(t)||e+1==n.length)return t;let i=n.charCodeAt(e+1);return Ru(i)?(t-55296<<10)+(i-56320)+65536:t}function xo(n){return n<=65535?String.fromCharCode(n):(n-=65536,String.fromCharCode((n>>10)+55296,(n&1023)+56320))}function Ke(n){return n<65536?1:2}const Cr=/\r\n?|\n/;var de=(function(n){return n[n.Simple=0]="Simple",n[n.TrackDel=1]="TrackDel",n[n.TrackBefore=2]="TrackBefore",n[n.TrackAfter=3]="TrackAfter",n})(de||(de={}));class nt{constructor(e){this.sections=e}get length(){let e=0;for(let t=0;t<this.sections.length;t+=2)e+=this.sections[t];return e}get newLength(){let e=0;for(let t=0;t<this.sections.length;t+=2){let i=this.sections[t+1];e+=i<0?this.sections[t]:i}return e}get empty(){return this.sections.length==0||this.sections.length==2&&this.sections[1]<0}iterGaps(e){for(let t=0,i=0,s=0;t<this.sections.length;){let r=this.sections[t++],o=this.sections[t++];o<0?(e(i,s,r),s+=r):s+=o,i+=r}}iterChangedRanges(e,t=!1){Qr(this,e,t)}get invertedDesc(){let e=[];for(let t=0;t<this.sections.length;){let i=this.sections[t++],s=this.sections[t++];s<0?e.push(i,s):e.push(s,i)}return new nt(e)}composeDesc(e){return this.empty?e:e.empty?this:bh(this,e)}mapDesc(e,t=!1){return e.empty?this:Ar(this,e,t)}mapPos(e,t=-1,i=de.Simple){let s=0,r=0;for(let o=0;o<this.sections.length;){let l=this.sections[o++],a=this.sections[o++],h=s+l;if(a<0){if(h>e)return r+(e-s);r+=l}else{if(i!=de.Simple&&h>=e&&(i==de.TrackDel&&s<e&&h>e||i==de.TrackBefore&&s<e||i==de.TrackAfter&&h>e))return null;if(h>e||h==e&&t<0&&!l)return e==s||t<0?r:r+a;r+=a}s=h}if(e>s)throw new RangeError(`Position ${e} is out of range for changeset of length ${s}`);return r}touchesRange(e,t=e){for(let i=0,s=0;i<this.sections.length&&s<=t;){let r=this.sections[i++],o=this.sections[i++],l=s+r;if(o>=0&&s<=t&&l>=e)return s<e&&l>t?"cover":!0;s=l}return!1}toString(){let e="";for(let t=0;t<this.sections.length;){let i=this.sections[t++],s=this.sections[t++];e+=(e?" ":"")+i+(s>=0?":"+s:"")}return e}toJSON(){return this.sections}static fromJSON(e){if(!Array.isArray(e)||e.length%2||e.some(t=>typeof t!="number"))throw new RangeError("Invalid JSON representation of ChangeDesc");return new nt(e)}static create(e){return new nt(e)}}class se extends nt{constructor(e,t){super(e),this.inserted=t}apply(e){if(this.length!=e.length)throw new RangeError("Applying change set to a document with the wrong length");return Qr(this,(t,i,s,r,o)=>e=e.replace(s,s+(i-t),o),!1),e}mapDesc(e,t=!1){return Ar(this,e,t,!0)}invert(e){let t=this.sections.slice(),i=[];for(let s=0,r=0;s<t.length;s+=2){let o=t[s],l=t[s+1];if(l>=0){t[s]=l,t[s+1]=o;let a=s>>1;for(;i.length<a;)i.push(V.empty);i.push(o?e.slice(r,r+o):V.empty)}r+=o}return new se(t,i)}compose(e){return this.empty?e:e.empty?this:bh(this,e,!0)}map(e,t=!1){return e.empty?this:Ar(this,e,t,!0)}iterChanges(e,t=!1){Qr(this,e,t)}get desc(){return nt.crea Line truncated
@@ -12,4 +12,4 @@ import{r as be,j as vr}from"./index-CL0FbnNJ.js";function wr(){return wr=Object.
`:i=="r"?"\r":i=="t"?" ":"\\")}eq(e){return this.search==e.search&&this.replace==e.replace&&this.caseSensitive==e.caseSensitive&&this.regexp==e.regexp&&this.wholeWord==e.wholeWord&&this.test==e.test}create(){return this.regexp?new S0(this):new y0(this)}getCursor(e,t=0,i){let s=e.doc?e:N.create({doc:e});return i==null&&(i=s.doc.length),this.regexp?jt(this,s,t,i):Ht(this,s,t,i)}}class Uf{constructor(e){this.spec=e}}function g0(n,e,t){return(i,s,r,o)=>{if(t&&!t(i,s,r,o))return!1;let l=i>=o&&s<=o+r.length?r.slice(i-o,s-o):e.doc.sliceString(i,s);return n(l,e,i,s)}}function Ht(n,e,t,i){let s;return n.wholeWord&&(s=O0(e.doc,e.charCategorizer(e.selection.main.head))),n.test&&(s=g0(n.test,e,s)),new ui(e.doc,n.unquoted,t,i,n.caseSensitive?void 0:r=>r.toLowerCase(),s)}function O0(n,e){return(t,i,s,r)=>((r>t||r+s.length<i)&&(r=Math.max(0,t-2),s=n.sliceString(r,Math.min(n.length,i+2))),(e(ds(s,t-r))!=G.Word||e(ps(s,t-r))!=G.Word)&&(e(ps(s,i-r))!=G.Word||e(ds(s,i-r))!=G.Word))}class y0 extends Uf{constructor(e){super(e)}nextMatch(e,t,i){let s=Ht(this.spec,e,i,e.doc.length).nextOverlapping();if(s.done){let r=Math.min(e.doc.length,t+this.spec.unquoted.length);s=Ht(this.spec,e,0,r).nextOverlapping()}return s.done||s.value.from==t&&s.value.to==i?null:s.value}prevMatchInRange(e,t,i){for(let s=i;;){let r=Math.max(t,s-1e4-this.spec.unquoted.length),o=Ht(this.spec,e,r,s),l=null;for(;!o.nextOverlapping().done;)l=o.value;if(l)return l;if(r==t)return null;s-=1e4}}prevMatch(e,t,i){let s=this.prevMatchInRange(e,0,t);return s||(s=this.prevMatchInRange(e,Math.max(0,i-this.spec.unquoted.length),e.doc.length)),s&&(s.from!=t||s.to!=i)?s:null}getReplacement(e){return this.spec.unquote(this.spec.replace)}matchAll(e,t){let i=Ht(this.spec,e,0,e.doc.length),s=[];for(;!i.next().done;){if(s.length>=t)return null;s.push(i.value)}return s}highlight(e,t,i,s){let r=Ht(this.spec,e,Math.max(0,t-this.spec.unquoted.length),Math.min(i+this.spec.unquoted.length,e.doc.length));for(;!r.next().done;)s(r.value.from,r.value.to)}}function b0(n,e,t){return(i,s,r)=>(!t||t(i,s,r))&&n(r[0],e,i,s)}function jt(n,e,t,i){let s;return n.wholeWord&&(s=x0(e.charCategorizer(e.selection.main.head))),n.test&&(s=b0(n.test,e,s)),new Xf(e.doc,n.search,{ignoreCase:!n.caseSensitive,test:s},t,i)}function ds(n,e){return n.slice(re(n,e,!1),e)}function ps(n,e){return n.slice(e,re(n,e))}function x0(n){return(e,t,i)=>!i[0].length||(n(ds(i.input,i.index))!=G.Word||n(ps(i.input,i.index))!=G.Word)&&(n(ps(i.input,i.index+i[0].length))!=G.Word||n(ds(i.input,i.index+i[0].length))!=G.Word)}class S0 extends Uf{nextMatch(e,t,i){let s=jt(this.spec,e,i,e.doc.length).next();return s.done&&(s=jt(this.spec,e,0,t).next()),s.done?null:s.value}prevMatchInRange(e,t,i){for(let s=1;;s++){let r=Math.max(t,i-s*1e4),o=jt(this.spec,e,r,i),l=null;for(;!o.next().done;)l=o.value;if(l&&(r==t||l.from>r+10))return l;if(r==t)return null}}prevMatch(e,t,i){return this.prevMatchInRange(e,0,t)||this.prevMatchInRange(e,i,e.doc.length)}getReplacement(e){return this.spec.unquote(this.spec.replace).replace(/\$([$&]|\d+)/g,(t,i)=>{if(i=="&")return e.match[0];if(i=="$")return"$";for(let s=i.length;s>0;s--){let r=+i.slice(0,s);if(r>0&&r<e.match.length)return e.match[r]+i.slice(s)}return t})}matchAll(e,t){let i=jt(this.spec,e,0,e.doc.length),s=[];for(;!i.next().done;){if(s.length>=t)return null;s.push(i.value)}return s}highlight(e,t,i,s){let r=jt(this.spec,e,Math.max(0,t-250),Math.min(i+250,e.doc.length));for(;!r.next().done;)s(r.value.from,r.value.to)}}const Ui=D.define(),Go=D.define(),kt=he.define({create(n){return new cr(Oo(n).create(),null)},update(n,e){for(let t of e.effects)t.is(Ui)?n=new cr(t.value.create(),n.panel):t.is(Go)&&(n=new cr(n.query,t.value?Zo:null));return n},provide:n=>Vi.from(n,e=>e.panel)});class cr{constructor(e,t){this.query=e,this.panel=t}}const k0=M.mark({class:"cm-searchMatch"}),v0=M.mark({class:"cm-searchMatch cm-searchMatch-selected"}),w0=J.fromClass(class{constructor(n){this.view=n,this.decorations=this.highlight(n.state.field(kt))}update(n){let e=n.state.field(kt);(e!=n.startState.field(kt)||n.docChanged||n.selectionSet||n.viewportChanged)&&(this.decorations=this.highlight(e))}highlight({query:n,panel:e}){if(!e||!n.spec.valid)return M.none;let{view:t}=this,i=new pt;for(let s=0,r=t.visibleRanges,o=r.length;s<o;s++){let{from:l,to:a}=r[s];for(;s<o-1&&a>r[s+1].from-500;)a=r[++s].to;n.highlight(t.state,l,a,(h,c)=>{let f=t.state.selection.ranges.some(u=>u.from==h&&u.to==c);i.add(h,c,f?v0:k0)})}return i.finish()}},{decorations:n=>n.decorations});function hn(n){return e=>{let t=e.state.field(kt,!1);return t&&t.query.spec.valid?n(e,t):Gf(e)}}const ms=hn((n,{query:e})=>{let{to:t}=n.state.selection.main,i=e.nextMatch(n.state,t,t);if(!i)return!1;let s=b.single(i.from,i.to),r=n.state.facet(gi);return n.dispatch({selection:s,effects:[Yo(n,i),r.scrollToMatch(s.main,n)],userEvent:"select.search"}),jf(n),!0}),gs=hn((n,{query:e})=>{let{state:t}=n,{from:i}=t.selection.main,s=e.prevMatch(t,i,i);if(!s)return!1;let r= Line truncated
`,{label:"if",detail:"block",type:"keyword"}),ot("if ${}:\n ${}\nelse:\n ${}",{label:"if",detail:"/ else block",type:"keyword"}),ot("class ${name}:\n def __init__(self, ${params}):\n ${}",{label:"class",detail:"definition",type:"keyword"}),ot("import ${module}",{label:"import",detail:"statement",type:"keyword"}),ot("from ${module} import ${names}",{label:"from",detail:"import",type:"keyword"})],Rb=D0(wu,Kf(Pb.concat(Mb)));function xr(n){let{node:e,pos:t}=n,i=n.lineIndent(t,-1),s=null;for(;;){let r=e.childBefore(t);if(r)if(r.name=="Comment")t=r.from;else if(r.name=="Body"||r.name=="MatchBody")n.baseIndentFor(r)+n.unit<=i&&(s=r),e=r;else if(r.name=="MatchClause")e=r;else if(r.type.is("Statement"))e=r;else break;else break}return s}function Sr(n,e){let t=n.baseIndentFor(e),i=n.lineAt(n.pos,-1),s=i.from+i.text.length;return/^\s*($|#)/.test(i.text)&&n.node.to<s+100&&!/\S/.test(n.state.sliceDoc(s,n.node.to))&&n.lineIndent(n.pos,-1)<=t||/^\s*(else:|elif |except |finally:|case\s+[^=:]+:)/.test(n.textAfter)&&n.lineIndent(n.pos,-1)>t?null:t+n.unit}const kr=os.define({name:"python",parser:Cb.configure({props:[Uc.add({Body:n=>{var e;let t=/^\s*(#|$)/.test(n.textAfter)&&xr(n)||n.node;return(e=Sr(n,t))!==null&&e!==void 0?e:n.continue()},MatchBody:n=>{var e;let t=xr(n);return(e=Sr(n,t||n.node))!==null&&e!==void 0?e:n.continue()},IfStatement:n=>/^\s*(else:|elif )/.test(n.textAfter)?n.baseIndent:n.continue(),"ForStatement WhileStatement":n=>/^\s*else:/.test(n.textAfter)?n.baseIndent:n.continue(),TryStatement:n=>/^\s*(except[ :]|finally:|else:)/.test(n.textAfter)?n.baseIndent:n.continue(),MatchStatement:n=>/^\s*case /.test(n.textAfter)?n.baseIndent+n.unit:n.continue(),"TupleExpression ComprehensionExpression ParamList ArgList ParenthesizedExpression":sr({closing:")"}),"DictionaryExpression DictionaryComprehensionExpression SetExpression SetComprehensionExpression":sr({closing:"}"}),"ArrayExpression ArrayComprehensionExpression":sr({closing:"]"}),MemberExpression:n=>n.baseIndent+n.unit,"String FormatString":()=>null,Script:n=>{var e;let t=xr(n);return(e=t&&Sr(n,t))!==null&&e!==void 0?e:n.continue()}}),Gc.add({"ArrayExpression DictionaryExpression SetExpression TupleExpression":pg,Body:(n,e)=>({from:n.from+1,to:n.to-(n.to==e.doc.length?0:1)}),"String FormatString":(n,e)=>({from:e.doc.lineAt(n.from).to,to:n.to})})]}),languageData:{closeBrackets:{brackets:["(","[","{","'",'"',"'''",'"""'],stringPrefixes:["f","fr","rf","r","u","b","br","rb","F","FR","RF","R","U","B","BR","RB"]},commentTokens:{line:"#"},indentOnInput:/^\s*([\}\]\)]|else:|elif |except |finally:|case\s+[^:]*:?)$/}});function Eb(){return new ng(kr,[kr.data.of({autocomplete:Ab}),kr.data.of({autocomplete:Rb})])}function Bb({value:n,onChange:e,id:t}){return vr.jsx("div",{className:"w-full overflow-hidden rounded-md border border-input",children:vr.jsx(pu,{value:n,onChange:e,extensions:[Eb()],theme:du,height:"256px",basicSetup:{lineNumbers:!0,foldGutter:!1,highlightActiveLine:!0},className:"text-sm",id:t})})}export{Bb as BotCodeEditor};
//# sourceMappingURL=BotCodeEditor-CNpOkiKc.js.map
//# sourceMappingURL=BotCodeEditor-nDB6q0XA.js.map
@@ -1 +1 @@
{"version":3,"file":"BotCodeEditor-CNpOkiKc.js","sources":["../../node_modules/@babel/runtime/helpers/esm/extends.js","../../node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js","../../node_modules/@marijn/find-cluster-break/src/index.js","../../node_modules/@codemirror/state/dist/index.js","../../node_modules/style-mod/src/style-mod.js","../../node_modules/w3c-keyname/index.js","../../node_modules/crelt/index.js","../../node_modules/@codemirror/view/dist/index.js","../../node_modules/@lezer/common/dist/index.js","../../node_modules/@lezer/highlight/dist/index.js","../../node_modules/@codemirror/language/dist/index.js","../../node_modules/@codemirror/commands/dist/index.js","../../node_modules/@codemirror/search/dist/index.js","../../node_modules/@codemirror/autocomplete/dist/index.js","../../node_modules/@codemirror/lint/dist/index.js","../../node_modules/@uiw/codemirror-extensions-basic-setup/esm/index.js","../../node_modules/@codemirror/theme-one-dark/dist/index.js","../../node_modules/@uiw/react-codemirror/esm/theme/light.js","../../node_modules/@uiw/react-codemirror/esm/getDefaultExtensions.js","../../node_modules/@uiw/react-codemirror/esm/utils.js","../../node_modules/@uiw/react-codemirror/esm/timeoutLatch.js","../../node_modules/@uiw/react-codemirror/esm/useCodeMirror.js","../../node_modules/@uiw/react-codemirror/esm/index.js","../../node_modules/@lezer/lr/dist/index.js","../../node_modules/@lezer/python/dist/index.js","../../node_modules/@codemirror/lang-python/dist/index.js","../../src/components/BotCodeEditor.tsx"],"sourcesContent":["function _extends() {\n return _extends = Object.assign ? Object.assign.bind() : function (n) {\n for (var e = 1; e < arguments.length; e++) {\n var t = arguments[e];\n for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);\n }\n return n;\n }, _extends.apply(null, arguments);\n}\nexport { _extends as default };","function _objectWithoutPropertiesLoose(r, e) {\n if (null == r) return {};\n var t = {};\n for (var n in r) if ({}.hasOwnProperty.call(r, n)) {\n if (-1 !== e.indexOf(n)) continue;\n t[n] = r[n];\n }\n return t;\n}\nexport { _objectWithoutPropertiesLoose as default };","// These are filled with ranges (rangeFrom[i] up to but not including\n// rangeTo[i]) of code points that count as extending characters.\nlet rangeFrom = [], rangeTo = []\n\n;(() => {\n // Compressed representation of the Grapheme_Cluster_Break=Extend\n // information from\n // http://www.unicode.org/Public/16.0.0/ucd/auxiliary/GraphemeBreakProperty.txt.\n // Each pair of elements represents a range, as an offet from the\n // previous range and a length. Numbers are in base-36, with the empty\n // string being a shorthand for 1.\n let numbers = \"lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o\".split(\",\").map(s => s ? parseInt(s, 36) : 1)\n for (let i = 0, n = 0; i < numbers.length; i++)\n (i % 2 ? rangeTo : rangeFrom).push(n = n + numbers[i])\n})()\n\nexport function isExtendingChar(code) {\n if (code < 768) return false\n for (let from = 0, to = rangeFrom.length;;) {\n let mid = (from + to) >> 1\n if (code < rangeFrom[mid]) to = mid\n else if (code >= rangeTo[mid]) from = mid + 1\n else return true\n if (from == to) return false\n }\n}\n\nfunction isRegionalIndicator(code) {\n return code >= 0x1F1E6 && code <= 0x1F1FF\n}\n\nfunction check(code) {\n for (let i = 0; i < rangeFrom.length; i++) {\n if (rangeTo[i] > code) return rangeFrom[i] <= code\n }\n return false\n}\n\nconst ZWJ = 0x200d\n\nexport function findClusterBreak(str, pos, forward = true, includeExtending = true) {\n return (forward ? nextClusterBreak : prevClusterBreak)(strLine truncated
{"version":3,"file":"BotCodeEditor-nDB6q0XA.js","sources":["../../node_modules/@babel/runtime/helpers/esm/extends.js","../../node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js","../../node_modules/@marijn/find-cluster-break/src/index.js","../../node_modules/@codemirror/state/dist/index.js","../../node_modules/style-mod/src/style-mod.js","../../node_modules/w3c-keyname/index.js","../../node_modules/crelt/index.js","../../node_modules/@codemirror/view/dist/index.js","../../node_modules/@lezer/common/dist/index.js","../../node_modules/@lezer/highlight/dist/index.js","../../node_modules/@codemirror/language/dist/index.js","../../node_modules/@codemirror/commands/dist/index.js","../../node_modules/@codemirror/search/dist/index.js","../../node_modules/@codemirror/autocomplete/dist/index.js","../../node_modules/@codemirror/lint/dist/index.js","../../node_modules/@uiw/codemirror-extensions-basic-setup/esm/index.js","../../node_modules/@codemirror/theme-one-dark/dist/index.js","../../node_modules/@uiw/react-codemirror/esm/theme/light.js","../../node_modules/@uiw/react-codemirror/esm/getDefaultExtensions.js","../../node_modules/@uiw/react-codemirror/esm/utils.js","../../node_modules/@uiw/react-codemirror/esm/timeoutLatch.js","../../node_modules/@uiw/react-codemirror/esm/useCodeMirror.js","../../node_modules/@uiw/react-codemirror/esm/index.js","../../node_modules/@lezer/lr/dist/index.js","../../node_modules/@lezer/python/dist/index.js","../../node_modules/@codemirror/lang-python/dist/index.js","../../src/components/BotCodeEditor.tsx"],"sourcesContent":["function _extends() {\n return _extends = Object.assign ? Object.assign.bind() : function (n) {\n for (var e = 1; e < arguments.length; e++) {\n var t = arguments[e];\n for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);\n }\n return n;\n }, _extends.apply(null, arguments);\n}\nexport { _extends as default };","function _objectWithoutPropertiesLoose(r, e) {\n if (null == r) return {};\n var t = {};\n for (var n in r) if ({}.hasOwnProperty.call(r, n)) {\n if (-1 !== e.indexOf(n)) continue;\n t[n] = r[n];\n }\n return t;\n}\nexport { _objectWithoutPropertiesLoose as default };","// These are filled with ranges (rangeFrom[i] up to but not including\n// rangeTo[i]) of code points that count as extending characters.\nlet rangeFrom = [], rangeTo = []\n\n;(() => {\n // Compressed representation of the Grapheme_Cluster_Break=Extend\n // information from\n // http://www.unicode.org/Public/16.0.0/ucd/auxiliary/GraphemeBreakProperty.txt.\n // Each pair of elements represents a range, as an offet from the\n // previous range and a length. Numbers are in base-36, with the empty\n // string being a shorthand for 1.\n let numbers = \"lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o\".split(\",\").map(s => s ? parseInt(s, 36) : 1)\n for (let i = 0, n = 0; i < numbers.length; i++)\n (i % 2 ? rangeTo : rangeFrom).push(n = n + numbers[i])\n})()\n\nexport function isExtendingChar(code) {\n if (code < 768) return false\n for (let from = 0, to = rangeFrom.length;;) {\n let mid = (from + to) >> 1\n if (code < rangeFrom[mid]) to = mid\n else if (code >= rangeTo[mid]) from = mid + 1\n else return true\n if (from == to) return false\n }\n}\n\nfunction isRegionalIndicator(code) {\n return code >= 0x1F1E6 && code <= 0x1F1FF\n}\n\nfunction check(code) {\n for (let i = 0; i < rangeFrom.length; i++) {\n if (rangeTo[i] > code) return rangeFrom[i] <= code\n }\n return false\n}\n\nconst ZWJ = 0x200d\n\nexport function findClusterBreak(str, pos, forward = true, includeExtending = true) {\n return (forward ? nextClusterBreak : prevClusterBreak)(strLine truncated
+572
View File
@@ -0,0 +1,572 @@
var yy=Object.defineProperty;var _y=(n,s,i)=>s in n?yy(n,s,{enumerable:!0,configurable:!0,writable:!0,value:i}):n[s]=i;var qo=(n,s,i)=>_y(n,typeof s!="symbol"?s+"":s,i);function wy(n,s){for(var i=0;i<s.length;i++){const l=s[i];if(typeof l!="string"&&!Array.isArray(l)){for(const c in l)if(c!=="default"&&!(c in n)){const u=Object.getOwnPropertyDescriptor(l,c);u&&Object.defineProperty(n,c,u.get?u:{enumerable:!0,get:()=>l[c]})}}}return Object.freeze(Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}))}(function(){const s=document.createElement("link").relList;if(s&&s.supports&&s.supports("modulepreload"))return;for(const c of document.querySelectorAll('link[rel="modulepreload"]'))l(c);new MutationObserver(c=>{for(const u of c)if(u.type==="childList")for(const p of u.addedNodes)p.tagName==="LINK"&&p.rel==="modulepreload"&&l(p)}).observe(document,{childList:!0,subtree:!0});function i(c){const u={};return c.integrity&&(u.integrity=c.integrity),c.referrerPolicy&&(u.referrerPolicy=c.referrerPolicy),c.crossOrigin==="use-credentials"?u.credentials="include":c.crossOrigin==="anonymous"?u.credentials="omit":u.credentials="same-origin",u}function l(c){if(c.ep)return;c.ep=!0;const u=i(c);fetch(c.href,u)}})();var Qf=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function aa(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}function Ax(n){if(Object.prototype.hasOwnProperty.call(n,"__esModule"))return n;var s=n.default;if(typeof s=="function"){var i=function l(){return this instanceof l?Reflect.construct(s,arguments,this.constructor):s.apply(this,arguments)};i.prototype=s.prototype}else i={};return Object.defineProperty(i,"__esModule",{value:!0}),Object.keys(n).forEach(function(l){var c=Object.getOwnPropertyDescriptor(n,l);Object.defineProperty(i,l,c.get?c:{enumerable:!0,get:function(){return n[l]}})}),i}var Yf={exports:{}},el={},Xf={exports:{}},gt={};/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var Gp;function by(){if(Gp)return gt;Gp=1;var n=Symbol.for("react.element"),s=Symbol.for("react.portal"),i=Symbol.for("react.fragment"),l=Symbol.for("react.strict_mode"),c=Symbol.for("react.profiler"),u=Symbol.for("react.provider"),p=Symbol.for("react.context"),d=Symbol.for("react.forward_ref"),g=Symbol.for("react.suspense"),m=Symbol.for("react.memo"),x=Symbol.for("react.lazy"),A=Symbol.iterator;function b(T){return T===null||typeof T!="object"?null:(T=A&&T[A]||T["@@iterator"],typeof T=="function"?T:null)}var k={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},N=Object.assign,C={};function w(T,z,q){this.props=T,this.context=z,this.refs=C,this.updater=q||k}w.prototype.isReactComponent={},w.prototype.setState=function(T,z){if(typeof T!="object"&&typeof T!="function"&&T!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,T,z,"setState")},w.prototype.forceUpdate=function(T){this.updater.enqueueForceUpdate(this,T,"forceUpdate")};function B(){}B.prototype=w.prototype;function S(T,z,q){this.props=T,this.context=z,this.refs=C,this.updater=q||k}var R=S.prototype=new B;R.constructor=S,N(R,w.prototype),R.isPureReactComponent=!0;var F=Array.isArray,M=Object.prototype.hasOwnProperty,H={current:null},U={key:!0,ref:!0,__self:!0,__source:!0};function j(T,z,q){var $,ue={},pe=null,Ae=null;if(z!=null)for($ in z.ref!==void 0&&(Ae=z.ref),z.key!==void 0&&(pe=""+z.key),z)M.call(z,$)&&!U.hasOwnProperty($)&&(ue[$]=z[$]);var me=arguments.length-2;if(me===1)ue.children=q;else if(1<me){for(var ge=Array(me),Be=0;Be<me;Be++)ge[Be]=arguments[Be+2];ue.children=ge}if(T&&T.defaultProps)for($ in me=T.defaultProps,me)ue[$]===void 0&&(ue[$]=me[$]);return{$$typeof:n,type:T,key:pe,ref:Ae,props:ue,_owner:H.current}}function ee(T,z){return{$$typeof:n,type:T.type,key:z,ref:T.ref,props:T.props,_owner:T._owner}}function Z(T){return typeof T=="object"&&T!==null&&T.$$typeof===n}function Y(T){var z={"=":"=0",":":"=2"};return"$"+T.replace(/[=:]/g,function(q){return z[q]})}var ne=/\/+/g;function K(T,z){return typeof T=="object"&&T!==null&&T.key!=null?Y(""+T.key):z.toString(36)}function ae(T,z,q,$,ue){var pe=typeof T;(pe==="undefined"||pe==="boolean")&&(T=null);var Ae=!1;if(T===null)Ae=!0;else switch(pe){case"string":case"number":Ae=!0;break;case"object":switch(T.$$typeof){case n:case s:Ae=!0}}if(Ae)return Ae=T,ue=ue(Ae),T=$===""?"."+K(Ae,0):$,F(ue)?(q="",T!=null&&(q=T.replace(ne,"$&/")+"/"),ae(ue,z,q,"",function(Be){return Be})):ue!=null&&(Z(ue)&&(ue=ee(ue,q+(!ue.key||Ae&&Ae.key===ue.key?"":(""+ue.key).replace(ne,"$&/")+"/")+T)),z.push(ue)),1;if(Ae=0,$=$===""?".":$+":",F(T))for(var me=0;me<T.length;me++){pe=T[me];var ge=$+K(pe,me);Ae+=ae(pe,z,q,ge,ue)}else if(ge=b(T),typeof ge=="function")for(T=ge.call(T),me=0;!(pe=T.next()).done;)pe=pe.value,ge=$+K(pe,me++),Ae+=ae(pe,z,q,ge,ue);else if(pe==="object")throw z=String(T),Error("Objects are not valid as a React child (found: "+(z==="[object Object]"?"object with keys {"+Object.keys(T).join(", ")+"}":z)+"). If you meant to render a collection of children, use an array instead.");return Ae}function xe(T,z,q){if(T==null)return T;var $=[],ue=0;return ae(T,$,"","",function(pe){return z.call(q,pe,ue++)}),$}function G(T){if(T._status===-1){var z=T._result;z=z(),z.then(function(q){(T._status===0||T._status===-1)&&(T._status=1,T._result=q)},function(q){(T._status===0||T._status===-1)&&(T._status=2,T._result=q)}),T._status===-1&&(T._status=0,T._result=z)}if(T._status===1)return T._result.default;throw T._result}var se={current:null},W={transition:null},re={ReactCurrentDispatcher:se,ReactCurrentBatchConfig:W,ReactCurrentOwner:H};function V(){throw Error("act(...) is not supported in production builds of React.")}return gt.Children={map:xe,forEach:function(T,z,q){xe(T,function(){z.apply(this,arguments)},q)},count:function(T){var z=0;return xe(T,function(){z++}),z},toArray:function(T){return xe(T,function(z){return z})||[]},only:function(T){if(!Z(T))throw Error("React.Children.only expected to receive a single React element child.");return T}},gt.Component=w,gt.Fragment=i,gt.Profiler=c,gt.PureComponent=S,gt.StrictMode=l,gt.Suspense=g,gt.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=re,gt.act=V,gt.cloneElement=function(T,z,q){if(T==null)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+T+".");var $=N({},T.props),ue=T.key,pe=T.ref,Ae=T._owner;if(z!=null){if(z.ref!==void 0&&(pe=z.ref,Ae=H.current),z.key!==void 0&&(ue=""+z.key),T.type&&T.type.defaultProps)var me=T.type.defaultProps;for(ge in z)M.call(z,ge)&&!U.hasOwnProperty(ge)&&($[ge]=z[ge]===void 0&&me!==void 0?me[ge]:z[ge])}var ge=arguments.length-2;if(ge===1)$.children=q;else if(1<ge){me=Array(ge);for(var Be=0;Be<ge;Be++)me[Be]=arguments[Be+2];$.children=me}return{$$typeof:n,type:T.type,key:ue,ref:pe,props:$,_owner:Ae}},gt.crLine truncated
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var Kp;function Cy(){if(Kp)return el;Kp=1;var n=M0(),s=Symbol.for("react.element"),i=Symbol.for("react.fragment"),l=Object.prototype.hasOwnProperty,c=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,u={key:!0,ref:!0,__self:!0,__source:!0};function p(d,g,m){var x,A={},b=null,k=null;m!==void 0&&(b=""+m),g.key!==void 0&&(b=""+g.key),g.ref!==void 0&&(k=g.ref);for(x in g)l.call(g,x)&&!u.hasOwnProperty(x)&&(A[x]=g[x]);if(d&&d.defaultProps)for(x in g=d.defaultProps,g)A[x]===void 0&&(A[x]=g[x]);return{$$typeof:s,type:d,key:b,ref:k,props:A,_owner:c.current}}return el.Fragment=i,el.jsx=p,el.jsxs=p,el}var Qp;function Ey(){return Qp||(Qp=1,Yf.exports=Cy()),Yf.exports}var _=Ey(),D=M0();const Pe=aa(D),I0=wy({__proto__:null,default:Pe},[D]);var Vc={},Jf={exports:{}},Qn={},e0={exports:{}},t0={};/**
* @license React
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var Yp;function ky(){return Yp||(Yp=1,(function(n){function s(W,re){var V=W.length;W.push(re);e:for(;0<V;){var T=V-1>>>1,z=W[T];if(0<c(z,re))W[T]=re,W[V]=z,V=T;else break e}}function i(W){return W.length===0?null:W[0]}function l(W){if(W.length===0)return null;var re=W[0],V=W.pop();if(V!==re){W[0]=V;e:for(var T=0,z=W.length,q=z>>>1;T<q;){var $=2*(T+1)-1,ue=W[$],pe=$+1,Ae=W[pe];if(0>c(ue,V))pe<z&&0>c(Ae,ue)?(W[T]=Ae,W[pe]=V,T=pe):(W[T]=ue,W[$]=V,T=$);else if(pe<z&&0>c(Ae,V))W[T]=Ae,W[pe]=V,T=pe;else break e}}return re}function c(W,re){var V=W.sortIndex-re.sortIndex;return V!==0?V:W.id-re.id}if(typeof performance=="object"&&typeof performance.now=="function"){var u=performance;n.unstable_now=function(){return u.now()}}else{var p=Date,d=p.now();n.unstable_now=function(){return p.now()-d}}var g=[],m=[],x=1,A=null,b=3,k=!1,N=!1,C=!1,w=typeof setTimeout=="function"?setTimeout:null,B=typeof clearTimeout=="function"?clearTimeout:null,S=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function R(W){for(var re=i(m);re!==null;){if(re.callback===null)l(m);else if(re.startTime<=W)l(m),re.sortIndex=re.expirationTime,s(g,re);else break;re=i(m)}}function F(W){if(C=!1,R(W),!N)if(i(g)!==null)N=!0,G(M);else{var re=i(m);re!==null&&se(F,re.startTime-W)}}function M(W,re){N=!1,C&&(C=!1,B(j),j=-1),k=!0;var V=b;try{for(R(re),A=i(g);A!==null&&(!(A.expirationTime>re)||W&&!Y());){var T=A.callback;if(typeof T=="function"){A.callback=null,b=A.priorityLevel;var z=T(A.expirationTime<=re);re=n.unstable_now(),typeof z=="function"?A.callback=z:A===i(g)&&l(g),R(re)}else l(g);A=i(g)}if(A!==null)var q=!0;else{var $=i(m);$!==null&&se(F,$.startTime-re),q=!1}return q}finally{A=null,b=V,k=!1}}var H=!1,U=null,j=-1,ee=5,Z=-1;function Y(){return!(n.unstable_now()-Z<ee)}function ne(){if(U!==null){var W=n.unstable_now();Z=W;var re=!0;try{re=U(!0,W)}finally{re?K():(H=!1,U=null)}}else H=!1}var K;if(typeof S=="function")K=function(){S(ne)};else if(typeof MessageChannel<"u"){var ae=new MessageChannel,xe=ae.port2;ae.port1.onmessage=ne,K=function(){xe.postMessage(null)}}else K=function(){w(ne,0)};function G(W){U=W,H||(H=!0,K())}function se(W,re){j=w(function(){W(n.unstable_now())},re)}n.unstable_IdlePriority=5,n.unstable_ImmediatePriority=1,n.unstable_LowPriority=4,n.unstable_NormalPriority=3,n.unstable_Profiling=null,n.unstable_UserBlockingPriority=2,n.unstable_cancelCallback=function(W){W.callback=null},n.unstable_continueExecution=function(){N||k||(N=!0,G(M))},n.unstable_forceFrameRate=function(W){0>W||125<W?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):ee=0<W?Math.floor(1e3/W):5},n.unstable_getCurrentPriorityLevel=function(){return b},n.unstable_getFirstCallbackNode=function(){return i(g)},n.unstable_next=function(W){switch(b){case 1:case 2:case 3:var re=3;break;default:re=b}var V=b;b=re;try{return W()}finally{b=V}},n.unstable_pauseExecution=function(){},n.unstable_requestPaint=function(){},n.unstable_runWithPriority=function(W,re){switch(W){case 1:case 2:case 3:case 4:case 5:break;default:W=3}var V=b;b=W;try{return re()}finally{b=V}},n.unstable_scheduleCallback=function(W,re,V){var T=n.unstable_now();switch(typeof V=="object"&&V!==null?(V=V.delay,V=typeof V=="number"&&0<V?T+V:T):V=T,W){case 1:var z=-1;break;case 2:z=250;break;case 5:z=1073741823;break;case 4:z=1e4;break;default:z=5e3}return z=V+z,W={id:x++,callback:re,priorityLevel:W,startTime:V,expirationTime:z,sortIndex:-1},V>T?(W.sortIndex=V,s(m,W),i(g)===null&&W===i(m)&&(C?(B(j),j=-1):C=!0,se(F,V-T))):(W.sortIndex=z,s(g,W),N||k||(N=!0,G(M))),W},n.unstable_shouldYield=Y,n.unstable_wrapCallback=function(W){var re=b;return function(){var V=b;b=re;try{return W.apply(this,arguments)}finally{b=V}}}})(t0)),t0}var Xp;function Sy(){return Xp||(Xp=1,e0.exports=ky()),e0.exports}/**
* @license React
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var Jp;function By(){if(Jp)return Qn;Jp=1;var n=M0(),s=Sy();function i(e){for(var r="https://reactjs.org/docs/error-decoder.html?invariant="+e,a=1;a<arguments.length;a++)r+="&args[]="+encodeURIComponent(arguments[a]);return"Minified React error #"+e+"; visit "+r+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var l=new Set,c={};function u(e,r){p(e,r),p(e+"Capture",r)}function p(e,r){for(c[e]=r,e=0;e<r.length;e++)l.add(r[e])}var d=!(typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),g=Object.prototype.hasOwnProperty,m=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,x={},A={};function b(e){return g.call(A,e)?!0:g.call(x,e)?!1:m.test(e)?A[e]=!0:(x[e]=!0,!1)}function k(e,r,a,h){if(a!==null&&a.type===0)return!1;switch(typeof r){case"function":case"symbol":return!0;case"boolean":return h?!1:a!==null?!a.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function N(e,r,a,h){if(r===null||typeof r>"u"||k(e,r,a,h))return!0;if(h)return!1;if(a!==null)switch(a.type){case 3:return!r;case 4:return r===!1;case 5:return isNaN(r);case 6:return isNaN(r)||1>r}return!1}function C(e,r,a,h,y,E,I){this.acceptsBooleans=r===2||r===3||r===4,this.attributeName=h,this.attributeNamespace=y,this.mustUseProperty=a,this.propertyName=e,this.type=r,this.sanitizeURL=E,this.removeEmptyString=I}var w={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){w[e]=new C(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var r=e[0];w[r]=new C(r,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){w[e]=new C(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){w[e]=new C(e,2,!1,e,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){w[e]=new C(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){w[e]=new C(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){w[e]=new C(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){w[e]=new C(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){w[e]=new C(e,5,!1,e.toLowerCase(),null,!1,!1)});var B=/[\-:]([a-z])/g;function S(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var r=e.replace(B,S);w[r]=new C(r,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var r=e.replace(B,S);w[r]=new C(r,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var r=e.replace(B,S);w[r]=new C(r,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){w[e]=new C(e,1,!1,e.toLowerCase(),null,!1,!1)}),w.xlinkHref=new C("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){w[e]=new C(e,1,!1,e.toLowerCase(),null,!0,!0)});function R(e,r,a,h){var y=w.hasOwnProperty(r)?w[r]:null;(y!==null?y.type!==0:h||!(2<r.length)||r[0]!=="o"&&r[0]!=="O"||r[1]!=="n"&&r[1]!= Line truncated
`+T+e}var q=!1;function $(e,r){if(!e||q)return"";q=!0;var a=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(r)if(r=function(){throw Error()},Object.defineProperty(r.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(r,[])}catch(he){var h=he}Reflect.construct(e,[],r)}else{try{r.call()}catch(he){h=he}e.call(r.prototype)}else{try{throw Error()}catch(he){h=he}e()}}catch(he){if(he&&h&&typeof he.stack=="string"){for(var y=he.stack.split(`
`),E=h.stack.split(`
`),I=y.length-1,Q=E.length-1;1<=I&&0<=Q&&y[I]!==E[Q];)Q--;for(;1<=I&&0<=Q;I--,Q--)if(y[I]!==E[Q]){if(I!==1||Q!==1)do if(I--,Q--,0>Q||y[I]!==E[Q]){var J=`
`+y[I].replace(" at new "," at ");return e.displayName&&J.includes("<anonymous>")&&(J=J.replace("<anonymous>",e.displayName)),J}while(1<=I&&0<=Q);break}}}finally{q=!1,Error.prepareStackTrace=a}return(e=e?e.displayName||e.name:"")?z(e):""}function ue(e){switch(e.tag){case 5:return z(e.type);case 16:return z("Lazy");case 13:return z("Suspense");case 19:return z("SuspenseList");case 0:case 2:case 15:return e=$(e.type,!1),e;case 11:return e=$(e.type.render,!1),e;case 1:return e=$(e.type,!0),e;default:return""}}function pe(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case U:return"Fragment";case H:return"Portal";case ee:return"Profiler";case j:return"StrictMode";case K:return"Suspense";case ae:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case Y:return(e.displayName||"Context")+".Consumer";case Z:return(e._context.displayName||"Context")+".Provider";case ne:var r=e.render;return e=e.displayName,e||(e=r.displayName||r.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case xe:return r=e.displayName||null,r!==null?r:pe(e.type)||"Memo";case G:r=e._payload,e=e._init;try{return pe(e(r))}catch{}}return null}function Ae(e){var r=e.type;switch(e.tag){case 24:return"Cache";case 9:return(r.displayName||"Context")+".Consumer";case 10:return(r._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=r.render,e=e.displayName||e.name||"",r.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return r;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return pe(r);case 8:return r===j?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof r=="function")return r.displayName||r.name||null;if(typeof r=="string")return r}return null}function me(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function ge(e){var r=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(r==="checkbox"||r==="radio")}function Be(e){var r=ge(e)?"checked":"value",a=Object.getOwnPropertyDescriptor(e.constructor.prototype,r),h=""+e[r];if(!e.hasOwnProperty(r)&&typeof a<"u"&&typeof a.get=="function"&&typeof a.set=="function"){var y=a.get,E=a.set;return Object.defineProperty(e,r,{configurable:!0,get:function(){return y.call(this)},set:function(I){h=""+I,E.call(this,I)}}),Object.defineProperty(e,r,{enumerable:a.enumerable}),{getValue:function(){return h},setValue:function(I){h=""+I},stopTracking:function(){e._valueTracker=null,delete e[r]}}}}function We(e){e._valueTracker||(e._valueTracker=Be(e))}function Ke(e){if(!e)return!1;var r=e._valueTracker;if(!r)return!0;var a=r.getValue(),h="";return e&&(h=ge(e)?e.checked?"true":"false":e.value),e=h,e!==a?(r.setValue(e),!0):!1}function Ee(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function Ue(e,r){var a=r.checked;return V({},r,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:a??e._wrapperState.initialChecked})}function ot(e,r){var a=r.defaultValue==null?"":r.defaultValue,h=r.checked!=null?r.checked:r.defaultChecked;a=me(r.value!=null?r.value:a),e._wrapperState={initialChecked:h,initialValue:a,controlled:r.type==="checkbox"||r.type==="radio"?r.checked!=null:r.value!=null}}function ht(e,r){r=r.checked,r!=null&&R(e,"checked",r,!1)}function et(e,r){ht(e,r);var a=me(r.value),h=r.type;if(a!=null)h==="number"?(a===0&&e.value===""||e.value!=a)&&(e.value=""+a):e.value!==""+a&&(e.value=""+a);else if(h==="submit"||h==="reset"){e.removeAttribute("value");return}r.hasOwnProperty("value")?Ge(e,r.type,a):r.hasOwnProperty("defaultValue")&&Ge(e,r.type,me(r.defaultValue)),r.checked==null&&r.defaultChecked!=null&&(e.defaultChecked=!!r.defaultChecked)}function st(e,r,a){if(r.hasOwnProperty("value")||r.hasOwnProperty("defaultValue")){var h=r.type;if(!(h!=="submit"&&h!=="reset"||r.value!==void 0&&r.value!==null))return;r=""+e._wrapperState.initialValue,a||r===e.value||(e.value=r),e.defaultValue=r}a=e.name,a!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,a!==""&&(e.name=a)}function Ge(e,r,a){(r!=="number"||Ee(e.ownerDocument)!==e)&&(a==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+a&&(e.defaultValue=""+a))}var $e=Array.isArray;function Ye(e,r,a,h){if(e=e.options,r){r={};for(var y=0;y<a.length;y++)r["$"+a[y]]=!0;for(a=0;a<e.length;a++)y=r.hasOwnProperty("$"+e[a].value),e[a].selected!==y&&(e[a].selected=y),y&&h&&(e[a].defaultSelected=!0)}else{for(a=""+me(a),r=null,y=0;y<e.length;y++){if(e[y].value===a){e[y].selected=!0,h&&(e[y].defaultSelected=!0);return}r!==null||e[y].disabled||(r=e[y])}r!==null&&(r.selected=!0)}}function Me(e,r){if(r.dangerouslySetInnerHTM Line truncated
`).replace(X,"")}function fe(e,r,a){if(r=le(r),le(e)!==r&&a)throw Error(i(425))}function we(){}var Ne=null,Qe=null;function ut(e,r){return e==="textarea"||e==="noscript"||typeof r.children=="string"||typeof r.children=="number"||typeof r.dangerouslySetInnerHTML=="object"&&r.dangerouslySetInnerHTML!==null&&r.dangerouslySetInnerHTML.__html!=null}var ln=typeof setTimeout=="function"?setTimeout:void 0,rn=typeof clearTimeout=="function"?clearTimeout:void 0,In=typeof Promise=="function"?Promise:void 0,Sn=typeof queueMicrotask=="function"?queueMicrotask:typeof In<"u"?function(e){return In.resolve(null).then(e).catch(Ji)}:ln;function Ji(e){setTimeout(function(){throw e})}function ja(e,r){var a=r,h=0;do{var y=a.nextSibling;if(e.removeChild(a),y&&y.nodeType===8)if(a=y.data,a==="/$"){if(h===0){e.removeChild(y),nr(r);return}h--}else a!=="$"&&a!=="$?"&&a!=="$!"||h++;a=y}while(a);nr(r)}function Qr(e){for(;e!=null;e=e.nextSibling){var r=e.nodeType;if(r===1||r===3)break;if(r===8){if(r=e.data,r==="$"||r==="$!"||r==="$?")break;if(r==="/$")return null}}return e}function rc(e){e=e.previousSibling;for(var r=0;e;){if(e.nodeType===8){var a=e.data;if(a==="$"||a==="$!"||a==="$?"){if(r===0)return e;r--}else a==="/$"&&r++}e=e.previousSibling}return null}var pi=Math.random().toString(36).slice(2),xr="__reactFiber$"+pi,eo="__reactProps$"+pi,kt="__reactContainer$"+pi,to="__reactEvents$"+pi,Zd="__reactListeners$"+pi,Wd="__reactHandles$"+pi;function mi(e){var r=e[xr];if(r)return r;for(var a=e.parentNode;a;){if(r=a[kt]||a[xr]){if(a=r.alternate,r.child!==null||a!==null&&a.child!==null)for(e=rc(e);e!==null;){if(a=e[xr])return a;e=rc(e)}return r}e=a,a=e.parentNode}return null}function gi(e){return e=e[xr]||e[kt],!e||e.tag!==5&&e.tag!==6&&e.tag!==13&&e.tag!==3?null:e}function xi(e){if(e.tag===5||e.tag===6)return e.stateNode;throw Error(i(33))}function Ns(e){return e[eo]||null}var qd=[],Fs=-1;function no(e){return{current:e}}function zt(e){0>Fs||(e.current=qd[Fs],qd[Fs]=null,Fs--)}function Mt(e,r){Fs++,qd[Fs]=e.current,e.current=r}var ro={},Bn=no(ro),Wn=no(!1),Lo=ro;function Ls(e,r){var a=e.type.contextTypes;if(!a)return ro;var h=e.stateNode;if(h&&h.__reactInternalMemoizedUnmaskedChildContext===r)return h.__reactInternalMemoizedMaskedChildContext;var y={},E;for(E in a)y[E]=r[E];return h&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=r,e.__reactInternalMemoizedMaskedChildContext=y),y}function qn(e){return e=e.childContextTypes,e!=null}function ic(){zt(Wn),zt(Bn)}function mh(e,r,a){if(Bn.current!==ro)throw Error(i(168));Mt(Bn,r),Mt(Wn,a)}function gh(e,r,a){var h=e.stateNode;if(r=r.childContextTypes,typeof h.getChildContext!="function")return a;h=h.getChildContext();for(var y in h)if(!(y in r))throw Error(i(108,Ae(e)||"Unknown",y));return V({},a,h)}function oc(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||ro,Lo=Bn.current,Mt(Bn,e),Mt(Wn,Wn.current),!0}function xh(e,r,a){var h=e.stateNode;if(!h)throw Error(i(169));a?(e=gh(e,r,Lo),h.__reactInternalMemoizedMergedChildContext=e,zt(Wn),zt(Bn),Mt(Bn,e)):zt(Wn),Mt(Wn,a)}var Ai=null,sc=!1,Gd=!1;function Ah(e){Ai===null?Ai=[e]:Ai.push(e)}function jv(e){sc=!0,Ah(e)}function io(){if(!Gd&&Ai!==null){Gd=!0;var e=0,r=_t;try{var a=Ai;for(_t=1;e<a.length;e++){var h=a[e];do h=h(!0);while(h!==null)}Ai=null,sc=!1}catch(y){throw Ai!==null&&(Ai=Ai.slice(e+1)),Nl(pa,io),y}finally{_t=r,Gd=!1}}return null}var Ms=[],Is=0,ac=null,lc=0,Ar=[],vr=0,Mo=null,vi=1,yi="";function Io(e,r){Ms[Is++]=lc,Ms[Is++]=ac,ac=e,lc=r}function vh(e,r,a){Ar[vr++]=vi,Ar[vr++]=yi,Ar[vr++]=Mo,Mo=e;var h=vi;e=yi;var y=32-at(h)-1;h&=~(1<<y),a+=1;var E=32-at(r)+y;if(30<E){var I=y-y%5;E=(h&(1<<I)-1).toString(32),h>>=I,y-=I,vi=1<<32-at(r)+y|a<<y|h,yi=E+e}else vi=1<<E|a<<y|h,yi=e}function $d(e){e.return!==null&&(Io(e,1),vh(e,1,0))}function Kd(e){for(;e===ac;)ac=Ms[--Is],Ms[Is]=null,lc=Ms[--Is],Ms[Is]=null;for(;e===Mo;)Mo=Ar[--vr],Ar[vr]=null,yi=Ar[--vr],Ar[vr]=null,vi=Ar[--vr],Ar[vr]=null}var ar=null,lr=null,Zt=!1,Nr=null;function yh(e,r){var a=br(5,null,null,0);a.elementType="DELETED",a.stateNode=r,a.return=e,r=e.deletions,r===null?(e.deletions=[a],e.flags|=16):r.push(a)}function _h(e,r){switch(e.tag){case 5:var a=e.type;return r=r.nodeType!==1||a.toLowerCase()!==r.nodeName.toLowerCase()?null:r,r!==null?(e.stateNode=r,ar=e,lr=Qr(r.firstChild),!0):!1;case 6:return r=e.pendingProps===""||r.nodeType!==3?null:r,r!==null?(e.stateNode=r,ar=e,lr=null,!0):!1;case 13:return r=r.nodeType!==8?null:r,r!==null?(a=Mo!==null?{id:vi,overflow:yi}:null,e.memoizedState={dehydrated:r,treeContext:a,retryLane:1073741824},a=br(18,null,null,0),a.stateNode=r,a.return=e,e.child=a,ar=e,lr=null,!0):!1;default:return!1}}function Qd(e){return(e.mode&1)!==0&&(e.flags&128)===0}function Yd(e){if(Zt){var r=lr;if(r){var a=r;if(!_h(e,r)){if(Qd(e))throw Error(i(418));r=Qr(a.nextSibling);var h=ar;r&&_h(e,r)?yh(h,a):(e.flags=e.flags&-4097|2,Zt=!1,ar=e)}}else{if(Qd(e))throw Error(i(418));e.flags=e.flags&-4097|2,Zt=!1,ar=e}}}function wh(e){for(e=e.r Line truncated
Error generating stack: `+E.message+`
`+E.stack}return{value:e,source:r,stack:y,digest:null}}function yf(e,r,a){return{value:e,source:null,stack:a??null,digest:r??null}}function _f(e,r){try{console.error(r.value)}catch(a){setTimeout(function(){throw a})}}var $v=typeof WeakMap=="function"?WeakMap:Map;function np(e,r,a){a=wi(-1,a),a.tag=3,a.payload={element:null};var h=r.value;return a.callback=function(){Bc||(Bc=!0,Mf=h),_f(e,r)},a}function rp(e,r,a){a=wi(-1,a),a.tag=3;var h=e.type.getDerivedStateFromError;if(typeof h=="function"){var y=r.value;a.payload=function(){return h(y)},a.callback=function(){_f(e,r)}}var E=e.stateNode;return E!==null&&typeof E.componentDidCatch=="function"&&(a.callback=function(){_f(e,r),typeof h!="function"&&(lo===null?lo=new Set([this]):lo.add(this));var I=r.stack;this.componentDidCatch(r.value,{componentStack:I!==null?I:""})}),a}function ip(e,r,a){var h=e.pingCache;if(h===null){h=e.pingCache=new $v;var y=new Set;h.set(r,y)}else y=h.get(r),y===void 0&&(y=new Set,h.set(r,y));y.has(a)||(y.add(a),e=ly.bind(null,e,r,a),r.then(e,e))}function op(e){do{var r;if((r=e.tag===13)&&(r=e.memoizedState,r=r!==null?r.dehydrated!==null:!0),r)return e;e=e.return}while(e!==null);return null}function sp(e,r,a,h,y){return(e.mode&1)===0?(e===r?e.flags|=65536:(e.flags|=128,a.flags|=131072,a.flags&=-52805,a.tag===1&&(a.alternate===null?a.tag=17:(r=wi(-1,1),r.tag=2,so(a,r,1))),a.lanes|=1),e):(e.flags|=65536,e.lanes=y,e)}var Kv=F.ReactCurrentOwner,Gn=!1;function On(e,r,a,h){r.child=e===null?kh(r,null,a,h):js(r,e.child,a,h)}function ap(e,r,a,h,y){a=a.render;var E=r.ref;return Hs(r,y),h=ff(e,r,a,h,E,y),a=hf(),e!==null&&!Gn?(r.updateQueue=e.updateQueue,r.flags&=-2053,e.lanes&=~y,bi(e,r,y)):(Zt&&a&&$d(r),r.flags|=1,On(e,r,h,y),r.child)}function lp(e,r,a,h,y){if(e===null){var E=a.type;return typeof E=="function"&&!Uf(E)&&E.defaultProps===void 0&&a.compare===null&&a.defaultProps===void 0?(r.tag=15,r.type=E,cp(e,r,E,h,y)):(e=Fc(a.type,null,h,r,r.mode,y),e.ref=r.ref,e.return=r,r.child=e)}if(E=e.child,(e.lanes&y)===0){var I=E.memoizedProps;if(a=a.compare,a=a!==null?a:Gr,a(I,h)&&e.ref===r.ref)return bi(e,r,y)}return r.flags|=1,e=ho(E,h),e.ref=r.ref,e.return=r,r.child=e}function cp(e,r,a,h,y){if(e!==null){var E=e.memoizedProps;if(Gr(E,h)&&e.ref===r.ref)if(Gn=!1,r.pendingProps=h=E,(e.lanes&y)!==0)(e.flags&131072)!==0&&(Gn=!0);else return r.lanes=e.lanes,bi(e,r,y)}return wf(e,r,a,h,y)}function up(e,r,a){var h=r.pendingProps,y=h.children,E=e!==null?e.memoizedState:null;if(h.mode==="hidden")if((r.mode&1)===0)r.memoizedState={baseLanes:0,cachePool:null,transitions:null},Mt(Ws,cr),cr|=a;else{if((a&1073741824)===0)return e=E!==null?E.baseLanes|a:a,r.lanes=r.childLanes=1073741824,r.memoizedState={baseLanes:e,cachePool:null,transitions:null},r.updateQueue=null,Mt(Ws,cr),cr|=e,null;r.memoizedState={baseLanes:0,cachePool:null,transitions:null},h=E!==null?E.baseLanes:a,Mt(Ws,cr),cr|=h}else E!==null?(h=E.baseLanes|a,r.memoizedState=null):h=a,Mt(Ws,cr),cr|=h;return On(e,r,y,a),r.child}function dp(e,r){var a=r.ref;(e===null&&a!==null||e!==null&&e.ref!==a)&&(r.flags|=512,r.flags|=2097152)}function wf(e,r,a,h,y){var E=qn(a)?Lo:Bn.current;return E=Ls(r,E),Hs(r,y),a=ff(e,r,a,h,E,y),h=hf(),e!==null&&!Gn?(r.updateQueue=e.updateQueue,r.flags&=-2053,e.lanes&=~y,bi(e,r,y)):(Zt&&h&&$d(r),r.flags|=1,On(e,r,a,y),r.child)}function fp(e,r,a,h,y){if(qn(a)){var E=!0;oc(r)}else E=!1;if(Hs(r,y),r.stateNode===null)bc(e,r),ep(r,a,h),vf(r,a,h,y),h=!0;else if(e===null){var I=r.stateNode,Q=r.memoizedProps;I.props=Q;var J=I.context,he=a.contextType;typeof he=="object"&&he!==null?he=yr(he):(he=qn(a)?Lo:Bn.current,he=Ls(r,he));var Ce=a.getDerivedStateFromProps,Se=typeof Ce=="function"||typeof I.getSnapshotBeforeUpdate=="function";Se||typeof I.UNSAFE_componentWillReceiveProps!="function"&&typeof I.componentWillReceiveProps!="function"||(Q!==h||J!==he)&&tp(r,I,h,he),oo=!1;var be=r.memoizedState;I.state=be,pc(r,h,I,y),J=r.memoizedState,Q!==h||be!==J||Wn.current||oo?(typeof Ce=="function"&&(Af(r,a,Ce,h),J=r.memoizedState),(Q=oo||Jh(r,a,Q,h,be,J,he))?(Se||typeof I.UNSAFE_componentWillMount!="function"&&typeof I.componentWillMount!="function"||(typeof I.componentWillMount=="function"&&I.componentWillMount(),typeof I.UNSAFE_componentWillMount=="function"&&I.UNSAFE_componentWillMount()),typeof I.componentDidMount=="function"&&(r.flags|=4194308)):(typeof I.componentDidMount=="function"&&(r.flags|=4194308),r.memoizedProps=h,r.memoizedState=J),I.props=h,I.state=J,I.context=he,h=Q):(typeof I.componentDidMount=="function"&&(r.flags|=4194308),h=!1)}else{I=r.stateNode,Bh(e,r),Q=r.memoizedProps,he=r.type===r.elementType?Q:Fr(r.type,Q),I.props=he,Se=r.pendingProps,be=I.context,J=a.contextType,typeof J=="object"&&J!==null?J=yr(J):(J=qn(a)?Lo:Bn.current,J=Ls(r,J));var Ie=a.getDerivedStateFromProps;(Ce=typeof Ie=="function"||typeof I.getSnapshotBeforeUpdate=="function")||typeof I.UNSAFE_componentWillReceiveProps!="function"&&typeof I.componentWillReceiveProps!="function"||(Q!==Se||be!==J)&&tp(r,I,h,J),oo=!1,be=r.m Line truncated
`)}function $s(n,s,i){const l=Math.floor(Date.now()/1e3);return{id:-Date.now(),type:"PRIV",conversation_key:n,text:s,sender_timestamp:l,received_at:l,paths:null,txt_type:0,signature:null,outgoing:i,acked:1}}function Iy(n){const s=D.useRef(null),i=D.useRef(null),l=D.useCallback(()=>{i.current!==null&&(clearInterval(i.current),i.current=null),s.current=null},[]),c=D.useCallback(async()=>{const p=s.current;if(!p)return;let d=null,g=null;for(let m=0;m<2;m++)try{d=await tt.requestTelemetry(p.conversationId,"");break}catch(x){g=x instanceof Error?x:new Error("Unknown error"),m===0&&await new Promise(A=>setTimeout(A,2e3))}if(d){const m=$s(p.conversationId,My(p,d),!1);n(x=>[...x,m])}else{const m=$s(p.conversationId,`Duty cycle poll failed after retry: ${(g==null?void 0:g.message)??"Unknown error"}`,!1);n(x=>[...x,m])}},[n]),u=D.useCallback(async(p,d)=>{const g=p.trim().toLowerCase();if(g==="dutycycle_start"){l();let m=null,x=null;for(let k=0;k<2;k++)try{m=await tt.requestTelemetry(d,"");break}catch(N){x=N instanceof Error?N:new Error("Unknown error"),k===0&&await new Promise(C=>setTimeout(C,2e3))}if(!m){const k=$s(d,`Failed to start duty cycle tracking after retry: ${(x==null?void 0:x.message)??"Unknown error"}`,!1);return n(N=>[...N,k]),!0}const A=Math.floor(Date.now()/1e3);s.current={startTime:A,uptime:m.uptime_seconds,txAirtime:m.airtime_seconds,rxAirtime:m.rx_airtime_seconds,sentFlood:m.sent_flood,sentDirect:m.sent_direct,recvFlood:m.recv_flood,recvDirect:m.recv_direct,conversationId:d};const b=$s(d,`Airtime/duty cycle statistics gathering begins at ${A}. Logs will follow every 5 minutes. To stop, run dutycycle_stop or navigate away from this conversation.`,!1);return n(k=>[...k,b]),i.current=window.setInterval(c,Fy),!0}if(g==="dutycycle_stop"){if(s.current&&s.current.conversationId===d){await c(),l();const m=$s(d,"Airtime/duty cycle statistics gathering stopped.",!1);n(x=>[...x,m])}else{const m=$s(d,"Duty cycle tracking is not active.",!1);n(x=>[...x,m])}return!0}return!1},[n,l,c]);return D.useEffect(()=>()=>{i.current!==null&&clearInterval(i.current)},[]),{handleAirtimeCommand:u,stopTracking:l}}function ru(n){if(n<60)return`${n}s`;const s=Math.floor(n/86400),i=Math.floor(n%86400/3600),l=Math.floor(n%3600/60);return s>0?i>0&&l>0?`${s}d${i}h${l}m`:i>0?`${s}d${i}h`:l>0?`${s}d${l}m`:`${s}d`:i>0?l>0?`${i}h${l}m`:`${i}h`:`${l}m`}function Oy(n){return["Telemetry",`Battery Voltage: ${n.battery_volts.toFixed(3)}V`,`Uptime: ${ru(n.uptime_seconds)}`,...n.clock_output?[`Clock: ${n.clock_output}`]:[],`TX Airtime: ${ru(n.airtime_seconds)}`,`RX Airtime: ${ru(n.rx_airtime_seconds)}`,"",`Noise Floor: ${n.noise_floor_dbm} dBm`,`Last RSSI: ${n.last_rssi_dbm} dBm`,`Last SNR: ${n.last_snr_db.toFixed(1)} dB`,"",`Packets: ${n.packets_received.toLocaleString()} rx / ${n.packets_sent.toLocaleString()} tx`,`Flood: ${n.recv_flood.toLocaleString()} rx / ${n.sent_flood.toLocaleString()} tx`,`Direct: ${n.recv_direct.toLocaleString()} rx / ${n.sent_direct.toLocaleString()} tx`,`Duplicates: ${n.flood_dups.toLocaleString()} flood / ${n.direct_dups.toLocaleString()} direct`,"",`TX Queue: ${n.tx_queue_len}`,`Debug Flags: ${n.full_events}`].join(`
`)}function jy(n){if(n.length===0)return`Neighbors
No neighbors reported`;const s=[...n].sort((l,c)=>c.snr-l.snr),i=[`Neighbors (${s.length})`];for(const l of s){const c=l.name||l.pubkey_prefix,u=l.snr>=0?`+${l.snr.toFixed(1)}`:l.snr.toFixed(1);i.push(`${c}, ${u} dB [${ru(l.last_heard_seconds)} ago]`)}return i.join(`
`)}function zy(n){if(n.length===0)return`ACL
No ACL entries`;const s=[`ACL (${n.length})`];for(const i of n){const l=i.name||i.pubkey_prefix;s.push(`${l}: ${i.permission_name}`)}return s.join(`
`)}function Go(n,s,i,l=0){const c=Math.floor(Date.now()/1e3);return{id:-Date.now()-l,type:"PRIV",conversation_key:n,text:s,sender_timestamp:c,received_at:c,paths:null,txt_type:0,signature:null,outgoing:i,acked:1}}function Hy(n,s,i){const[l,c]=D.useState(!1),{handleAirtimeCommand:u,stopTracking:p}=Iy(i);D.useEffect(()=>{c(!1),p()},[n==null?void 0:n.id,p]);const d=D.useMemo(()=>{if(!n||n.type!=="contact")return!1;const x=s.find(A=>A.public_key===n.id);return(x==null?void 0:x.type)===id},[n,s]),g=D.useCallback(async x=>{if(!(!n||n.type!=="contact")&&d)try{const A=await tt.requestTelemetry(n.id,x),b=Go(n.id,Oy(A),!1,0),k=Go(n.id,jy(A.neighbors),!1,1),N=Go(n.id,zy(A.acl),!1,2);i(C=>[...C,b,k,N]),c(!0)}catch(A){const b=Go(n.id,`Telemetry request failed: ${A instanceof Error?A.message:"Unknown error"}`,!1,0);i(k=>[...k,b])}},[n,d,i]),m=D.useCallback(async x=>{if(!n||n.type!=="contact"||!d||!l||await u(x,n.id))return;const b=Go(n.id,`> ${x}`,!0,0);i(k=>[...k,b]);try{const k=await tt.sendRepeaterCommand(n.id,x),N=Go(n.id,k.response,!1,1);k.sender_timestamp&&(N.sender_timestamp=k.sender_timestamp),i(C=>[...C,N])}catch(k){const N=Go(n.id,`Command failed: ${k instanceof Error?k.message:"Unknown error"}`,!1,1);i(C=>[...C,N])}},[n,d,l,i,u]);return{repeaterLoggedIn:l,activeContactIsRepeater:d,handleTelemetryRequest:g,handleRepeaterCommand:m}}const yx="remoteterm-lastMessageTime",_x="remoteterm-sortOrder";let $u={};function rm(n){$u={...n}}function im(){return{...$u}}function om(n,s){return $u[n]=s,{...$u}}function Di(n,s){return`${n}-${s}`}function Vy(){try{const n=localStorage.getItem(yx);return n?JSON.parse(n):{}}catch{return{}}}function Uy(){try{return localStorage.getItem(_x)==="alpha"?"alpha":"recent"}catch{return"recent"}}function sm(){try{localStorage.removeItem(yx),localStorage.removeItem(_x)}catch{}}function Zy(n,s,i,l=null){const[c,u]=D.useState({}),[p,d]=D.useState({}),[g,m]=D.useState(im),x=D.useRef(l);D.useEffect(()=>{x.current=l},[l]);const A=D.useCallback(async()=>{try{const w=await tt.getUnreads(x.current??void 0);if(u(w.counts),d(w.mentions),Object.keys(w.last_message_times).length>0){for(const[B,S]of Object.entries(w.last_message_times))om(B,S);m(im())}}catch(w){console.error("Failed to fetch unreads:",w)}},[]);D.useEffect(()=>{n.length===0&&s.length===0||A()},[n,s,A]),D.useEffect(()=>{if(i&&i.type!=="raw"&&i.type!=="map"&&i.type!=="visualizer"){const w=Di(i.type,i.id);u(B=>{if(B[w]){const S={...B};return delete S[w],S}return B}),d(B=>{if(B[w]){const S={...B};return delete S[w],S}return B}),i.type==="channel"?tt.markChannelRead(i.id).catch(B=>{console.error("Failed to mark channel as read on server:",B)}):i.type==="contact"&&tt.markContactRead(i.id).catch(B=>{console.error("Failed to mark contact as read on server:",B)})}},[i]);const b=D.useCallback((w,B)=>{u(S=>({...S,[w]:(S[w]||0)+1})),B&&d(S=>({...S,[w]:!0}))},[]),k=D.useCallback(()=>{u({}),d({}),tt.markAllRead().catch(w=>{console.error("Failed to mark all as read on server:",w)})},[]),N=D.useCallback(w=>{if(w.type==="raw"||w.type==="map"||w.type==="visualizer")return;const B=Di(w.type,w.id);u(S=>{if(S[B]){const R={...S};return delete R[B],R}return S}),d(S=>{if(S[B]){const R={...S};return delete R[B],R}return S}),w.type==="channel"?tt.markChannelRead(w.id).catch(S=>{console.error("Failed to mark channel as read on server:",S)}):w.type==="contact"&&tt.markContactRead(w.id).catch(S=>{console.error("Failed to mark contact as read on server:",S)})},[]),C=D.useCallback(w=>{let B=null;if(w.type==="CHAN"&&w.conversation_key?B=Di("channel",w.conversation_key):w.type==="PRIV"&&w.conversation_key&&(B=Di("contact",w.conversation_key)),B){const S=w.received_at||Math.floor(Date.now()/1e3),R=om(B,S);m(R)}},[]);return{unreadCounts:c,mentions:p,lastMessageTimes:g,incrementUnread:b,markAllRead:k,markConversationRead:N,trackNewMessage:C}}var O0=vx();const wx=aa(O0);function Wy(n){if(typeof document>"u")return;let s=document.head||document.getElementsByTagName("head")[0],i=document.createElement("style");i.type="text/css",s.appendChild(i),i.styleSheet?i.styleSheet.cssText=n:i.appendChild(document.createTextNode(n))}const qy=n=>{switch(n){case"success":return Ky;case"info":return Yy;case"warning":return Qy;case"error":return Xy;default:return null}},Gy=Array(12).fill(0),$y=({visible:n,className:s})=>Pe.createElement("div",{className:["sonner-loading-wrapper",s].filter(Boolean).join(" "),"data-visible":n},Pe.createElement("div",{className:"sonner-spinner"},Gy.map((i,l)=>Pe.createElement("div",{className:"sonner-loading-bar",key:`spinner-bar-${l}`})))),Ky=Pe.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor",height:"20",width:"20"},Pe.createElement("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z",clipRule:"evenodd"})),Qy=Pe.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24 Line truncated
* @license lucide-react v0.562.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const y_=n=>n.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),__=n=>n.replace(/^([A-Z])|[\s-_]+(\w)/g,(s,i,l)=>l?l.toUpperCase():i.toLowerCase()),cm=n=>{const s=__(n);return s.charAt(0).toUpperCase()+s.slice(1)},bx=(...n)=>n.filter((s,i,l)=>!!s&&s.trim()!==""&&l.indexOf(s)===i).join(" ").trim(),w_=n=>{for(const s in n)if(s.startsWith("aria-")||s==="role"||s==="title")return!0};/**
* @license lucide-react v0.562.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/var b_={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};/**
* @license lucide-react v0.562.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const C_=D.forwardRef(({color:n="currentColor",size:s=24,strokeWidth:i=2,absoluteStrokeWidth:l,className:c="",children:u,iconNode:p,...d},g)=>D.createElement("svg",{ref:g,...b_,width:s,height:s,stroke:n,strokeWidth:l?Number(i)*24/Number(s):i,className:bx("lucide",c),...!u&&!w_(d)&&{"aria-hidden":"true"},...d},[...p.map(([m,x])=>D.createElement(m,x)),...Array.isArray(u)?u:[u]]));/**
* @license lucide-react v0.562.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const j0=(n,s)=>{const i=D.forwardRef(({className:l,...c},u)=>D.createElement(C_,{ref:u,iconNode:s,className:bx(`lucide-${y_(cm(n))}`,`lucide-${n}`,l),...c}));return i.displayName=cm(n),i};/**
* @license lucide-react v0.562.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const E_=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],k_=j0("check",E_);/**
* @license lucide-react v0.562.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const S_=[["path",{d:"M4 5h16",key:"1tepv9"}],["path",{d:"M4 12h16",key:"1lakjw"}],["path",{d:"M4 19h16",key:"1djgab"}]],B_=j0("menu",S_);/**
* @license lucide-react v0.562.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const P_=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],Cx=j0("x",P_);function T_({health:n,config:s,onSettingsClick:i,onMenuClick:l}){const c=(n==null?void 0:n.radio_connected)??!1,[u,p]=D.useState(!1),d=async()=>{p(!0);try{const g=await tt.reconnectRadio();g.connected&&xt.success("Reconnected",{description:g.message})}catch(g){xt.error("Reconnection failed",{description:g instanceof Error?g.message:"Check radio connection and power"})}finally{p(!1)}};return _.jsxs("div",{className:"flex items-center gap-4 px-4 py-2 bg-[#252525] border-b border-[#333] text-xs",children:[l&&_.jsx("button",{onClick:l,className:"md:hidden p-1 bg-transparent border-none text-[#e0e0e0] cursor-pointer","aria-label":"Open menu",children:_.jsx(B_,{className:"h-5 w-5"})}),_.jsx("h1",{className:"text-base font-semibold mr-auto",children:"RemoteTerm"}),_.jsxs("div",{className:"flex items-center gap-1 text-[#888]",children:[_.jsx("div",{className:`w-2 h-2 rounded-full ${c?"bg-[#4caf50]":"bg-[#666]"}`}),_.jsx("span",{className:"hidden lg:inline text-[#e0e0e0]",children:c?"Connected":"Disconnected"})]}),s&&_.jsxs("div",{className:"hidden lg:flex items-center gap-2 text-[#888]",children:[_.jsx("span",{className:"text-[#e0e0e0]",children:s.name||"Unnamed"}),_.jsx("span",{className:"font-mono text-[#888] cursor-pointer hover:text-[#4a9eff]",onClick:()=>{navigator.clipboard.writeText(s.public_key),xt.success("Public key copied!")},title:"Click to copy public key",children:s.public_key.toLowerCase()})]}),!c&&_.jsx("button",{onClick:d,disabled:u,className:"px-3 py-1 bg-[#4a3000] border border-[#6b4500] text-[#ffa500] rounded text-xs cursor-pointer hover:bg-[#5a3a00] disabled:opacity-50 disabled:cursor-not-allowed",children:u?"Reconnecting...":"Reconnect"}),_.jsxs("button",{onClick:i,className:"px-3 py-1 bg-[#333] border border-[#444] text-[#e0e0e0] rounded text-xs cursor-pointer hover:bg-[#444]",children:[_.jsx("span",{role:"img","aria-label":"Settings",children:"🔧"})," ","Radio & Config"]})]})}const D_=12;function R_(n){return n.slice(0,D_)}function Ri(n,s){return n||R_(s)}const na=2,N_={text:"🛜",background:"#444444",textColor:"#ffffff"};function F_(n){let s=0;for(let i=0;i<n.length;i++){const l=n.charCodeAt(i);s=(s<<5)-s+l,s=s&s}return Math.abs(s)}const L_=/[\u{1F1E0}-\u{1F1FF}]{2}|[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]|[\u{1F600}-\u{1F64F}]|[\u{1F680}-\u{1F6FF}]/u;function M_(n,s){if(!n)return s.slice(0,2).toUpperCase();const i=n.match(L_);if(i)return i[0];const l=n.match(/[a-zA-Z]/g);if(!l||l.length===0)return s.slice(0,2).toUpperCase();const c=n.indexOf(" ");if(c!==-1){const u=l[0],p=n.slice(c+1).match(/[a-zA-Z]/);if(p)return(u+p[0]).toUpperCase()}return l[0].toUpperCase()}function I_(n){const s=F_(n),i=s%360,l=50+(s>>8)%30,c=35+(s>>16)%20,u=`hsl(${i}, ${l}%, ${c}%)`,p=c<45?"#ffffff":"#000000";return{background:u,text:p}}function O_(n,s,i){if(i===na)return N_;const l=M_(n,s),c=I_(s);return{text:l,background:c.background,textColor:c.text}}function v0({name:n,publicKey:s,size:i=28,contactType:l}){const c=O_(n,s,l);return _.jsx("div",{className:"flex items-center justify-center rounded-full font-semibold flex-shrink-0 select-none",style:{backgroundColor:c.background,color:c.textColor,width:i,height:i,fontSize:i*.45},children:c.text})}const Ex="remoteterm-favorites";function ts(n,s,i){return n.some(l=>l.type===s&&l.id===i)}function j_(){try{const n=localStorage.getItem(Ex);return n?JSON.parse(n):[]}catch{return[]}}function um(){try{localStorage.removeItem(Ex)}catch{}}function kx(n){var s,i,l="";if(typeof n=="string"||typeof n=="number")l+=n;else if(typeof n=="object")if(Array.isArray(n)){var c=n.length;for(s=0;s<c;s++)n[s]&&(i=kx(n[s]))&&(l&&(l+=" "),l+=i)}else for(i in n)n[i]&&(l&&(l+=" "),l+=i);return l}function Sx(){for(var n,s,i=0,l="",c=arguments.length;i<c;i++)(n=arguments[i])&&(s=kx(n))&&(l&&(l+=" "),l+=s);return l}const z_=(n,s)=>{const i=new Array(n.length+s.length);for(let l=0;l<n.length;l++)i[l]=n[l];for(let l=0;l<s.length;l++)i[n.length+l]=s[l];return i},H_=(n,s)=>({classGroupId:n,validator:s}),Bx=(n=new Map,s=null,i)=>({nextPart:n,validators:s,classGroupId:i}),Ku="-",dm=[],V_="arbitrary..",U_=n=>{const s=W_(n),{conflictingClassGroups:i,conflictingClassGroupModifiers:l}=n;return{getClassGroupId:p=>{if(p.startsWith("[")&&p.endsWith("]"))return Z_(p);const d=p.split(Ku),g=d[0]===""&&d.length>1?1:0;return Px(d,g,s)},getConflictingClassGroupIds:(p,d)=>{if(d){const g=l[p],m=i[p];return g?m?z_(m,g):g:m||dm}return i[p]||dm}}},Px=(n,s,i)=>{if(n.length-s===0)return i.classGroupId;const c=n[s],u=i.nextPart.get(c);if(u){const m=Px(n,s+1,u);if(m)return m}const p=i.validators;if(p===null)return;const d=s===0?n.join(Ku):n.slice(s).join(Ku),g=p.length;for(let m=0;m<g;m++){const x=p[m];if(x.validator(d))return x.classGroupId}},Z_=n=>n.slice(1,-1).indexOf(":")===-1?void 0:(()=>{const s=n.slice(1,-1),i=s.indexOf(":"),l=s.slice(0,i);return l?V_+l:void 0})(),W_=n=>{const{theme:s,classLine truncated
.`.concat(Sw,` {
overflow: hidden `).concat(l,`;
padding-right: `).concat(d,"px ").concat(l,`;
}
body[`).concat(ea,`] {
overflow: hidden `).concat(l,`;
overscroll-behavior: contain;
`).concat([s&&"position: relative ".concat(l,";"),i==="margin"&&`
padding-left: `.concat(c,`px;
padding-top: `).concat(u,`px;
padding-right: `).concat(p,`px;
margin-left:0;
margin-top:0;
margin-right: `).concat(d,"px ").concat(l,`;
`),i==="padding"&&"padding-right: ".concat(d,"px ").concat(l,";")].filter(Boolean).join(""),`
}
.`).concat(ou,` {
right: `).concat(d,"px ").concat(l,`;
}
.`).concat(su,` {
margin-right: `).concat(d,"px ").concat(l,`;
}
.`).concat(ou," .").concat(ou,` {
right: 0 `).concat(l,`;
}
.`).concat(su," .").concat(su,` {
margin-right: 0 `).concat(l,`;
}
body[`).concat(ea,`] {
`).concat(Bw,": ").concat(d,`px;
}
`)},Bm=function(){var n=parseInt(document.body.getAttribute(ea)||"0",10);return isFinite(n)?n:0},Gw=function(){D.useEffect(function(){return document.body.setAttribute(ea,(Bm()+1).toString()),function(){var n=Bm()-1;n<=0?document.body.removeAttribute(ea):document.body.setAttribute(ea,n.toString())}},[])},$w=function(n){var s=n.noRelative,i=n.noImportant,l=n.gapMode,c=l===void 0?"margin":l;Gw();var u=D.useMemo(function(){return Zw(c)},[c]);return D.createElement(Ww,{styles:qw(u,!s,c,i?"":"!important")})},w0=!1;if(typeof window<"u")try{var Qc=Object.defineProperty({},"passive",{get:function(){return w0=!0,!0}});window.addEventListener("test",Qc,Qc),window.removeEventListener("test",Qc,Qc)}catch{w0=!1}var Qs=w0?{passive:!1}:!1,Kw=function(n){return n.tagName==="TEXTAREA"},Yx=function(n,s){if(!(n instanceof Element))return!1;var i=window.getComputedStyle(n);return i[s]!=="hidden"&&!(i.overflowY===i.overflowX&&!Kw(n)&&i[s]==="visible")},Qw=function(n){return Yx(n,"overflowY")},Yw=function(n){return Yx(n,"overflowX")},Pm=function(n,s){var i=s.ownerDocument,l=s;do{typeof ShadowRoot<"u"&&l instanceof ShadowRoot&&(l=l.host);var c=Xx(n,l);if(c){var u=Jx(n,l),p=u[1],d=u[2];if(p>d)return!0}l=l.parentNode}while(l&&l!==i.body);return!1},Xw=function(n){var s=n.scrollTop,i=n.scrollHeight,l=n.clientHeight;return[s,i,l]},Jw=function(n){var s=n.scrollLeft,i=n.scrollWidth,l=n.clientWidth;return[s,i,l]},Xx=function(n,s){return n==="v"?Qw(s):Yw(s)},Jx=function(n,s){return n==="v"?Xw(s):Jw(s)},eb=function(n,s){return n==="h"&&s==="rtl"?-1:1},tb=function(n,s,i,l,c){var u=eb(n,window.getComputedStyle(s).direction),p=u*l,d=i.target,g=s.contains(d),m=!1,x=p>0,A=0,b=0;do{if(!d)break;var k=Jx(n,d),N=k[0],C=k[1],w=k[2],B=C-w-u*N;(N||B)&&Xx(n,d)&&(A+=B,b+=N);var S=d.parentNode;d=S&&S.nodeType===Node.DOCUMENT_FRAGMENT_NODE?S.host:S}while(!g&&d!==document.body||g&&(s.contains(d)||s===d));return(x&&Math.abs(A)<1||!x&&Math.abs(b)<1)&&(m=!0),m},Yc=function(n){return"changedTouches"in n?[n.changedTouches[0].clientX,n.changedTouches[0].clientY]:[0,0]},Tm=function(n){return[n.deltaX,n.deltaY]},Dm=function(n){return n&&"current"in n?n.current:n},nb=function(n,s){return n[0]===s[0]&&n[1]===s[1]},rb=function(n){return`
.block-interactivity-`.concat(n,` {pointer-events: none;}
.allow-interactivity-`).concat(n,` {pointer-events: all;}
`)},ib=0,Ys=[];function ob(n){var s=D.useRef([]),i=D.useRef([0,0]),l=D.useRef(),c=D.useState(ib++)[0],u=D.useState(Qx)[0],p=D.useRef(n);D.useEffect(function(){p.current=n},[n]),D.useEffect(function(){if(n.inert){document.body.classList.add("block-interactivity-".concat(c));var C=kw([n.lockRef.current],(n.shards||[]).map(Dm),!0).filter(Boolean);return C.forEach(function(w){return w.classList.add("allow-interactivity-".concat(c))}),function(){document.body.classList.remove("block-interactivity-".concat(c)),C.forEach(function(w){return w.classList.remove("allow-interactivity-".concat(c))})}}},[n.inert,n.lockRef.current,n.shards]);var d=D.useCallback(function(C,w){if("touches"in C&&C.touches.length===2||C.type==="wheel"&&C.ctrlKey)return!p.current.allowPinchZoom;var B=Yc(C),S=i.current,R="deltaX"in C?C.deltaX:S[0]-B[0],F="deltaY"in C?C.deltaY:S[1]-B[1],M,H=C.target,U=Math.abs(R)>Math.abs(F)?"h":"v";if("touches"in C&&U==="h"&&H.type==="range")return!1;var j=window.getSelection(),ee=j&&j.anchorNode,Z=ee?ee===H||ee.contains(H):!1;if(Z)return!1;var Y=Pm(U,H);if(!Y)return!0;if(Y?M=U:(M=U==="v"?"h":"v",Y=Pm(U,H)),!Y)return!1;if(!l.current&&"changedTouches"in C&&(R||F)&&(l.current=M),!M)return!0;var ne=l.current||M;return tb(ne,w,C,ne==="h"?R:F)},[]),g=D.useCallback(function(C){var w=C;if(!(!Ys.length||Ys[Ys.length-1]!==u)){var B="deltaY"in w?Tm(w):Yc(w),S=s.current.filter(function(M){return M.name===w.type&&(M.target===w.target||w.target===M.shadowParent)&&nb(M.delta,B)})[0];if(S&&S.should){w.cancelable&&w.preventDefault();return}if(!S){var R=(p.current.shards||[]).map(Dm).filter(Boolean).filter(function(M){return M.contains(w.target)}),F=R.length>0?d(w,R[0]):!p.current.noIsolation;F&&w.cancelable&&w.preventDefault()}}},[]),m=D.useCallback(function(C,w,B,S){var R={name:C,delta:w,target:B,should:S,shadowParent:sb(B)};s.current.push(R),setTimeout(function(){s.current=s.current.filter(function(F){return F!==R})},1)},[]),x=D.useCallback(function(C){i.current=Yc(C),l.current=void 0},[]),A=D.useCallback(function(C){m(C.type,Tm(C),C.target,d(C,n.lockRef.current))},[]),b=D.useCallback(function(C){m(C.type,Yc(C),C.target,d(C,n.lockRef.current))},[]);D.useEffect(function(){return Ys.push(u),n.setCallbacks({onScrollCapture:A,onWheelCapture:A,onTouchMoveCapture:b}),document.addEventListener("wheel",g,Qs),document.addEventListener("touchmove",g,Qs),document.addEventListener("touchstart",x,Qs),function(){Ys=Ys.filter(function(C){return C!==u}),document.removeEventListener("wheel",g,Qs),document.removeEventListener("touchmove",g,Qs),document.removeEventListener("touchstart",x,Qs)}},[]);var k=n.removeScrollBar,N=n.inert;return D.createElement(D.Fragment,null,N?D.createElement(u,{styles:rb(c)}):null,k?D.createElement($w,{noRelative:n.noRelative,gapMode:n.gapMode}):null)}function sb(n){for(var s=null;n!==null;)n instanceof ShadowRoot&&(s=n.host,n=n.host),n=n.parentNode;return s}const ab=Lw(Kx,ob);var eA=D.forwardRef(function(n,s){return D.createElement(sd,ri({},n,{ref:s,sideCar:ab}))});eA.classNames=sd.classNames;var lb=function(n){if(typeof document>"u")return null;var s=Array.isArray(n)?n[0]:n;return s.ownerDocument.body},Xs=new WeakMap,Xc=new WeakMap,Jc={},u0=0,tA=function(n){return n&&(n.host||tA(n.parentNode))},cb=function(n,s){return s.map(function(i){if(n.contains(i))return i;var l=tA(i);return l&&n.contains(l)?l:(console.error("aria-hidden",i,"in not contained inside",n,". Doing nothing"),null)}).filter(function(i){return!!i})},ub=function(n,s,i,l){var c=cb(s,Array.isArray(n)?n:[n]);Jc[i]||(Jc[i]=new WeakMap);var u=Jc[i],p=[],d=new Set,g=new Set(c),m=function(A){!A||d.has(A)||(d.add(A),m(A.parentNode))};c.forEach(m);var x=function(A){!A||g.has(A)||Array.prototype.forEach.call(A.children,function(b){if(d.has(b))x(b);else try{var k=b.getAttribute(l),N=k!==null&&k!=="false",C=(Xs.get(b)||0)+1,w=(u.get(b)||0)+1;Xs.set(b,C),u.set(b,w),p.push(b),C===1&&N&&Xc.set(b,!0),w===1&&b.setAttribute(i,"true"),N||b.setAttribute(l,"true")}catch(B){console.error("aria-hidden: cannot operate on ",b,B)}})};return x(s),d.clear(),u0++,function(){p.forEach(function(A){var b=Xs.get(A)-1,k=u.get(A)-1;Xs.set(A,b),u.set(A,k),b||(Xc.has(A)||A.removeAttribute(l),Xc.delete(A)),k||A.removeAttribute(i)}),u0--,u0||(Xs=new WeakMap,Xs=new WeakMap,Xc=new WeakMap,Jc={})}},db=function(n,s,i){i===void 0&&(i="data-aria-hidden");var l=Array.from(Array.isArray(n)?n:[n]),c=lb(n);return c?(l.push.apply(l,Array.from(c.querySelectorAll("[aria-live], script"))),ub(l,c,i,"aria-hidden")):function(){return null}};function fb(n){const s=hb(n),i=D.forwardRef((l,c)=>{const{children:u,...p}=l,d=D.Children.toArray(u),g=d.find(mb);if(g){const m=g.props.children,x=d.map(A=>A===g?D.Children.count(m)>1?D.Children.only(null):D.isValidElement(m)?m.props.children:null:A);return _.jsx(s,{...p,ref:c,children:D.isValidElement(m)?D.cloneElement(m,void 0,x):null})}return _.jsx(s,{...p,ref:c,children:u})});return i.displayName=`${n}.Slot`,i}function hb(n){const s=D.forwardRef((i,l)=>{const{chi Line truncated
If you want to hide the \`${s.titleName}\`, you can wrap it with our VisuallyHidden component.
For more information, see https://radix-ui.com/primitives/docs/components/${s.docsSlug}`;return D.useEffect(()=>{n&&(document.getElementById(n)||console.error(i))},[i,n]),null},kb="DialogDescriptionWarning",Sb=({contentRef:n,descriptionId:s})=>{const l=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${gA(kb).contentName}}.`;return D.useEffect(()=>{var u;const c=(u=n.current)==null?void 0:u.getAttribute("aria-describedby");s&&c&&(document.getElementById(s)||console.warn(l))},[l,n,s]),null},xA=rA,AA=sA,ld=aA,cd=lA,ud=uA,dd=fA,vA=pA;const q0=xA,Bb=AA,yA=D.forwardRef(({className:n,...s},i)=>_.jsx(ld,{ref:i,className:dt("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",n),...s}));yA.displayName=ld.displayName;const fd=D.forwardRef(({className:n,children:s,...i},l)=>_.jsxs(Bb,{children:[_.jsx(yA,{}),_.jsxs(cd,{ref:l,className:dt("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",n),...i,children:[s,_.jsxs(vA,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",children:[_.jsx(Cx,{className:"h-4 w-4"}),_.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));fd.displayName=cd.displayName;const hd=({className:n,...s})=>_.jsx("div",{className:dt("flex flex-col space-y-1.5 text-center sm:text-left",n),...s});hd.displayName="DialogHeader";const G0=({className:n,...s})=>_.jsx("div",{className:dt("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",n),...s});G0.displayName="DialogFooter";const pd=D.forwardRef(({className:n,...s},i)=>_.jsx(ud,{ref:i,className:dt("text-lg font-semibold leading-none tracking-tight",n),...s}));pd.displayName=ud.displayName;const md=D.forwardRef(({className:n,...s},i)=>_.jsx(dd,{ref:i,className:dt("text-sm text-muted-foreground",n),...s}));md.displayName=dd.displayName;function Rm(){const n=window.location.hash.slice(1);if(!n)return null;if(n==="raw")return{type:"raw",name:"raw"};if(n==="map")return{type:"map",name:"map"};if(n==="visualizer")return{type:"visualizer",name:"visualizer"};if(n.startsWith("map/focus/")){const c=n.slice(10);return c?{type:"map",name:"map",mapFocusKey:decodeURIComponent(c)}:{type:"map",name:"map"}}const s=n.indexOf("/");if(s===-1)return null;const i=n.slice(0,s),l=decodeURIComponent(n.slice(s+1));return(i==="channel"||i==="contact")&&l?{type:i,name:l}:null}function _A(n){return`#map/focus/${encodeURIComponent(n)}`}function Pb(n){if(!n)return"";if(n.type==="raw")return"#raw";if(n.type==="map")return"#map";if(n.type==="visualizer")return"#visualizer";const s=n.type==="channel"&&n.name.startsWith("#")?n.name.slice(1):n.name;return`#${n.type}/${encodeURIComponent(s)}`}function Tb(n){const s=Pb(n);s!==window.location.hash&&window.history.replaceState(null,"",s||window.location.pathname)}function Db({open:n,onClose:s,paths:i,senderInfo:l,contacts:c,config:u}){const p=i.map(g=>({...g,resolved:U1(g.path,l,c,u)})),d=i.length===1;return _.jsx(q0,{open:n,onOpenChange:g=>!g&&s(),children:_.jsxs(fd,{className:"max-w-md max-h-[80vh] flex flex-col",children:[_.jsxs(hd,{children:[_.jsxs(pd,{children:["Message Path",!d&&`s (${i.length})`]}),_.jsx(md,{children:d?_.jsxs(_.Fragment,{children:["This shows ",_.jsx("em",{children:"one route"})," that this message traveled through the mesh network. Routers may be incorrectly identified due to prefix collisions between heard and non-heard router advertisements."]}):_.jsxs(_.Fragment,{children:["This message was received via ",_.jsxs("strong",{children:[i.length," different routes"]}),". Routers may be incorrectly identified due to prefix collisions."]})})]}),_.jsxs("div",{className:"flex-1 overflow-y-auto py-2 space-y-4",children:[p.map((g,m)=>_.jsxs("div",{children:[!d&&_.jsxs("div",{className:"text-xs text-muted-foreground font-medium mb-2 pb-1 border-b border-border",children:["Path ",m+1," — received ",ra(g.received_at)]}),_.jsx(Rb,{resolved:g.resolved,senderInfo:l,hideStraightLine:!d})]},m)),!d&&p.length>0&&(()=>{const g=p[0].resolved;return Bt(g.sender.lat,g.sender.lon)&&Bt(g.receiver.lat,g.receiver.lon)?_.jsxs("div",{className:"pt-3 mt-1 border-t border-border",children:[_.jsx("span",{className:"text-sm text-muted-foreground",children:"Straight-line distance: "}),_.jsx("span",{className:"text-sm font-medium",c Line truncated
`).map(($,ue,pe)=>_.jsxs("span",{children:[Lb($,d),ue<pe.length-1&&_.jsx("br",{})]},ue)),!re&&_.jsxs(_.Fragment,{children:[_.jsx("span",{className:"text-[10px] text-muted-foreground/50 ml-2",children:ra(j.sender_timestamp||j.received_at)}),!j.outgoing&&j.paths&&j.paths.length>0&&_.jsx(Mm,{paths:j.paths,variant:"inline",onClick:()=>C({paths:j.paths,senderInfo:M(j,Z,ne)})})]}),j.outgoing&&(j.acked>0?` ✓${j.acked>1?j.acked:""}`:" ?")]})]})]},j.id)})]}),b&&_.jsx("button",{onClick:S,className:"absolute bottom-4 right-4 w-10 h-10 rounded-full bg-muted hover:bg-accent border border-border flex items-center justify-center shadow-lg transition-opacity",title:"Scroll to bottom",children:_.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"text-muted-foreground",children:_.jsx("polyline",{points:"6 9 12 15 18 9"})})}),N&&_.jsx(Db,{open:!0,onClose:()=>C(null),paths:N.paths,senderInfo:N.senderInfo,contacts:s,config:g??null})]})}const Im=156,Ib=140,Ob=156,jb=120,zb=8,Hb=D.forwardRef(function({onSend:s,disabled:i,placeholder:l,isRepeaterMode:c,conversationType:u,senderName:p},d){const[g,m]=D.useState(""),[x,A]=D.useState(!1),b=D.useRef(null);D.useImperativeHandle(d,()=>({appendText:M=>{var H;m(U=>U+M),(H=b.current)==null||H.focus()}}));const k=D.useMemo(()=>{if(u==="contact")return{warningAt:Ib,dangerAt:Im,hardLimit:Im};if(u==="channel"){const M=(p==null?void 0:p.length)??10,H=Math.max(1,Ob-M-2);return{warningAt:jb,dangerAt:Math.max(1,H-zb),hardLimit:H}}return null},[u,p]),{limitState:N,warningMessage:C}=D.useMemo(()=>{if(!k)return{limitState:"normal",warningMessage:null};const M=g.length;return M>=k.hardLimit?{limitState:"error",warningMessage:"likely truncated by radio"}:M>=k.dangerAt?{limitState:"danger",warningMessage:"may impact multi-repeater hop delivery"}:M>=k.warningAt?{limitState:"warning",warningMessage:"may impact multi-repeater hop delivery"}:{limitState:"normal",warningMessage:null}},[g.length,k]),w=k?k.hardLimit-g.length:0,B=D.useCallback(async M=>{M.preventDefault();const H=g.trim();if(c){if(x||i)return;A(!0);try{await s(H),m("")}catch(U){console.error("Failed to request telemetry:",U),xt.error("Failed to request telemetry",{description:U instanceof Error?U.message:"Check radio connection"});return}finally{A(!1)}setTimeout(()=>{var U;return(U=b.current)==null?void 0:U.focus()},0)}else{if(!H||x||i)return;A(!0);try{await s(H),m("")}catch(U){console.error("Failed to send message:",U),xt.error("Failed to send message",{description:U instanceof Error?U.message:"Check radio connection"});return}finally{A(!1)}setTimeout(()=>{var U;return(U=b.current)==null?void 0:U.focus()},0)}},[g,x,i,s,c]),S=D.useCallback(M=>{M.key==="Enter"&&!M.shiftKey&&(M.preventDefault(),B(M))},[B]),R=c?!0:g.trim().length>0,F=!c&&k!==null;return _.jsxs("form",{className:"px-4 py-3 border-t border-border flex flex-col gap-1",onSubmit:B,children:[_.jsxs("div",{className:"flex gap-2",children:[_.jsx(Xt,{ref:b,type:c?"password":"text",autoComplete:c?"off":void 0,value:g,onChange:M=>m(M.target.value),onKeyDown:S,placeholder:l||(c?"Enter password for admin login...":"Type a message..."),disabled:i||x,className:"flex-1 min-w-0"}),_.jsx(Jt,{type:"submit",disabled:i||x||!R,className:"flex-shrink-0",children:x?c?"Logging in...":"Sending...":c?g.trim()?"Log in with password":"Log in as guest/use repeater ACLs":"Send"})]}),F&&_.jsxs("div",{className:"flex items-center justify-end gap-2 text-xs",children:[_.jsxs("span",{className:dt("tabular-nums",N==="error"||N==="danger"?"text-red-500 font-medium":N==="warning"?"text-yellow-500":"text-muted-foreground"),children:[g.length,"/",k.hardLimit,w<0&&` (${w})`]}),C&&_.jsxs("span",{className:dt(N==="error"?"text-red-500":"text-yellow-500"),children:["— ",C]})]})]})});function Om(n){const s=Vb(n),i=D.forwardRef((l,c)=>{const{children:u,...p}=l,d=D.Children.toArray(u),g=d.find(Zb);if(g){const m=g.props.children,x=d.map(A=>A===g?D.Children.count(m)>1?D.Children.only(null):D.isValidElement(m)?m.props.children:null:A);return _.jsx(s,{...p,ref:c,children:D.isValidElement(m)?D.cloneElement(m,void 0,x):null})}return _.jsx(s,{...p,ref:c,children:u})});return i.displayName=`${n}.Slot`,i}function Vb(n){const s=D.forwardRef((i,l)=>{const{children:c,...u}=i;if(D.isValidElement(c)){const p=qb(c),d=Wb(u,c.props);return c.type!==D.Fragment&&(d.ref=l?El(l,p):p),D.cloneElement(c,d)}return D.Children.count(c)>1?D.Children.only(null):null});return s.displayName=`${n}.SlotClone`,s}var Ub=Symbol("radix.slottable");function Zb(n){return D.isValidElement(n)&&typeof n.type=="function"&&"__radixId"in n.type&&n.type.__radixId===Ub}function Wb(n,s){const i={...s};for(const l in s){const c=n[l],u=s[l];/^on[A-Z]/.test(l)?c&&u?i[l]=(...d)=>{const g=u(...d);return c(...d),g}:c&&(i[l]=c):l==="style"?i[l]={...c,...u}:l==="className"&&(i[l]=[c,u].filter(Boolean).join(" "))}return{...n,...i}}functio Line truncated
sender_name: str | None,
sender_key: str | None,
message_text: str,
is_dm: bool,
channel_key: str | None,
channel_name: str | None,
sender_timestamp: int | None,
path: str | None,
) -> str | list[str] | None:
"""
Process incoming messages and optionally return a reply.
Args:
sender_name: Display name of sender (may be None)
sender_key: 64-char hex public key (None for channel msgs)
message_text: The message content
is_dm: True for direct messages, False for channel
channel_key: 32-char hex key for channels, None for DMs
channel_name: Channel name with hash (e.g. "#bot"), None for DMs
sender_timestamp: Sender's timestamp (unix seconds, may be None)
path: Hex-encoded routing path (may be None)
Returns:
None for no reply, a string for a single reply,
or a list of strings to send multiple messages in order
"""
# Example: Only respond in #bot channel to "!pling" command
if channel_name == "#bot" and "!pling" in message_text.lower():
return "[BOT] Plong!"
return None`,[et,st]=D.useState([]),[Ge,$e]=D.useState(null),[Ye,Me]=D.useState(null),[wt,It]=D.useState("");D.useEffect(()=>{s&&(C(s.name),B(String(s.lat)),R(String(s.lon)),M(String(s.tx_power)),U(String(s.radio.freq)),ee(String(s.radio.bw)),Y(String(s.radio.sf)),K(String(s.radio.cr)))},[s]),D.useEffect(()=>{l&&(se(String(l.max_radio_contacts)),Ee(l.auto_decrypt_dm_on_advert),ot(String(l.advert_interval)),st(l.bots||[]))},[l]),D.useEffect(()=>{n&&A()},[n,A]);const Nn=D.useMemo(()=>{const oe=parseFloat(H),Te=parseFloat(j),pt=parseInt(Z,10),Ft=parseInt(ne,10);for(const nn of f0)if(nn.freq===oe&&nn.bw===Te&&nn.sf===pt&&nn.cr===Ft)return nn.name;return"custom"},[H,j,Z,ne]),Ot=oe=>{if(oe==="custom")return;const Te=f0.find(pt=>pt.name===oe);Te&&(U(String(Te.freq)),ee(String(Te.bw)),Y(String(Te.sf)),K(String(Te.cr)))},en=()=>{if(!navigator.geolocation){xt.error("Geolocation not supported",{description:"Your browser does not support geolocation"});return}ue(!0),navigator.geolocation.getCurrentPosition(oe=>{B(oe.coords.latitude.toFixed(6)),R(oe.coords.longitude.toFixed(6)),ue(!1),xt.success("Location updated")},oe=>{ue(!1),xt.error("Failed to get location",{description:oe.message})},{enableHighAccuracy:!0,timeout:1e4})},sn=async()=>{Ae(""),re(!0);try{const oe={lat:parseFloat(w),lon:parseFloat(S),tx_power:parseInt(F,10),radio:{freq:parseFloat(H),bw:parseFloat(j),sf:parseInt(Z,10),cr:parseInt(ne,10)}};await u(oe),xt.success("Radio config saved, rebooting..."),re(!1),T(!0),await g(),c()}catch(oe){Ae(oe instanceof Error?oe.message:"Failed to save"),re(!1)}finally{T(!1)}},yn=async()=>{Ae(""),re(!0);try{await u({name:N});const Te=parseInt(Ue,10);!isNaN(Te)&&Te!==(l==null?void 0:l.advert_interval)&&await p({advert_interval:Te}),xt.success("Identity settings saved")}catch(oe){Ae(oe instanceof Error?oe.message:"Failed to save")}finally{re(!1)}},Ht=async()=>{Ae(""),re(!0);try{const oe=parseInt(G,10);!isNaN(oe)&&oe!==(l==null?void 0:l.max_radio_contacts)&&await p({max_radio_contacts:oe}),xt.success("Serial settings saved")}catch(oe){Ae(oe instanceof Error?oe.message:"Failed to save")}finally{re(!1)}},Pt=async()=>{if(!ae.trim()){Ae("Private key is required");return}Ae(""),re(!0);try{await d(ae.trim()),xe(""),xt.success("Private key set, rebooting..."),re(!1),T(!0),await g(),c()}catch(oe){Ae(oe instanceof Error?oe.message:"Failed to set private key"),re(!1)}finally{T(!1)}},Vt=async()=>{if(confirm("Are you sure you want to reboot the radio? The connection will drop temporarily.")){Ae(""),T(!0);try{await g(),c()}catch(oe){Ae(oe instanceof Error?oe.message:"Failed to reboot radio")}finally{T(!1)}}},Fn=async()=>{q(!0);try{await m()}finally{q(!1)}},pn=async()=>{const oe=parseInt(me,10);if(isNaN(oe)||oe<1){xt.error("Invalid retention days",{description:"Retention days must be at least 1"});return}We(!0);try{const Te=await tt.runMaintenance(oe);xt.success("Database cleanup complete",{description:`Deleted ${Te.packets_deleted} old packet${Te.packets_deleted===1?"":"s"}`}),await x()}catch(Te){console.error("Failed to run maintenance:",Te),xt.error("Database cleanup failed",{description:Te instanceof Error?Te.message:"Unknown error"})}finally{We(!1)}},ye=async()=>{re(!0),Ae("");try{await p({auto_decrypt_dm_on_advert:Ke}),xt.success("Database settings saved")}catch(oe){console.error("Failed to save database settings:",oe),Ae(oe instanceof Error?oe.message:"Failed to save"),xt.error("Failed to save settings")}finally{re(!1)}},ke=async()=>{re(!0),Ae("");try{await p({bots:et}),xt.success("Bot settings saved")}catch(oe){console.error("Failed to save bot settings:",oe);const Te=oe instanceof Error?oe.message:"Failed to save";Ae(Te),xt.error(Te)}finally{re(!1)}},Fe=()=>{const oe={id:crypto.randomUUID(),name:`Bot ${et.length+1}`,enabled:!1,code:ht};st([...et,oe]),$e(oe.id)},lt=oe=>{const Te=et.find(pt=>pt.id===oe);Te&&Te.code.trim()&&Te.code!==ht&&!confirm(`Delete "${Te.name}"? This will remove all its code.`)||(st(et.filter(pt=>pt.id!==oe)),Ge===oe&&$e(null))},te=oe=>{st(et.map(Te=>Te.id===oe?{...Te,enabled:!Te.enabled}:Te))},ve=(oe,Te)=>{st(et.map(pt=>pt.id===oe?{...pt,code:Te}:pt))},_e=oe=>{Me(oe.id),It(oe.name)},Re=()=>{Ye&&wt.trim()&&st(et.map(oe=>oe.id===Ye?{...oe,name:wt.trim()}:oe)),Me(null),It("")},ct=oe=>{st(et.map(Te=>Te.id===oe?{...Te,code:ht}:Te))};return _.jsx(q0,{open:n,onOpenChange:oe=>!oe&&c(),children:_.jsxs(fd,{className:"sm:max-w-[50vw] sm:min-w-[500px] max-h-[90vh] overflow-y-auto",children:[_.jsxs(hd,{children:[_.jsx(pd,{children:"Radio & Settings"}),_.jsxs(md,{className:"sr-only",children:[b==="radio"&&"Configure radio frequency, power, and location settings",b==="identity"&&"Manage radio name, public key, private key, and advertising settings",b==="serial"&&"View serial port connection and configure contact sync",b==="database"&&"View database statistics and clean up old packets",b==="bot"&&"Configure automatic message bot with Python code"]})]}),s?_.jsxs(K0,{value:b,onValueChange:oe=>k(oe),className:"w-full",childre Line truncated
(c) 2012 by Cédric Mesnil. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/return(function(l){var c=i,u=c.lib,p=u.WordArray,d=u.Hasher,g=c.algo,m=p.create([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8,3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12,1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2,4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13]),x=p.create([5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12,6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2,15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13,8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14,12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11]),A=p.create([11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6]),b=p.create([8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]),k=p.create([0,1518500249,1859775393,2400959708,2840853838]),N=p.create([1352829926,1548603684,1836072691,2053994217,0]),C=g.RIPEMD160=d.extend({_doReset:function(){this._hash=p.create([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(H,U){for(var j=0;j<16;j++){var ee=U+j,Z=H[ee];H[ee]=(Z<<8|Z>>>24)&16711935|(Z<<24|Z>>>8)&4278255360}var Y=this._hash.words,ne=k.words,K=N.words,ae=m.words,xe=x.words,G=A.words,se=b.words,W,re,V,T,z,q,$,ue,pe,Ae;q=W=Y[0],$=re=Y[1],ue=V=Y[2],pe=T=Y[3],Ae=z=Y[4];for(var me,j=0;j<80;j+=1)me=W+H[U+ae[j]]|0,j<16?me+=w(re,V,T)+ne[0]:j<32?me+=B(re,V,T)+ne[1]:j<48?me+=S(re,V,T)+ne[2]:j<64?me+=R(re,V,T)+ne[3]:me+=F(re,V,T)+ne[4],me=me|0,me=M(me,G[j]),me=me+z|0,W=z,z=T,T=M(V,10),V=re,re=me,me=q+H[U+xe[j]]|0,j<16?me+=F($,ue,pe)+K[0]:j<32?me+=R($,ue,pe)+K[1]:j<48?me+=S($,ue,pe)+K[2]:j<64?me+=B($,ue,pe)+K[3]:me+=w($,ue,pe)+K[4],me=me|0,me=M(me,se[j]),me=me+Ae|0,q=Ae,Ae=pe,pe=M(ue,10),ue=$,$=me;me=Y[1]+V+pe|0,Y[1]=Y[2]+T+Ae|0,Y[2]=Y[3]+z+q|0,Y[3]=Y[4]+W+$|0,Y[4]=Y[0]+re+ue|0,Y[0]=me},_doFinalize:function(){var H=this._data,U=H.words,j=this._nDataBytes*8,ee=H.sigBytes*8;U[ee>>>5]|=128<<24-ee%32,U[(ee+64>>>9<<4)+14]=(j<<8|j>>>24)&16711935|(j<<24|j>>>8)&4278255360,H.sigBytes=(U.length+1)*4,this._process();for(var Z=this._hash,Y=Z.words,ne=0;ne<5;ne++){var K=Y[ne];Y[ne]=(K<<8|K>>>24)&16711935|(K<<24|K>>>8)&4278255360}return Z},clone:function(){var H=d.clone.call(this);return H._hash=this._hash.clone(),H}});function w(H,U,j){return H^U^j}function B(H,U,j){return H&U|~H&j}function S(H,U,j){return(H|~U)^j}function R(H,U,j){return H&j|U&~j}function F(H,U,j){return H^(U|~j)}function M(H,U){return H<<U|H>>>32-U}c.RIPEMD160=d._createHelper(C),c.HmacRIPEMD160=d._createHmacHelper(C)})(),i.RIPEMD160})})(_u)),_u.exports}var wu={exports:{}},J2=wu.exports,ig;function yd(){return ig||(ig=1,(function(n,s){(function(i,l){n.exports=l(vt())})(J2,function(i){(function(){var l=i,c=l.lib,u=c.Base,p=l.enc,d=p.Utf8,g=l.algo;g.HMAC=u.extend({init:function(m,x){m=this._hasher=new m.init,typeof x=="string"&&(x=d.parse(x));var A=m.blockSize,b=A*4;x.sigBytes>b&&(x=m.finalize(x)),x.clamp();for(var k=this._oKey=x.clone(),N=this._iKey=x.clone(),C=k.words,w=N.words,B=0;B<A;B++)C[B]^=1549556828,w[B]^=909522486;k.sigBytes=N.sigBytes=b,this.reset()},reset:function(){var m=this._hasher;m.reset(),m.update(this._iKey)},update:function(m){return this._hasher.update(m),this},finalize:function(m){var x=this._hasher,A=x.finalize(m);x.reset();var b=x.finalize(this._oKey.clone().concat(A));return b}})})()})})(wu)),wu.exports}var bu={exports:{}},eC=bu.exports,og;function tC(){return og||(og=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),Bl(),yd())})(eC,function(i){return(function(){var l=i,c=l.lib,u=c.Base,p=c.WordArray,d=l.algo,g=d.SHA256,m=d.HMAC,x=d.PBKDF2=u.extend({cfg:u.extend({keySize:128/32,hasher:g,iterations:25e4}),init:function(A){this.cfg=this.cfg.extend(A)},compute:function(A,b){for(var k=this.cfg,N=m.create(k.hasher,A),C=p.create(),w=p.create([1]),B=C.words,S=w.words,R=k.keySize,F=k.iterations;B.length<R;){var M=N.update(b).finalize(w);N.reset();for(var H=M.words,U=H.length,j=M,ee=1;ee<F;ee++){j=N.finalize(j),N.reset();for(var Z=j.words,Y=0;Y<U;Y++)H[Y]^=Z[Y]}C.concat(M),S[0]++}return C.sigBytes=R*4,C}});l.PBKDF2=function(A,b,k){return x.create(k).compute(A,b)}})(),i.PBKDF2})})(bu)),bu.exports}var Cu={exports:{}},nC=Cu.exports,sg;function yo(){return sg||(sg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),ev(),yd())})(nC,function(i){return(function(){var l=i,c=l.lib,u=c.Base,p=c.WordArray,d=l.algo,g=d.MD5,m=d.EvpKDF=u.extend({cfg:u.extend({keySize:128/32,hasher:g,iterations:1}),init:function(x){this.cfg=this.cfg.extend(x)},compute:function(x,A){for(var b,k=this.cfg,N=k.hasher.create(),C=p.create(),w=C.words,B=k.keySize,S=k.iterations;w.length<B;){b&&N.update(b),b=N.update(x).finalize(A),N.reset();for(var R=1;R<S;R++)b=N.finalize(b),N.reset();C.concat(b)}return C.sigBytes=B*4,C}});l.EvpKDF=function(x,A,b){return m.create(b).compute(x,A)}})(),i.EvpKDF})})(Cu)),Cu.exports}var Eu={exports:{}},rC=Eu.Line truncated
* Counter block mode compatible with Dr Brian Gladman fileenc.c
* derived from CryptoJS.mode.CTR
* Jan Hruby jhruby.web@gmail.com
*/return i.mode.CTRGladman=(function(){var l=i.lib.BlockCipherMode.extend();function c(d){if((d>>24&255)===255){var g=d>>16&255,m=d>>8&255,x=d&255;g===255?(g=0,m===255?(m=0,x===255?x=0:++x):++m):++g,d=0,d+=g<<16,d+=m<<8,d+=x}else d+=1<<24;return d}function u(d){return(d[0]=c(d[0]))===0&&(d[1]=c(d[1])),d}var p=l.Encryptor=l.extend({processBlock:function(d,g){var m=this._cipher,x=m.blockSize,A=this._iv,b=this._counter;A&&(b=this._counter=A.slice(0),this._iv=void 0),u(b);var k=b.slice(0);m.encryptBlock(k,0);for(var N=0;N<x;N++)d[g+N]^=k[N]}});return l.Decryptor=p,l})(),i.mode.CTRGladman})})(Bu)),Bu.exports}var Pu={exports:{}},uC=Pu.exports,dg;function dC(){return dg||(dg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(uC,function(i){return i.mode.OFB=(function(){var l=i.lib.BlockCipherMode.extend(),c=l.Encryptor=l.extend({processBlock:function(u,p){var d=this._cipher,g=d.blockSize,m=this._iv,x=this._keystream;m&&(x=this._keystream=m.slice(0),this._iv=void 0),d.encryptBlock(x,0);for(var A=0;A<g;A++)u[p+A]^=x[A]}});return l.Decryptor=c,l})(),i.mode.OFB})})(Pu)),Pu.exports}var Tu={exports:{}},fC=Tu.exports,fg;function hC(){return fg||(fg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(fC,function(i){return i.mode.ECB=(function(){var l=i.lib.BlockCipherMode.extend();return l.Encryptor=l.extend({processBlock:function(c,u){this._cipher.encryptBlock(c,u)}}),l.Decryptor=l.extend({processBlock:function(c,u){this._cipher.decryptBlock(c,u)}}),l})(),i.mode.ECB})})(Tu)),Tu.exports}var Du={exports:{}},pC=Du.exports,hg;function mC(){return hg||(hg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(pC,function(i){return i.pad.AnsiX923={pad:function(l,c){var u=l.sigBytes,p=c*4,d=p-u%p,g=u+d-1;l.clamp(),l.words[g>>>2]|=d<<24-g%4*8,l.sigBytes+=d},unpad:function(l){var c=l.words[l.sigBytes-1>>>2]&255;l.sigBytes-=c}},i.pad.Ansix923})})(Du)),Du.exports}var Ru={exports:{}},gC=Ru.exports,pg;function xC(){return pg||(pg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(gC,function(i){return i.pad.Iso10126={pad:function(l,c){var u=c*4,p=u-l.sigBytes%u;l.concat(i.lib.WordArray.random(p-1)).concat(i.lib.WordArray.create([p<<24],1))},unpad:function(l){var c=l.words[l.sigBytes-1>>>2]&255;l.sigBytes-=c}},i.pad.Iso10126})})(Ru)),Ru.exports}var Nu={exports:{}},AC=Nu.exports,mg;function vC(){return mg||(mg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(AC,function(i){return i.pad.Iso97971={pad:function(l,c){l.concat(i.lib.WordArray.create([2147483648],1)),i.pad.ZeroPadding.pad(l,c)},unpad:function(l){i.pad.ZeroPadding.unpad(l),l.sigBytes--}},i.pad.Iso97971})})(Nu)),Nu.exports}var Fu={exports:{}},yC=Fu.exports,gg;function _C(){return gg||(gg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(yC,function(i){return i.pad.ZeroPadding={pad:function(l,c){var u=c*4;l.clamp(),l.sigBytes+=u-(l.sigBytes%u||u)},unpad:function(l){for(var c=l.words,u=l.sigBytes-1,u=l.sigBytes-1;u>=0;u--)if(c[u>>>2]>>>24-u%4*8&255){l.sigBytes=u+1;break}}},i.pad.ZeroPadding})})(Fu)),Fu.exports}var Lu={exports:{}},wC=Lu.exports,xg;function bC(){return xg||(xg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(wC,function(i){return i.pad.NoPadding={pad:function(){},unpad:function(){}},i.pad.NoPadding})})(Lu)),Lu.exports}var Mu={exports:{}},CC=Mu.exports,Ag;function EC(){return Ag||(Ag=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(CC,function(i){return(function(l){var c=i,u=c.lib,p=u.CipherParams,d=c.enc,g=d.Hex,m=c.format;m.Hex={stringify:function(x){return x.ciphertext.toString(g)},parse:function(x){var A=g.parse(x);return p.create({ciphertext:A})}}})(),i.format.Hex})})(Mu)),Mu.exports}var Iu={exports:{}},kC=Iu.exports,vg;function SC(){return vg||(vg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),ss(),as(),yo(),vn())})(kC,function(i){return(function(){var l=i,c=l.lib,u=c.BlockCipher,p=l.algo,d=[],g=[],m=[],x=[],A=[],b=[],k=[],N=[],C=[],w=[];(function(){for(var R=[],F=0;F<256;F++)F<128?R[F]=F<<1:R[F]=F<<1^283;for(var M=0,H=0,F=0;F<256;F++){var U=H^H<<1^H<<2^H<<3^H<<4;U=U>>>8^U&255^99,d[M]=U,g[U]=M;var j=R[M],ee=R[j],Z=R[ee],Y=R[U]*257^U*16843008;m[M]=Y<<24|Y>>>8,x[M]=Y<<16|Y>>>16,A[M]=Y<<8|Y>>>24,b[M]=Y;var Y=Z*16843009^ee*65537^j*257^M*16843008;k[U]=Y<<24|Y>>>8,N[U]=Y<<16|Y>>>16,C[U]=Y<<8|Y>>>24,w[U]=Y,M?(M=j^R[R[R[Z^j]]],H^=R[R[H]]):M=H=1}})();var B=[0,1,2,4,8,16,32,64,128,27,54],S=p.AES=u.extend({_doReset:function(){var R;if(!(this._nRounds&&this._keyPriorReset===this._key)){for(var F=this._keyPriorReset=this._key,M=F.words,H=F.sigBytes/4,U=this._nRounds=H+6,j=(U+1)*4,ee=this._keySchedule=[],Z=0;Z<j;Z++)Z<H?ee[Z]=M[Z]:(R=ee[Z-1],Z%H?H>6&&Z%H==4&&(R=d[R>>>24]<<24|d[R>>>16&255]<<16|d[R>>>8&255]<<8|d[R&255]):(R=R<<8|R>>>24,R=d[R>>>24]<<24|d[R>>>16&255]<<16|d[R>>>8&255]<<8|d[R&255],R^=B[Z/H|0]<<24),ee[Z]=ee[Z-H]^R);for(var Y=this._invKeySchedule=[],ne=0;ne<j;ne++){var Z=j-ne;if(ne%4)var R=ee[Z];else var R=ee[Z-4];ne<4||Z<=4?Y[ne]=R:Y[ne]=k[d[R>>>24]]^N[d[R>>>16&255]]^C[d[R>>>8&255]]^w[d[R&255]Line truncated
• Timestamp (4 bytes) - send time as unix timestamp
• Request Type (1 byte) - type of request (GetStats, GetTelemetryData, etc.)
• Request Data (remaining bytes) - additional request-specific data`,startByte:d+g,endByte:d+c.length-1,value:b});const k={type:n.PayloadType.Request,version:n.PayloadVersion.Version1,isValid:!0,timestamp:0,requestType:n.RequestType.GetStats,requestData:"",destinationHash:m,sourceHash:x,cipherMac:A,ciphertext:b};return u!=null&&u.includeSegments&&(k.segments=p),k}catch(p){return{type:n.PayloadType.Request,version:n.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode request payload"],timestamp:0,requestType:n.RequestType.GetStats,requestData:"",destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:""}}}}return ll.RequestPayloadDecoder=i,ll}var cl={},Vg;function cE(){if(Vg)return cl;Vg=1,Object.defineProperty(cl,"__esModule",{value:!0}),cl.ResponsePayloadDecoder=void 0;const n=dr(),s=Cn();class i{static decode(c,u){try{if(c.length<4){const N={type:n.PayloadType.Response,version:n.PayloadVersion.Version1,isValid:!1,errors:["Response payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return u!=null&&u.includeSegments&&(N.segments=[{name:"Invalid Response Data",description:"Response payload too short (minimum 4 bytes required)",startByte:u.segmentOffset||0,endByte:(u.segmentOffset||0)+c.length-1,value:(0,s.bytesToHex)(c)}]),N}const p=[],d=(u==null?void 0:u.segmentOffset)||0;let g=0;const m=(0,s.byteToHex)(c[g]);u!=null&&u.includeSegments&&p.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:d+g,endByte:d+g,value:m}),g+=1;const x=(0,s.byteToHex)(c[g]);u!=null&&u.includeSegments&&p.push({name:"Source Hash",description:"First byte of source node public key",startByte:d+g,endByte:d+g,value:x}),g+=1;const A=(0,s.bytesToHex)(c.subarray(g,g+2));u!=null&&u.includeSegments&&p.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:d+g,endByte:d+g+1,value:A}),g+=2;const b=(0,s.bytesToHex)(c.subarray(g));u!=null&&u.includeSegments&&c.length>g&&p.push({name:"Ciphertext",description:"Encrypted response data (tag + content)",startByte:d+g,endByte:d+c.length-1,value:b});const k={type:n.PayloadType.Response,version:n.PayloadVersion.Version1,isValid:!0,destinationHash:m,sourceHash:x,cipherMac:A,ciphertext:b,ciphertextLength:c.length-4};return u!=null&&u.includeSegments&&(k.segments=p),k}catch(p){return{type:n.PayloadType.Response,version:n.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode response payload"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return cl.ResponsePayloadDecoder=i,cl}var ul={},Ug;function uE(){if(Ug)return ul;Ug=1,Object.defineProperty(ul,"__esModule",{value:!0}),ul.AnonRequestPayloadDecoder=void 0;const n=dr(),s=Cn();class i{static decode(c,u){try{if(c.length<35){const N={type:n.PayloadType.AnonRequest,version:n.PayloadVersion.Version1,isValid:!1,errors:["AnonRequest payload too short (minimum 35 bytes: dest + public key + MAC)"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return u!=null&&u.includeSegments&&(N.segments=[{name:"Invalid AnonRequest Data",description:"AnonRequest payload too short (minimum 35 bytes required: 1 for dest hash + 32 for public key + 2 for MAC)",startByte:u.segmentOffset||0,endByte:(u.segmentOffset||0)+c.length-1,value:(0,s.bytesToHex)(c)}]),N}const p=[],d=(u==null?void 0:u.segmentOffset)||0;let g=0;const m=(0,s.byteToHex)(c[0]);u!=null&&u.includeSegments&&p.push({name:"Destination Hash",description:`First byte of destination node public key: 0x${m}`,startByte:d+g,endByte:d+g,value:m}),g+=1;const x=(0,s.bytesToHex)(c.subarray(1,33));u!=null&&u.includeSegments&&p.push({name:"Sender Public Key",description:"Ed25519 public key of the sender (32 bytes)",startByte:d+g,endByte:d+g+31,value:x}),g+=32;const A=(0,s.bytesToHex)(c.subarray(33,35));u!=null&&u.includeSegments&&p.push({name:"Cipher MAC",description:"MAC for encrypted data verification (2 bytes)",startByte:d+g,endByte:d+g+1,value:A}),g+=2;const b=(0,s.bytesToHex)(c.subarray(35));u!=null&&u.includeSegments&&c.length>35&&p.push({name:"Ciphertext",description:`Encrypted message data (${c.length-35} bytes). Contains encrypted plaintext with this structure:
• Timestamp (4 bytes) - send time as unix timestamp
• Sync Timestamp (4 bytes) - room server only, sender's "sync messages SINCE x" timestamp
• Password (remaining bytes) - password for repeater/room`,startByte:d+g,endByte:d+c.length-1,value:b});const k={type:n.PayloadType.AnonRequest,version:n.PayloadVersion.Version1,isValid:!0,destinationHash:m,senderPublicKey:x,cipherMac:A,ciphertext:b,ciphertextLength:c.length-35};return u!=null&&u.includeSegments&&(k.segments=p),k}catch(p){return{type:n.PayloadType.AnonRequest,version:n.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode AnonRequest payload"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return ul.AnonRequestPayloadDecoder=i,ul}var dl={},Zg;function dE(){if(Zg)return dl;Zg=1,Object.defineProperty(dl,"__esModule",{value:!0}),dl.AckPayloadDecoder=void 0;const n=dr(),s=Cn();class i{static decode(c,u){try{if(c.length<4){const x={type:n.PayloadType.Ack,version:n.PayloadVersion.Version1,isValid:!1,errors:["Ack payload too short (minimum 4 bytes for checksum)"],checksum:""};return u!=null&&u.includeSegments&&(x.segments=[{name:"Invalid Ack Data",description:"Ack payload too short (minimum 4 bytes required for checksum)",startByte:u.segmentOffset||0,endByte:(u.segmentOffset||0)+c.length-1,value:(0,s.bytesToHex)(c)}]),x}const p=[],d=(u==null?void 0:u.segmentOffset)||0,g=(0,s.bytesToHex)(c.subarray(0,4));u!=null&&u.includeSegments&&p.push({name:"Checksum",description:`CRC checksum of message timestamp, text, and sender pubkey: 0x${g}`,startByte:d,endByte:d+3,value:g}),u!=null&&u.includeSegments&&c.length>4&&p.push({name:"Additional Data",description:"Extra data in Ack payload",startByte:d+4,endByte:d+c.length-1,value:(0,s.bytesToHex)(c.subarray(4))});const m={type:n.PayloadType.Ack,version:n.PayloadVersion.Version1,isValid:!0,checksum:g};return u!=null&&u.includeSegments&&(m.segments=p),m}catch(p){return{type:n.PayloadType.Ack,version:n.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode Ack payload"],checksum:""}}}}return dl.AckPayloadDecoder=i,dl}var fl={},Wg;function fE(){if(Wg)return fl;Wg=1,Object.defineProperty(fl,"__esModule",{value:!0}),fl.PathPayloadDecoder=void 0;const n=dr(),s=Cn();class i{static decode(c){try{if(c.length<2)return{type:n.PayloadType.Path,version:n.PayloadVersion.Version1,isValid:!1,errors:["Path payload too short (minimum 2 bytes: path length + extra type)"],pathLength:0,pathHashes:[],extraType:0,extraData:""};const u=c[0];if(c.length<1+u+1)return{type:n.PayloadType.Path,version:n.PayloadVersion.Version1,isValid:!1,errors:[`Path payload too short (need ${1+u+1} bytes for path length + path + extra type)`],pathLength:u,pathHashes:[],extraType:0,extraData:""};const p=[];for(let m=0;m<u;m++)p.push((0,s.byteToHex)(c[1+m]));const d=c[1+u];let g="";return c.length>1+u+1&&(g=(0,s.bytesToHex)(c.subarray(1+u+1))),{type:n.PayloadType.Path,version:n.PayloadVersion.Version1,isValid:!0,pathLength:u,pathHashes:p,extraType:d,extraData:g}}catch(u){return{type:n.PayloadType.Path,version:n.PayloadVersion.Version1,isValid:!1,errors:[u instanceof Error?u.message:"Failed to decode Path payload"],pathLength:0,pathHashes:[],extraType:0,extraData:""}}}}return fl.PathPayloadDecoder=i,fl}var hl={},qg;function hE(){if(qg)return hl;qg=1,Object.defineProperty(hl,"__esModule",{value:!0}),hl.TextMessagePayloadDecoder=void 0;const n=dr(),s=Cn();class i{static decode(c,u){try{if(c.length<4){const N={type:n.PayloadType.TextMessage,version:n.PayloadVersion.Version1,isValid:!1,errors:["TextMessage payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return u!=null&&u.includeSegments&&(N.segments=[{name:"Invalid TextMessage Data",description:"TextMessage payload too short (minimum 4 bytes required)",startByte:u.segmentOffset||0,endByte:(u.segmentOffset||0)+c.length-1,value:(0,s.bytesToHex)(c)}]),N}const p=[],d=(u==null?void 0:u.segmentOffset)||0;let g=0;const m=(0,s.byteToHex)(c[g]);u!=null&&u.includeSegments&&p.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:d+g,endByte:d+g,value:m}),g+=1;const x=(0,s.byteToHex)(c[g]);u!=null&&u.includeSegments&&p.push({name:"Source Hash",description:"First byte of source node public key",startByte:d+g,endByte:d+g,value:x}),g+=1;const A=(0,s.bytesToHex)(c.subarray(g,g+2));u!=null&&u.includeSegments&&p.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:d+g,endByte:d+g+1,value:A}),g+=2;const b=(0,s.bytesToHex)(c.subarray(g));u!=null&&u.includeSegments&&c.length>g&&p.push({name:"Ciphertext",description:"Encrypted message data (timestamp + message text)",startByte:d+g,endByte:d+c.length-1,value:b});const k={type:n.PayloadType.TextMessage,version:n.PayloadVersion.Version1,isValid:!0,destinationHash:m,sourceHash:x,cipherMac:A,ciphertext:b,ciphertextLength:c.length-4};return u!=null&&u.includeSegments&&(k.segments=p),k}catch(p){return{type:n.PayloadType.TextMessage,version:n.PayloadVersion.Version1,i Line truncated
* Leaflet 1.9.4, a JS library for interactive maps. https://leafletjs.com
* (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade
*/var PE=gl.exports,Jg;function TE(){return Jg||(Jg=1,(function(n,s){(function(i,l){l(s)})(PE,(function(i){var l="1.9.4";function c(t){var o,f,v,P;for(f=1,v=arguments.length;f<v;f++){P=arguments[f];for(o in P)t[o]=P[o]}return t}var u=Object.create||(function(){function t(){}return function(o){return t.prototype=o,new t}})();function p(t,o){var f=Array.prototype.slice;if(t.bind)return t.bind.apply(t,f.call(arguments,1));var v=f.call(arguments,2);return function(){return t.apply(o,v.length?v.concat(f.call(arguments)):arguments)}}var d=0;function g(t){return"_leaflet_id"in t||(t._leaflet_id=++d),t._leaflet_id}function m(t,o,f){var v,P,O,X;return X=function(){v=!1,P&&(O.apply(f,P),P=!1)},O=function(){v?P=arguments:(t.apply(f,arguments),setTimeout(X,o),v=!0)},O}function x(t,o,f){var v=o[1],P=o[0],O=v-P;return t===v&&f?t:((t-P)%O+O)%O+P}function A(){return!1}function b(t,o){if(o===!1)return t;var f=Math.pow(10,o===void 0?6:o);return Math.round(t*f)/f}function k(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}function N(t){return k(t).split(/\s+/)}function C(t,o){Object.prototype.hasOwnProperty.call(t,"options")||(t.options=t.options?u(t.options):{});for(var f in o)t.options[f]=o[f];return t.options}function w(t,o,f){var v=[];for(var P in t)v.push(encodeURIComponent(f?P.toUpperCase():P)+"="+encodeURIComponent(t[P]));return(!o||o.indexOf("?")===-1?"?":"&")+v.join("&")}var B=/\{ *([\w_ -]+) *\}/g;function S(t,o){return t.replace(B,function(f,v){var P=o[v];if(P===void 0)throw new Error("No value provided for variable "+f);return typeof P=="function"&&(P=P(o)),P})}var R=Array.isArray||function(t){return Object.prototype.toString.call(t)==="[object Array]"};function F(t,o){for(var f=0;f<t.length;f++)if(t[f]===o)return f;return-1}var M="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";function H(t){return window["webkit"+t]||window["moz"+t]||window["ms"+t]}var U=0;function j(t){var o=+new Date,f=Math.max(0,16-(o-U));return U=o+f,window.setTimeout(t,f)}var ee=window.requestAnimationFrame||H("RequestAnimationFrame")||j,Z=window.cancelAnimationFrame||H("CancelAnimationFrame")||H("CancelRequestAnimationFrame")||function(t){window.clearTimeout(t)};function Y(t,o,f){if(f&&ee===j)t.call(o);else return ee.call(window,p(t,o))}function ne(t){t&&Z.call(window,t)}var K={__proto__:null,extend:c,create:u,bind:p,get lastId(){return d},stamp:g,throttle:m,wrapNum:x,falseFn:A,formatNum:b,trim:k,splitWords:N,setOptions:C,getParamString:w,template:S,isArray:R,indexOf:F,emptyImageUrl:M,requestFn:ee,cancelFn:Z,requestAnimFrame:Y,cancelAnimFrame:ne};function ae(){}ae.extend=function(t){var o=function(){C(this),this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()},f=o.__super__=this.prototype,v=u(f);v.constructor=o,o.prototype=v;for(var P in this)Object.prototype.hasOwnProperty.call(this,P)&&P!=="prototype"&&P!=="__super__"&&(o[P]=this[P]);return t.statics&&c(o,t.statics),t.includes&&(xe(t.includes),c.apply(null,[v].concat(t.includes))),c(v,t),delete v.statics,delete v.includes,v.options&&(v.options=f.options?u(f.options):{},c(v.options,t.options)),v._initHooks=[],v.callInitHooks=function(){if(!this._initHooksCalled){f.callInitHooks&&f.callInitHooks.call(this),this._initHooksCalled=!0;for(var O=0,X=v._initHooks.length;O<X;O++)v._initHooks[O].call(this)}},o},ae.include=function(t){var o=this.prototype.options;return c(this.prototype,t),t.options&&(this.prototype.options=o,this.mergeOptions(t.options)),this},ae.mergeOptions=function(t){return c(this.prototype.options,t),this},ae.addInitHook=function(t){var o=Array.prototype.slice.call(arguments,1),f=typeof t=="function"?t:function(){this[t].apply(this,o)};return this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(f),this};function xe(t){if(!(typeof L>"u"||!L||!L.Mixin)){t=R(t)?t:[t];for(var o=0;o<t.length;o++)t[o]===L.Mixin.Events&&console.warn("Deprecated include of L.Mixin.Events: this property will be removed in future releases, please inherit from L.Evented instead.",new Error().stack)}}var G={on:function(t,o,f){if(typeof t=="object")for(var v in t)this._on(v,t[v],o);else{t=N(t);for(var P=0,O=t.length;P<O;P++)this._on(t[P],o,f)}return this},off:function(t,o,f){if(!arguments.length)delete this._events;else if(typeof t=="object")for(var v in t)this._off(v,t[v],o);else{t=N(t);for(var P=arguments.length===1,O=0,X=t.length;O<X;O++)P?this._off(t[O]):this._off(t[O],o,f)}return this},_on:function(t,o,f,v){if(typeof o!="function"){console.warn("wrong listener type: "+typeof o);return}if(this._listens(t,o,f)===!1){f===this&&(f=void 0);var P={fn:o,ctx:f};v&&(P.once=!0),this._events=this._events||{},this._events[t]=this._events[t]||[],this._events[t].push(P)}},_off:function(t,o,f){var v,P,O;if(this._events&&(v=this._events[t],!!v)){if(arguments.length===1){if(this._firingCount)for(P=0,O=v.length;P<O;P++)v[P].fn=A;delete this._events[t];return}if(typeof o!="function"){console.warn("wrong listener type: "+typeof o);return}var X=thLine truncated
// SHA256 round constants
const K: array<u32, 64> = array<u32, 64>(
0x428a2f98u, 0x71374491u, 0xb5c0fbcfu, 0xe9b5dba5u, 0x3956c25bu, 0x59f111f1u, 0x923f82a4u, 0xab1c5ed5u,
0xd807aa98u, 0x12835b01u, 0x243185beu, 0x550c7dc3u, 0x72be5d74u, 0x80deb1feu, 0x9bdc06a7u, 0xc19bf174u,
0xe49b69c1u, 0xefbe4786u, 0x0fc19dc6u, 0x240ca1ccu, 0x2de92c6fu, 0x4a7484aau, 0x5cb0a9dcu, 0x76f988dau,
0x983e5152u, 0xa831c66du, 0xb00327c8u, 0xbf597fc7u, 0xc6e00bf3u, 0xd5a79147u, 0x06ca6351u, 0x14292967u,
0x27b70a85u, 0x2e1b2138u, 0x4d2c6dfcu, 0x53380d13u, 0x650a7354u, 0x766a0abbu, 0x81c2c92eu, 0x92722c85u,
0xa2bfe8a1u, 0xa81a664bu, 0xc24b8b70u, 0xc76c51a3u, 0xd192e819u, 0xd6990624u, 0xf40e3585u, 0x106aa070u,
0x19a4c116u, 0x1e376c08u, 0x2748774cu, 0x34b0bcb5u, 0x391c0cb3u, 0x4ed8aa4au, 0x5b9cca4fu, 0x682e6ff3u,
0x748f82eeu, 0x78a5636fu, 0x84c87814u, 0x8cc70208u, 0x90befffau, 0xa4506cebu, 0xbef9a3f7u, 0xc67178f2u
);
// Character lookup table (a-z = 0-25, 0-9 = 26-35, dash = 36)
const CHARS: array<u32, 37> = array<u32, 37>(
0x61u, 0x62u, 0x63u, 0x64u, 0x65u, 0x66u, 0x67u, 0x68u, 0x69u, 0x6au, // a-j
0x6bu, 0x6cu, 0x6du, 0x6eu, 0x6fu, 0x70u, 0x71u, 0x72u, 0x73u, 0x74u, // k-t
0x75u, 0x76u, 0x77u, 0x78u, 0x79u, 0x7au, // u-z
0x30u, 0x31u, 0x32u, 0x33u, 0x34u, 0x35u, 0x36u, 0x37u, 0x38u, 0x39u, // 0-9
0x2du // dash
);
struct Params {
target_channel_hash: u32,
batch_offset: u32,
name_length: u32,
batch_size: u32,
target_mac: u32, // First 2 bytes of target MAC (in high 16 bits)
ciphertext_words: u32, // Number of 32-bit words in ciphertext
ciphertext_len_bits: u32, // Length of ciphertext in bits
verify_mac: u32, // 1 to verify MAC, 0 to skip
}
@group(0) @binding(0) var<uniform> params: Params;
@group(0) @binding(1) var<storage, read_write> match_count: atomic<u32>;
@group(0) @binding(2) var<storage, read_write> match_indices: array<u32>;
@group(0) @binding(3) var<storage, read> ciphertext: array<u32>; // Ciphertext data
fn rotr(x: u32, n: u32) -> u32 {
return (x >> n) | (x << (32u - n));
}
fn ch(x: u32, y: u32, z: u32) -> u32 {
return (x & y) ^ (~x & z);
}
fn maj(x: u32, y: u32, z: u32) -> u32 {
return (x & y) ^ (x & z) ^ (y & z);
}
fn sigma0(x: u32) -> u32 {
return rotr(x, 2u) ^ rotr(x, 13u) ^ rotr(x, 22u);
}
fn sigma1(x: u32) -> u32 {
return rotr(x, 6u) ^ rotr(x, 11u) ^ rotr(x, 25u);
}
fn gamma0(x: u32) -> u32 {
return rotr(x, 7u) ^ rotr(x, 18u) ^ (x >> 3u);
}
fn gamma1(x: u32) -> u32 {
return rotr(x, 17u) ^ rotr(x, 19u) ^ (x >> 10u);
}
// Convert index to room name bytes, returns the hash as a u32 for the first byte check
fn index_to_room_name(idx: u32, length: u32, msg: ptr<function, array<u32, 16>>) -> bool {
// Message starts with '#' (0x23)
var byte_pos = 0u;
var word_idx = 0u;
var current_word = 0x23000000u; // '#' in big-endian position 0
byte_pos = 1u;
var remaining = idx;
var prev_was_dash = false;
// Generate room name from index
for (var i = 0u; i < length; i++) {
let char_count = select(37u, 36u, i == 0u || i == length - 1u); // no dash at start/end
var char_idx = remaining % char_count;
remaining = remaining / char_count;
// Check for consecutive dashes (invalid)
let is_dash = char_idx == 36u && i > 0u && i < length - 1u;
if (is_dash && prev_was_dash) {
return false; // Invalid: consecutive dashes
}
prev_was_dash = is_dash;
// Map char index to actual character
let c = CHARS[char_idx];
// Pack byte into current word (big-endian)
let shift = (3u - byte_pos % 4u) * 8u;
if (byte_pos % 4u == 0u && byte_pos > 0u) {
(*msg)[word_idx] = current_word;
word_idx = word_idx + 1u;
current_word = 0u;
}
current_word = current_word | (c << shift);
byte_pos = byte_pos + 1u;
}
// Add padding: 0x80 followed by zeros, then length in bits
let msg_len_bits = (length + 1u) * 8u; // +1 for '#'
// Add 0x80 padding byte
let shift = (3u - byte_pos % 4u) * 8u;
if (byte_pos % 4u == 0u) {
(*msg)[word_idx] = current_word;
word_idx = word_idx + 1u;
current_word = 0x80000000u;
} else {
current_word = current_word | (0x80u << shift);
}
byte_pos = byte_pos + 1u;
// Store current word
if (byte_pos % 4u == 0u || word_idx < 14u) {
(*msg)[word_idx] = current_word;
word_idx = word_idx + 1u;
}
// Zero-fill until word 14
for (var i = word_idx; i < 14u; i++) {
(*msg)[i] = 0u;
}
// Length in bits (64-bit, but we only use lower 32 bits for short messages)
(*msg)[14u] = 0u;
(*msg)[15u] = msg_len_bits;
return true;
}
fn sha256_block(msg: ptr<function, array<u32, 16>>) -> array<u32, 8> {
// Initialize hash values
var h: array<u32, 8> = array<u32, 8>(
0x6a09e667u, 0xbb67ae85u, 0x3c6ef372u, 0xa54ff53au,
0x510e527fu, 0x9b05688cu, 0x1f83d9abu, 0x5be0cd19u
);
// Message schedule
var w: array<u32, 64>;
for (var i = 0u; i < 16u; i++) {
w[i] = (*msg)[i];
}
for (var i = 16u; i < 64u; i++) {
w[i] = gamma1(w[i-2u]) + w[i-7u] + gamma0(w[i-15u]) + w[i-16u];
}
// Compression
var a = h[0]; var b = h[1]; var c = h[2]; var d = h[3];
var e = h[4]; var f = h[5]; var g = h[6]; var hh = h[7];
for (var i = 0u; i < 64u; i++) {
let t1 = hh + sigma1(e) + ch(e, f, g) + K[i] + w[i];
let t2 = sigma0(a) + maj(a, b, c);
hh = g; g = f; f = e; e = d + t1;
d = c; c = b; b = a; a = t1 + t2;
}
h[0] = h[0] + a; h[1] = h[1] + b; h[2] = h[2] + c; h[3] = h[3] + d;
h[4] = h[4] + e; h[5] = h[5] + f; h[6] = h[6] + g; h[7] = h[7] + hh;
return h;
}
// Compute SHA256 of the key (16 bytes) to get channel hash
fn sha256_key(key: array<u32, 4>) -> u32 {
var msg: array<u32, 16>;
// Key bytes (16 bytes = 4 words)
msg[0] = key[0];
msg[1] = key[1];
msg[2] = key[2];
msg[3] = key[3];
// Padding: 0x80 followed by zeros
msg[4] = 0x80000000u;
for (var i = 5u; i < 14u; i++) {
msg[i] = 0u;
}
// Length: 128 bits
msg[14] = 0u;
msg[15] = 128u;
let hash = sha256_block(&msg);
// Return first byte of hash (big-endian)
return hash[0] >> 24u;
}
// HMAC-SHA256 for MAC verification
// Key is 16 bytes (4 words), padded to 32 bytes with zeros for MeshCore
// Returns first 2 bytes of HMAC (as u32 in high 16 bits)
fn hmac_sha256_mac(key: array<u32, 4>, ciphertext_len: u32) -> u32 {
// HMAC: H((K' ^ opad) || H((K' ^ ipad) || message))
// K' is 64 bytes (32 bytes key + 32 bytes zero padding for MeshCore, then padded to 64)
// ipad = 0x36 repeated, opad = 0x5c repeated
// Build padded key (64 bytes = 16 words)
// MeshCore uses 32-byte secret: 16-byte key + 16 zero bytes
var k_pad: array<u32, 16>;
k_pad[0] = key[0];
k_pad[1] = key[1];
k_pad[2] = key[2];
k_pad[3] = key[3];
for (var i = 4u; i < 16u; i++) {
k_pad[i] = 0u;
}
// Inner hash: SHA256((K' ^ ipad) || message)
// First block: K' ^ ipad (64 bytes)
var inner_block: array<u32, 16>;
for (var i = 0u; i < 16u; i++) {
inner_block[i] = k_pad[i] ^ 0x36363636u;
}
// Initialize hash state with first block
var h: array<u32, 8> = sha256_block(&inner_block);
// Process ciphertext blocks (continuing from h state)
let ciphertext_words = params.ciphertext_words;
var word_idx = 0u;
// Process full 64-byte blocks of ciphertext
while (word_idx + 16u <= ciphertext_words) {
var block: array<u32, 16>;
for (var i = 0u; i < 16u; i++) {
block[i] = ciphertext[word_idx + i];
}
h = sha256_block_continue(&block, h);
word_idx = word_idx + 16u;
}
// Final block with remaining ciphertext + padding
var final_block: array<u32, 16>;
var remaining = ciphertext_words - word_idx;
for (var i = 0u; i < 16u; i++) {
if (i < remaining) {
final_block[i] = ciphertext[word_idx + i];
} else if (i == remaining) {
// Add 0x80 padding
final_block[i] = 0x80000000u;
} else {
final_block[i] = 0u;
}
}
// Add length (64 bytes of ipad + ciphertext length)
let total_bits = 512u + params.ciphertext_len_bits;
if (remaining < 14u) {
final_block[14] = 0u;
final_block[15] = total_bits;
h = sha256_block_continue(&final_block, h);
} else {
// Need extra block for length
h = sha256_block_continue(&final_block, h);
var len_block: array<u32, 16>;
for (var i = 0u; i < 14u; i++) {
len_block[i] = 0u;
}
len_block[14] = 0u;
len_block[15] = total_bits;
h = sha256_block_continue(&len_block, h);
}
let inner_hash = h;
// Outer hash: SHA256((K' ^ opad) || inner_hash)
var outer_block: array<u32, 16>;
for (var i = 0u; i < 16u; i++) {
outer_block[i] = k_pad[i] ^ 0x5c5c5c5cu;
}
h = sha256_block(&outer_block);
// Second block: inner_hash (32 bytes) + padding
var hash_block: array<u32, 16>;
for (var i = 0u; i < 8u; i++) {
hash_block[i] = inner_hash[i];
}
hash_block[8] = 0x80000000u;
for (var i = 9u; i < 14u; i++) {
hash_block[i] = 0u;
}
hash_block[14] = 0u;
hash_block[15] = 512u + 256u; // 64 bytes opad + 32 bytes inner hash
h = sha256_block_continue(&hash_block, h);
// Return first 2 bytes (high 16 bits of first word)
return h[0] & 0xFFFF0000u;
}
// SHA256 block computation continuing from existing state
fn sha256_block_continue(msg: ptr<function, array<u32, 16>>, h_in: array<u32, 8>) -> array<u32, 8> {
var h = h_in;
// Message schedule
var w: array<u32, 64>;
for (var i = 0u; i < 16u; i++) {
w[i] = (*msg)[i];
}
for (var i = 16u; i < 64u; i++) {
w[i] = gamma1(w[i-2u]) + w[i-7u] + gamma0(w[i-15u]) + w[i-16u];
}
// Compression
var a = h[0]; var b = h[1]; var c = h[2]; var d = h[3];
var e = h[4]; var f = h[5]; var g = h[6]; var hh = h[7];
for (var i = 0u; i < 64u; i++) {
let t1 = hh + sigma1(e) + ch(e, f, g) + K[i] + w[i];
let t2 = sigma0(a) + maj(a, b, c);
hh = g; g = f; f = e; e = d + t1;
d = c; c = b; b = a; a = t1 + t2;
}
h[0] = h[0] + a; h[1] = h[1] + b; h[2] = h[2] + c; h[3] = h[3] + d;
h[4] = h[4] + e; h[5] = h[5] + f; h[6] = h[6] + g; h[7] = h[7] + hh;
return h;
}
// Process a single candidate and record match if found
fn process_candidate(name_idx: u32) {
// Generate message for this room name
var msg: array<u32, 16>;
let valid = index_to_room_name(name_idx, params.name_length, &msg);
if (!valid) {
return;
}
// Compute SHA256("#roomname") - this gives us the key
let key_hash = sha256_block(&msg);
// Take first 16 bytes (4 words) as the key
var key: array<u32, 4>;
key[0] = key_hash[0];
key[1] = key_hash[1];
key[2] = key_hash[2];
key[3] = key_hash[3];
// Compute SHA256(key) to get channel hash
let channel_hash = sha256_key(key);
// Check if channel hash matches target
if (channel_hash != params.target_channel_hash) {
return;
}
// Channel hash matches - verify MAC if enabled
if (params.verify_mac == 1u) {
let computed_mac = hmac_sha256_mac(key, params.ciphertext_len_bits);
if (computed_mac != params.target_mac) {
return;
}
}
// Found a match - record the index
let match_idx = atomicAdd(&match_count, 1u);
if (match_idx < 1024u) { // Limit stored matches
match_indices[match_idx] = name_idx;
}
}
// Each thread processes 32 candidates to amortize thread overhead
const CANDIDATES_PER_THREAD: u32 = 32u;
@compute @workgroup_size(256)
fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
let base_idx = global_id.x * CANDIDATES_PER_THREAD;
for (var i = 0u; i < CANDIDATES_PER_THREAD; i++) {
let idx = base_idx + i;
if (idx >= params.batch_size) {
return;
}
let name_idx = params.batch_offset + idx;
process_candidate(name_idx);
}
}
`}async init(){if(!navigator.gpu)return console.warn("WebGPU not supported"),!1;try{const s=await navigator.gpu.requestAdapter();if(!s)return console.warn("No GPU adapter found"),!1;this.device=await s.requestDevice(),this.bindGroupLayout=this.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}}]}),this.paramsBuffer=this.device.createBuffer({size:32,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.matchCountBuffer=this.device.createBuffer({size:4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST}),this.matchIndicesBuffer=this.device.createBuffer({size:1024*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC});for(let c=0;c<2;c++)this.matchCountReadBuffers[c]=this.device.createBuffer({size:4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),this.matchIndicesReadBuffers[c]=this.device.createBuffer({size:1024*4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST});const i=this.device.createShaderModule({code:this.shaderCode}),l=this.device.createPipelineLayout({bindGroupLayouts:[this.bindGroupLayout]});return this.pipeline=this.device.createComputePipeline({layout:l,compute:{module:i,entryPoint:"main"}}),!0}catch(s){return console.error("WebGPU initialization failed:",s),!1}}isAvailable(){return this.device!==null&&this.pipeline!==null}indexToRoomName(s,i){return es(i,s)}countNamesForLength(s){return vl(s)}async runBatch(s,i,l,c,u,p){if(!this.device||!this.pipeline||!this.bindGroupLayout||!this.paramsBuffer||!this.matchCountBuffer||!this.matchIndicesBuffer||!this.matchCountReadBuffers[0]||!this.matchCountReadBuffers[1]||!this.matchIndicesReadBuffers[0]||!this.matchIndicesReadBuffers[1])throw new Error("GPU not initialized");const d=this.currentReadBufferIndex;this.currentReadBufferIndex=1-this.currentReadBufferIndex;const g=this.matchCountReadBuffers[d],m=this.matchIndicesReadBuffers[d],x=u&&p?1:0;let A,b=0,k=0;if(x){const M=new Uint8Array(u.length/2);for(let Z=0;Z<M.length;Z++)M[Z]=parseInt(u.substr(Z*2,2),16);b=M.length*8;const H=Math.ceil(M.length/4)*4,U=new Uint8Array(H);U.set(M),A=new Uint32Array(H/4);for(let Z=0;Z<A.length;Z++)A[Z]=U[Z*4]<<24|U[Z*4+1]<<16|U[Z*4+2]<<8|U[Z*4+3];const j=parseInt(p.substr(0,2),16),ee=parseInt(p.substr(2,2),16);k=j<<24|ee<<16}else A=new Uint32Array([0]);const N=Math.max(A.length*4,4);(!this.ciphertextBuffer||this.ciphertextBufferSize<N)&&(this.ciphertextBuffer&&this.ciphertextBuffer.destroy(),this.ciphertextBuffer=this.device.createBuffer({size:N,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.ciphertextBufferSize=N,this.bindGroupDirty=!0);const C=new Uint32Array([s,l,i,c,k,A.length,b,x]);this.device.queue.writeBuffer(this.paramsBuffer,0,C),this.device.queue.writeBuffer(this.ciphertextBuffer,0,A),this.device.queue.writeBuffer(this.matchCountBuffer,0,kd.ZERO_DATA),(this.bindGroupDirty||!this.bindGroup)&&(this.bindGroup=this.device.createBindGroup({layout:this.bindGroupLayout,entries:[{binding:0,resource:{buffer:this.paramsBuffer}},{binding:1,resource:{buffer:this.matchCountBuffer}},{binding:2,resource:{buffer:this.matchIndicesBuffer}},{binding:3,resource:{buffer:this.ciphertextBuffer}}]}),this.bindGroupDirty=!1);const w=this.device.createCommandEncoder(),B=w.beginComputePass();B.setPipeline(this.pipeline),B.setBindGroup(0,this.bindGroup),B.dispatchWorkgroups(Math.ceil(c/(256*32))),B.end(),w.copyBufferToBuffer(this.matchCountBuffer,0,g,0,4),w.copyBufferToBuffer(this.matchIndicesBuffer,0,m,0,1024*4),this.device.queue.submit([w.finish()]),await g.mapAsync(GPUMapMode.READ);const R=new Uint32Array(g.getMappedRange())[0];g.unmap();const F=[];if(R>0){await m.mapAsync(GPUMapMode.READ);const M=new Uint32Array(m.getMappedRange());for(let H=0;H<Math.min(R,1024);H++)F.push(M[H]);m.unmap()}return F}destroy(){var s,i,l,c,u,p,d,g;(s=this.paramsBuffer)==null||s.destroy(),(i=this.matchCountBuffer)==null||i.destroy(),(l=this.matchIndicesBuffer)==null||l.destroy(),(c=this.ciphertextBuffer)==null||c.destroy(),(u=this.matchCountReadBuffers[0])==null||u.destroy(),(p=this.matchCountReadBuffers[1])==null||p.destroy(),(d=this.matchIndicesReadBuffers[0])==null||d.destroy(),(g=this.matchIndicesReadBuffers[1])==null||g.destroy(),this.paramsBuffer=null,this.matchCountBuffer=null,this.matchIndicesBuffer=null,this.ciphertextBuffer=null,this.ciphertextBufferSize=0,this.matchCountReadBuffers=[null,null],this.matchIndicesReadBuffers=[null,null],this.currentReadBufferIndex=0,this.bindGroup=null,this.bindGroupDirty=!0,this.device&&(this.device.destroy(),this.device=null),this.pipeline=null,this.bindGroupLayout=null}}kd.ZERO_DATA=new Uint32Array([0]);function sS(){return typeof navigator<"u"&&"gpu"in navigator}class hx{runBatch(s,i,l,c,u,p){const d=[],g=s.toString(16).padStart(2,"0 Line truncated
`).map(u=>u.trim().toLowerCase()).filter(u=>u.length>0);this.wordlist=c.filter(px)}setWordlist(s){this.wordlist=s.map(i=>i.trim().toLowerCase()).filter(px)}abort(){this.abortFlag=!0}isGpuAvailable(){return sS()}async decodePacket(s){var l;const i=s.trim().replace(/\s+/g,"").replace(/^0x/i,"");if(!i||!/^[0-9a-fA-F]+$/.test(i))return null;try{const u=(l=(await yt.MeshCorePacketDecoder.decodeWithVerification(i,{})).payload)==null?void 0:l.decoded;return!(u!=null&&u.channelHash)||!(u!=null&&u.ciphertext)||!(u!=null&&u.cipherMac)?null:{channelHash:u.channelHash,ciphertext:u.ciphertext,cipherMac:u.cipherMac,isGroupText:!0}}catch{return null}}async crack(s,i,l){this.abortFlag=!1,this.useTimestampFilter=(i==null?void 0:i.useTimestampFilter)??!0,this.useUtf8Filter=(i==null?void 0:i.useUtf8Filter)??!0,this.useSenderFilter=(i==null?void 0:i.useSenderFilter)??!0,this.validSeconds=(i==null?void 0:i.validSeconds)??N0,this.useCpu=(i==null?void 0:i.forceCpu)??!1;const c=(i==null?void 0:i.maxLength)??8,u=(i==null?void 0:i.startingLength)??1,p=(i==null?void 0:i.useDictionary)??!0,d=(i==null?void 0:i.startFromType)??"bruteforce",g=s.toLowerCase(),m=await this.decodePacket(g);if(!m)return{found:!1,error:"Invalid packet or not a GroupText packet"};const{channelHash:x,ciphertext:A,cipherMac:b}=m,k=parseInt(x,16);this.useCpu?this.cpuInstance||(this.cpuInstance=new hx):this.gpuInstance||(this.gpuInstance=new kd,await this.gpuInstance.init()||(this.useCpu=!0,this.cpuInstance=new hx));const N=performance.now();let C=0,w=performance.now(),B=u,S=0,R=0,F=!1;if(i!=null&&i.startFrom){const K=i.startFrom.toLowerCase();if(d==="dictionary"){const ae=this.wordlist.indexOf(K);ae>=0&&(R=ae+1)}else{F=!0;const ae=rS(K);ae&&(B=Math.max(u,ae.length),S=ae.index+1,S>=vl(B)&&(B++,S=0))}}let M=0;p&&!F&&this.wordlist.length>0&&(M+=this.wordlist.length-R);for(let K=B;K<=c;K++)M+=vl(K);M-=S;const H=(K,ae,xe)=>{if(!l)return;const se=(performance.now()-N)/1e3,W=se>0?Math.round(C/se):0,re=M-C,V=W>0?re/W:0;l({checked:C,total:M,percent:M>0?Math.min(100,C/M*100):0,rateKeysPerSec:W,etaSeconds:V,elapsedSeconds:se,currentLength:ae,currentPosition:xe,phase:K})},U=K=>{if(!Fv(A,b,K))return{valid:!1};const ae=yt.ChannelCrypto.decryptGroupTextMessage(A,b,K);return!ae.success||!ae.data?{valid:!1}:this.useTimestampFilter&&!iS(ae.data.timestamp,this.validSeconds)?{valid:!1}:this.useUtf8Filter&&!oS(ae.data.message)?{valid:!1}:this.useSenderFilter&&!ae.data.sender?{valid:!1}:{valid:!0,message:ae.data.sender?`${ae.data.sender}: ${ae.data.message}`:ae.data.message}};if(!F&&R===0&&B===u&&S===0){H("public-key",0,R0);const K=L0(Gu);if(x===K){const ae=U(Gu);if(ae.valid)return{found:!0,roomName:R0,key:Gu,decryptedMessage:ae.message}}}if(p&&!F&&this.wordlist.length>0)for(let K=R;K<this.wordlist.length;K++){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:this.wordlist[K],resumeType:"dictionary"};const ae=this.wordlist[K],xe=F0("#"+ae),G=L0(xe);if(parseInt(G,16)===k){const W=U(xe);if(W.valid)return{found:!0,roomName:ae,key:xe,decryptedMessage:W.message,resumeFrom:ae,resumeType:"dictionary"}}C++;const se=performance.now();se-w>=200&&(H("wordlist",ae.length,ae),w=se,await new Promise(W=>setTimeout(W,0)))}const j=this.useCpu?1024:32768,ee=(i==null?void 0:i.gpuDispatchMs)??1e3;let Z=j,Y=!1;for(let K=B;K<=c;K++){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:es(K,0)||void 0,resumeType:"bruteforce"};const ae=vl(K);let xe=K===B?S:0;for(;xe<ae;){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:es(K,xe)||void 0,resumeType:"bruteforce"};const G=Math.min(Z,ae-xe),se=performance.now();let W;this.useCpu?W=this.cpuInstance.runBatch(k,K,xe,G,A,b):W=await this.gpuInstance.runBatch(k,K,xe,G,A,b);const re=performance.now()-se;if(C+=G,!this.useCpu&&!Y&&G>=j&&re>0){const T=ee/re,z=Math.round(G*T),q=Math.pow(2,Math.round(Math.log2(Math.max(j,z))));Z=Math.max(j,q),Y=!0}for(const T of W){const z=es(K,T);if(!z)continue;const q=F0("#"+z),$=U(q);if($.valid)return{found:!0,roomName:z,key:q,decryptedMessage:$.message,resumeFrom:z,resumeType:"bruteforce"}}xe+=G;const V=performance.now();if(V-w>=200){const T=es(K,Math.min(xe,ae-1))||"";H("bruteforce",K,T),w=V,await new Promise(z=>setTimeout(z,0))}}}return{found:!1,resumeFrom:es(c,vl(c)-1)||void 0,resumeType:"bruteforce"}}destroy(){this.gpuInstance&&(this.gpuInstance.destroy(),this.gpuInstance=null),this.cpuInstance&&(this.cpuInstance.destroy(),this.cpuInstance=null)}}var g0,mx;function dS(){return mx||(mx=1,g0={webm:"data:video/webm;base64,GkXfowEAAAAAAAAfQoaBAUL3gQFC8oEEQvOBCEKChHdlYm1Ch4EEQoWBAhhTgGcBAAAAAAAVkhFNm3RALE27i1OrhBVJqWZTrIHfTbuMU6uEFlSua1OsggEwTbuMU6uEHFO7a1OsghV17AEAAAAAAACkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmAQAAAAAAAEUq17GDD0JATYCNTGF2ZjU1LjMzLjEwMFdBjUxhdmY1NS4zMy4xMDBzpJBlrrXf3DCDVB8KcgbMpcr+RImIQJBgAAAAAAAWVK5rAQAAAAAAD++uAQAAAAAAADL Line truncated
NoSleep enabled for older iOS devices. This can interrupt
active or long-running network requests from completing successfully.
See https://github.com/richtr/NoSleep.js/issues/15 for more details.
`),this.noSleepTimer=window.setInterval(()=>{document.hidden||(window.location.href=window.location.href.split("#")[0],window.setTimeout(window.stop,0))},15e3),this.enabled=!0,Promise.resolve()):this.noSleepVideo.play().then(d=>(this.enabled=!0,d)).catch(d=>{throw this.enabled=!1,d})}disable(){l()?(this._wakeLock&&this._wakeLock.release(),this._wakeLock=null):i()?this.noSleepTimer&&(console.warn(`
NoSleep now disabled for older iOS devices.
`),window.clearInterval(this.noSleepTimer),this.noSleepTimer=null):this.noSleepVideo.pause(),this.enabled=!1}}return x0=c,x0}var hS=fS();const pS=aa(hS);function mS(n){if(n.length<4)return null;try{const i=parseInt(n.slice(0,2),16)&3;let l=2;if(i===0||i===3){if(n.length<l+8)return null;l+=8}if(n.length<l+2)return null;const c=parseInt(n.slice(l,l+2),16);l+=2;const u=c*2;return n.length<l+u?null:(l+=u,n.slice(l))}catch{return null}}function gS({packets:n,channels:s,onChannelCreate:i,onRunningChange:l,visible:c=!1}){const[u,p]=D.useState(!1),[d,g]=D.useState(6),[m,x]=D.useState(!1),[A,b]=D.useState(!0),[k,N]=D.useState(!1),[C,w]=D.useState(null),[B,S]=D.useState(new Map),[R,F]=D.useState([]),[M,H]=D.useState(!1),[U,j]=D.useState(null),[ee,Z]=D.useState(null),[Y,ne]=D.useState(0),K=D.useRef(null),ae=D.useRef(null),xe=D.useRef(!1),G=D.useRef(!1),se=D.useRef(!1),W=D.useRef(new Map),re=D.useRef(!1),V=D.useRef(6),T=D.useRef(!0),z=D.useRef(!1),q=D.useRef(new Set),$=D.useRef(new Set);D.useEffect(()=>{const Ee=new uS;K.current=Ee,j(Ee.isGpuAvailable());const Ue=new pS;return ae.current=Ue,()=>{Ee.destroy(),K.current=null,Ue.disable(),ae.current=null}},[]),D.useEffect(()=>{!c||M||YA(async()=>{const{ENGLISH_WORDLIST:Ee}=await import("./wordlist-BtmChKSf.js");return{ENGLISH_WORDLIST:Ee}},[]).then(({ENGLISH_WORDLIST:Ee})=>{K.current&&(K.current.setWordlist(Ee),H(!0))}).catch(Ee=>{console.error("Failed to load wordlist:",Ee),xt.error("Failed to load wordlist",{description:"Cracking will not be available"})})},[c,M]),D.useEffect(()=>{const Ee=()=>{tt.getUndecryptedPacketCount().then(({count:ot})=>Z(ot)).catch(()=>Z(null))};Ee();const Ue=setInterval(Ee,36e5);return()=>clearInterval(Ue)},[]);const ue=D.useMemo(()=>new Set(s.map(Ee=>Ee.key.toUpperCase())),[s]),pe=n.filter(Ee=>Ee.payload_type==="GROUP_TEXT"&&!Ee.decrypted);D.useEffect(()=>{let Ee=0;S(Ue=>{const ot=new Map(Ue);let ht=!1;for(const et of pe)if(!ot.has(et.id)){const st=mS(et.data);if(st&&$.current.has(st)){Ee++;continue}st&&$.current.add(st),ot.set(et.id,{packet:et,attempts:0,lastAttemptLength:0,status:"pending"}),ht=!0}return ht?(W.current=ot,ot):Ue}),Ee>0&&ne(Ue=>Ue+Ee)},[pe.length]),D.useEffect(()=>{W.current=B},[B]),D.useEffect(()=>{re.current=m},[m]),D.useEffect(()=>{V.current=d},[d]),D.useEffect(()=>{T.current=A},[A]),D.useEffect(()=>{z.current=k},[k]),D.useEffect(()=>{q.current=new Set(pe.map(Ee=>Ee.id))},[pe]),D.useEffect(()=>{l==null||l(u)},[u,l]);const Ae=Array.from(B.values()).filter(Ee=>Ee.status==="pending").length,me=Array.from(B.values()).filter(Ee=>Ee.status==="cracked").length,ge=Array.from(B.values()).filter(Ee=>Ee.status==="failed").length,Be=D.useCallback(async()=>{if(se.current||!K.current||!xe.current)return;const Ee=W.current;let Ue=null,ot=null;for(const[Ge,$e]of Ee.entries())if($e.status==="pending"){Ue=$e,ot=Ge;break}if(!Ue&&re.current){const Ge=Array.from(Ee.entries()).filter(([,$e])=>$e.status==="failed"&&$e.lastAttemptLength<10);Ge.length>0&&(Ge.sort(($e,Ye)=>$e[1].lastAttemptLength-Ye[1].lastAttemptLength),[ot,Ue]=Ge[0])}if(!Ue||ot===null){xe.current&&setTimeout(()=>Be(),1e3);return}if(!q.current.has(ot)){S(Ge=>{const $e=new Map(Ge);return $e.delete(ot),$e}),xe.current&&setTimeout(()=>Be(),10);return}se.current=!0;const ht=V.current,et=Ue.lastAttemptLength>0,st=et?Ue.lastAttemptLength+1:ht;try{const Ge=await K.current.crack(Ue.packet.data,{maxLength:st,useSenderFilter:!0,useTimestampFilter:!0,useUtf8Filter:!0,...z.current&&{gpuDispatchMs:1e4},...et&&{useDictionary:!1,startingLength:st}},$e=>{w($e)});if(G.current){G.current=!1,se.current=!1,w(null);return}if(Ge.found&&Ge.roomName&&Ge.key){S(Me=>{const wt=new Map(Me),It=wt.get(ot);return It&&wt.set(ot,{...It,status:"cracked",attempts:It.attempts+1,lastAttemptLength:st}),wt});const $e={roomName:Ge.roomName,key:Ge.key,packetId:ot,message:Ge.decryptedMessage||"",crackedAt:Date.now()};F(Me=>[...Me,$e]);const Ye=Ge.key.toUpperCase();if(!ue.has(Ye))try{const Me="#"+Ge.roomName;await i(Me,Ge.key),T.current&&await tt.decryptHistoricalPackets({key_type:"channel",channel_name:Me})}catch(Me){console.error("Failed to create channel or decrypt historical:",Me),xt.error("Failed to save cracked channel",{description:Me instanceof Error?Me.message:"Channel discovered but could not be saved"})}}else S($e=>{const Ye=new Map($e),Me=Ye.get(ot);return Me&&Ye.set(ot,{...Me,status:"failed",attempts:Me.attempts+1,lastAttemptLength:st}),Ye})}catch(Ge){console.error("Cracking error:",Ge),S($e=>{const Ye=new Map($e),Me=Ye.get(ot);return Me&&Ye.set(ot,{...Me,status:"failed",attempts:Me.attempts+1,lastAttemptLength:st}),Ye})}se.current=!1,w(null),xe.current&&setTimeout(()=>Be(),100)},[ue,i]),We=()=>{var Ee;if(!U){xt.error("WebGPU not available",{description:"Cracking requires Chrome 113+ or Edge 113+ with WebGPU support."});return}p(!0),xe.current=!0,G.current=!1,(Ee=ae.current)==null||Ee.enable(),Be()},Ke=()=>{var Ee,Ue;p(!1),xe.current=!1,G.current=!0,(Ee=K.current)==null||Ee.abort(),(Ue=ae.current)==nul Line truncated
//# sourceMappingURL=index-BrthzT77.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"mappings":";;;;;;;;6CASa,IAAIA,EAAE,OAAO,IAAI,eAAe,EAAEC,EAAE,OAAO,IAAI,cAAc,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,mBAAmB,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,eAAe,EAAEC,EAAE,OAAO,IAAI,mBAAmB,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,YAAY,EAAEC,EAAE,OAAO,IAAI,YAAY,EAAEC,EAAE,OAAO,SAAS,SAASC,EAAEC,EAAE,CAAC,OAAUA,IAAP,MAAqB,OAAOA,GAAlB,SAA2B,MAAKA,EAAEF,GAAGE,EAAEF,CAAC,GAAGE,EAAE,YAAY,EAAqB,OAAOA,GAApB,WAAsBA,EAAE,KAAI,CAC1e,IAAIC,EAAE,CAAC,UAAU,UAAU,CAAC,MAAM,EAAE,EAAE,mBAAmB,UAAU,GAAG,oBAAoB,UAAU,GAAG,gBAAgB,UAAU,EAAE,EAAEC,EAAE,OAAO,OAAOC,EAAE,GAAG,SAASC,EAAEJ,EAAEK,EAAEC,EAAE,CAAC,KAAK,MAAMN,EAAE,KAAK,QAAQK,EAAE,KAAK,KAAKF,EAAE,KAAK,QAAQG,GAAGL,CAAC,CAACG,EAAE,UAAU,iBAAiB,GACnQA,EAAE,UAAU,SAAS,SAASJ,EAAEK,EAAE,CAAC,GAAc,OAAOL,GAAlB,UAAkC,OAAOA,GAApB,YAA6BA,GAAN,KAAQ,MAAM,MAAM,uHAAuH,EAAE,KAAK,QAAQ,gBAAgB,KAAKA,EAAEK,EAAE,UAAU,CAAC,EAAED,EAAE,UAAU,YAAY,SAASJ,EAAE,CAAC,KAAK,QAAQ,mBAAmB,KAAKA,EAAE,aAAa,CAAC,EAAE,SAASO,GAAG,EAAEA,EAAE,UAAUH,EAAE,UAAU,SAASI,EAAER,EAAEK,EAAEC,EAAE,CAAC,KAAK,MAAMN,EAAE,KAAK,QAAQK,EAAE,KAAK,KAAKF,EAAE,KAAK,QAAQG,GAAGL,CAAC,CAAC,IAAIQ,EAAED,EAAE,UAAU,IAAID,EACrfE,EAAE,YAAYD,EAAEN,EAAEO,EAAEL,EAAE,SAAS,EAAEK,EAAE,qBAAqB,GAAG,IAAIC,EAAE,MAAM,QAAQC,EAAE,OAAO,UAAU,eAAeC,EAAE,CAAC,QAAQ,IAAI,EAAEC,EAAE,CAAC,IAAI,GAAG,IAAI,GAAG,OAAO,GAAG,SAAS,EAAE,EACxK,SAASC,EAAEd,EAAEK,EAAEC,EAAE,CAAC,IAAIS,EAAEC,GAAE,GAAGC,GAAE,KAAKC,GAAE,KAAK,GAASb,GAAN,KAAQ,IAAIU,KAAcV,EAAE,MAAX,SAAiBa,GAAEb,EAAE,KAAcA,EAAE,MAAX,SAAiBY,GAAE,GAAGZ,EAAE,KAAKA,EAAEM,EAAE,KAAKN,EAAEU,CAAC,GAAG,CAACF,EAAE,eAAeE,CAAC,IAAIC,GAAED,CAAC,EAAEV,EAAEU,CAAC,GAAG,IAAII,GAAE,UAAU,OAAO,EAAE,GAAOA,KAAJ,EAAMH,GAAE,SAASV,UAAU,EAAEa,GAAE,CAAC,QAAQC,GAAE,MAAMD,EAAC,EAAEE,GAAE,EAAEA,GAAEF,GAAEE,KAAID,GAAEC,EAAC,EAAE,UAAUA,GAAE,CAAC,EAAEL,GAAE,SAASI,EAAC,CAAC,GAAGpB,GAAGA,EAAE,aAAa,IAAIe,KAAKI,GAAEnB,EAAE,aAAamB,GAAWH,GAAED,CAAC,IAAZ,SAAgBC,GAAED,CAAC,EAAEI,GAAEJ,CAAC,GAAG,MAAM,CAAC,SAAS5B,EAAE,KAAKa,EAAE,IAAIiB,GAAE,IAAIC,GAAE,MAAMF,GAAE,OAAOJ,EAAE,OAAO,CAAC,CAC7a,SAASU,GAAEtB,EAAEK,EAAE,CAAC,MAAM,CAAC,SAASlB,EAAE,KAAKa,EAAE,KAAK,IAAIK,EAAE,IAAIL,EAAE,IAAI,MAAMA,EAAE,MAAM,OAAOA,EAAE,MAAM,CAAC,CAAC,SAASuB,EAAEvB,EAAE,CAAC,OAAiB,OAAOA,GAAlB,UAA4BA,IAAP,MAAUA,EAAE,WAAWb,CAAC,CAAC,SAASqC,EAAOxB,EAAE,CAAC,IAAIK,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,EAAE,MAAM,IAAIL,EAAE,QAAQ,QAAQ,SAASA,EAAE,CAAC,OAAOK,EAAEL,CAAC,CAAC,CAAC,CAAC,CAAC,IAAIyB,GAAE,OAAO,SAASC,EAAE1B,EAAEK,EAAE,CAAC,OAAiB,OAAOL,GAAlB,UAA4BA,IAAP,MAAgBA,EAAE,KAAR,KAAYwB,EAAO,GAAGxB,EAAE,GAAG,EAAEK,EAAE,SAAS,EAAE,CAAC,CAC/W,SAASsB,GAAE3B,EAAEK,EAAEC,EAAES,EAAEC,GAAE,CAAC,IAAIC,GAAE,OAAOjB,GAAmBiB,KAAd,aAA6BA,KAAZ,aAAcjB,EAAE,MAAK,IAAIkB,GAAE,GAAG,GAAUlB,IAAP,KAASkB,GAAE,OAAQ,QAAOD,GAAC,CAAE,IAAK,SAAS,IAAK,SAASC,GAAE,GAAG,MAAM,IAAK,SAAS,OAAOlB,EAAE,SAAQ,CAAE,KAAKb,EAAE,KAAKC,EAAE8B,GAAE,EAAE,CAAC,CAAC,GAAGA,GAAE,OAAOA,GAAElB,EAAEgB,GAAEA,GAAEE,EAAC,EAAElB,EAAOe,IAAL,GAAO,IAAIW,EAAER,GAAE,CAAC,EAAEH,EAAEL,EAAEM,EAAC,GAAGV,EAAE,GAASN,GAAN,OAAUM,EAAEN,EAAE,QAAQyB,GAAE,KAAK,EAAE,KAAKE,GAAEX,GAAEX,EAAEC,EAAE,GAAG,SAASN,GAAE,CAAC,OAAOA,EAAC,CAAC,GAASgB,IAAN,OAAUO,EAAEP,EAAC,IAAIA,GAAEM,GAAEN,GAAEV,GAAG,CAACU,GAAE,KAAKE,IAAGA,GAAE,MAAMF,GAAE,IAAI,IAAI,GAAGA,GAAE,KAAK,QAAQS,GAAE,KAAK,EAAE,KAAKzB,CAAC,GAAGK,EAAE,KAAKW,EAAC,GAAG,EAAyB,GAAvBE,GAAE,EAAEH,EAAOA,IAAL,GAAO,IAAIA,EAAE,IAAOL,EAAEV,CAAC,EAAE,QAAQmB,GAAE,EAAEA,GAAEnB,EAAE,OAAOmB,KAAI,CAACF,GACrfjB,EAAEmB,EAAC,EAAE,IAAIC,GAAEL,EAAEW,EAAET,GAAEE,EAAC,EAAED,IAAGS,GAAEV,GAAEZ,EAAEC,EAAEc,GAAEJ,EAAC,CAAC,SAASI,GAAErB,EAAEC,CAAC,EAAe,OAAOoB,IAApB,WAAsB,IAAIpB,EAAEoB,GAAE,KAAKpB,CAAC,EAAEmB,GAAE,EAAE,EAAEF,GAAEjB,EAAE,KAAI,GAAI,MAAMiB,GAAEA,GAAE,MAAMG,GAAEL,EAAEW,EAAET,GAAEE,IAAG,EAAED,IAAGS,GAAEV,GAAEZ,EAAEC,EAAEc,GAAEJ,EAAC,UAAqBC,KAAX,SAAa,MAAMZ,EAAE,OAAOL,CAAC,EAAE,MAAM,mDAAuEK,IAApB,kBAAsB,qBAAqB,OAAO,KAAKL,CAAC,EAAE,KAAK,IAAI,EAAE,IAAIK,GAAG,2EAA2E,EAAE,OAAOa,EAAC,CACzZ,SAASU,GAAE5B,EAAEK,EAAEC,EAAE,CAAC,GAASN,GAAN,KAAQ,OAAOA,EAAE,IAAIe,EAAE,GAAGC,GAAE,EAAE,OAAAW,GAAE3B,EAAEe,EAAE,GAAG,GAAG,SAASf,GAAE,CAAC,OAAOK,EAAE,KAAKC,EAAEN,GAAEgB,IAAG,CAAC,CAAC,EAASD,CAAC,CAAC,SAASc,EAAE7B,EAAE,CAAC,GAAQA,EAAE,UAAP,GAAe,CAAC,IAAIK,EAAEL,EAAE,QAAQK,EAAEA,EAAC,EAAGA,EAAE,KAAK,SAASA,EAAE,EAAQL,EAAE,UAAN,GAAoBA,EAAE,UAAP,MAAeA,EAAE,QAAQ,EAAEA,EAAE,QAAQK,EAAC,EAAE,SAASA,EAAE,EAAQL,EAAE,UAAN,GAAoBA,EAAE,UAAP,MAAeA,EAAE,QAAQ,EAAEA,EAAE,QAAQK,EAAC,CAAC,EAAOL,EAAE,UAAP,KAAiBA,EAAE,QAAQ,EAAEA,EAAE,QAAQK,EAAE,CAAC,GAAOL,EAAE,UAAN,EAAc,OAAOA,EAAE,QAAQ,QAAQ,MAAMA,EAAE,OAAQ,CAC5Z,IAAI8B,GAAE,CAAC,QAAQ,IAAI,EAAEC,EAAE,CAAC,WAAW,IAAI,EAAEC,GAAE,CAAC,uBAAuBF,GAAE,wBAAwBC,EAAE,kBAAkBnB,CAAC,EAAE,SAASqB,GAAG,CAAC,MAAM,MAAM,0DAA0D,CAAE,CACzM,OAAAC,GAAA,SAAiB,CAAC,IAAIN,GAAE,QAAQ,SAAS5B,EAAEK,EAAEC,EAAE,CAACsB,GAAE5B,EAAE,UAAU,CAACK,EAAE,MAAM,KAAK,SAAS,CAAC,EAAEC,CAAC,CAAC,EAAE,MAAM,SAASN,EAAE,CAAC,IAAIK,EAAE,EAAE,OAAAuB,GAAE5B,EAAE,UAAU,CAACK,GAAG,CAAC,EAASA,CAAC,EAAE,QAAQ,SAASL,EAAE,CAAC,OAAO4B,GAAE5B,EAAE,SAASA,EAAE,CAAC,OAAOA,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,SAASA,EAAE,CAAC,GAAG,CAACuB,EAAEvB,CAAC,EAAE,Line truncated
-572
View File
@@ -1,572 +0,0 @@
var _y=Object.defineProperty;var wy=(n,s,i)=>s in n?_y(n,s,{enumerable:!0,configurable:!0,writable:!0,value:i}):n[s]=i;var qo=(n,s,i)=>wy(n,typeof s!="symbol"?s+"":s,i);function by(n,s){for(var i=0;i<s.length;i++){const l=s[i];if(typeof l!="string"&&!Array.isArray(l)){for(const c in l)if(c!=="default"&&!(c in n)){const u=Object.getOwnPropertyDescriptor(l,c);u&&Object.defineProperty(n,c,u.get?u:{enumerable:!0,get:()=>l[c]})}}}return Object.freeze(Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}))}(function(){const s=document.createElement("link").relList;if(s&&s.supports&&s.supports("modulepreload"))return;for(const c of document.querySelectorAll('link[rel="modulepreload"]'))l(c);new MutationObserver(c=>{for(const u of c)if(u.type==="childList")for(const p of u.addedNodes)p.tagName==="LINK"&&p.rel==="modulepreload"&&l(p)}).observe(document,{childList:!0,subtree:!0});function i(c){const u={};return c.integrity&&(u.integrity=c.integrity),c.referrerPolicy&&(u.referrerPolicy=c.referrerPolicy),c.crossOrigin==="use-credentials"?u.credentials="include":c.crossOrigin==="anonymous"?u.credentials="omit":u.credentials="same-origin",u}function l(c){if(c.ep)return;c.ep=!0;const u=i(c);fetch(c.href,u)}})();var Qf=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function aa(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}function vx(n){if(Object.prototype.hasOwnProperty.call(n,"__esModule"))return n;var s=n.default;if(typeof s=="function"){var i=function l(){return this instanceof l?Reflect.construct(s,arguments,this.constructor):s.apply(this,arguments)};i.prototype=s.prototype}else i={};return Object.defineProperty(i,"__esModule",{value:!0}),Object.keys(n).forEach(function(l){var c=Object.getOwnPropertyDescriptor(n,l);Object.defineProperty(i,l,c.get?c:{enumerable:!0,get:function(){return n[l]}})}),i}var Yf={exports:{}},el={},Xf={exports:{}},gt={};/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var Kp;function Cy(){if(Kp)return gt;Kp=1;var n=Symbol.for("react.element"),s=Symbol.for("react.portal"),i=Symbol.for("react.fragment"),l=Symbol.for("react.strict_mode"),c=Symbol.for("react.profiler"),u=Symbol.for("react.provider"),p=Symbol.for("react.context"),d=Symbol.for("react.forward_ref"),g=Symbol.for("react.suspense"),m=Symbol.for("react.memo"),x=Symbol.for("react.lazy"),A=Symbol.iterator;function w(D){return D===null||typeof D!="object"?null:(D=A&&D[A]||D["@@iterator"],typeof D=="function"?D:null)}var k={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},N=Object.assign,C={};function b(D,z,q){this.props=D,this.context=z,this.refs=C,this.updater=q||k}b.prototype.isReactComponent={},b.prototype.setState=function(D,z){if(typeof D!="object"&&typeof D!="function"&&D!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,D,z,"setState")},b.prototype.forceUpdate=function(D){this.updater.enqueueForceUpdate(this,D,"forceUpdate")};function S(){}S.prototype=b.prototype;function B(D,z,q){this.props=D,this.context=z,this.refs=C,this.updater=q||k}var T=B.prototype=new S;T.constructor=B,N(T,b.prototype),T.isPureReactComponent=!0;var F=Array.isArray,M=Object.prototype.hasOwnProperty,H={current:null},V={key:!0,ref:!0,__self:!0,__source:!0};function j(D,z,q){var $,ue={},pe=null,Ae=null;if(z!=null)for($ in z.ref!==void 0&&(Ae=z.ref),z.key!==void 0&&(pe=""+z.key),z)M.call(z,$)&&!V.hasOwnProperty($)&&(ue[$]=z[$]);var me=arguments.length-2;if(me===1)ue.children=q;else if(1<me){for(var xe=Array(me),Be=0;Be<me;Be++)xe[Be]=arguments[Be+2];ue.children=xe}if(D&&D.defaultProps)for($ in me=D.defaultProps,me)ue[$]===void 0&&(ue[$]=me[$]);return{$$typeof:n,type:D,key:pe,ref:Ae,props:ue,_owner:H.current}}function ee(D,z){return{$$typeof:n,type:D.type,key:z,ref:D.ref,props:D.props,_owner:D._owner}}function Z(D){return typeof D=="object"&&D!==null&&D.$$typeof===n}function Q(D){var z={"=":"=0",":":"=2"};return"$"+D.replace(/[=:]/g,function(q){return z[q]})}var J=/\/+/g;function K(D,z){return typeof D=="object"&&D!==null&&D.key!=null?Q(""+D.key):z.toString(36)}function oe(D,z,q,$,ue){var pe=typeof D;(pe==="undefined"||pe==="boolean")&&(D=null);var Ae=!1;if(D===null)Ae=!0;else switch(pe){case"string":case"number":Ae=!0;break;case"object":switch(D.$$typeof){case n:case s:Ae=!0}}if(Ae)return Ae=D,ue=ue(Ae),D=$===""?"."+K(Ae,0):$,F(ue)?(q="",D!=null&&(q=D.replace(J,"$&/")+"/"),oe(ue,z,q,"",function(Be){return Be})):ue!=null&&(Z(ue)&&(ue=ee(ue,q+(!ue.key||Ae&&Ae.key===ue.key?"":(""+ue.key).replace(J,"$&/")+"/")+D)),z.push(ue)),1;if(Ae=0,$=$===""?".":$+":",F(D))for(var me=0;me<D.length;me++){pe=D[me];var xe=$+K(pe,me);Ae+=oe(pe,z,q,xe,ue)}else if(xe=w(D),typeof xe=="function")for(D=xe.call(D),me=0;!(pe=D.next()).done;)pe=pe.value,xe=$+K(pe,me++),Ae+=oe(pe,z,q,xe,ue);else if(pe==="object")throw z=String(D),Error("Objects are not valid as a React child (found: "+(z==="[object Object]"?"object with keys {"+Object.keys(D).join(", ")+"}":z)+"). If you meant to render a collection of children, use an array instead.");return Ae}function ge(D,z,q){if(D==null)return D;var $=[],ue=0;return oe(D,$,"","",function(pe){return z.call(q,pe,ue++)}),$}function G(D){if(D._status===-1){var z=D._result;z=z(),z.then(function(q){(D._status===0||D._status===-1)&&(D._status=1,D._result=q)},function(q){(D._status===0||D._status===-1)&&(D._status=2,D._result=q)}),D._status===-1&&(D._status=0,D._result=z)}if(D._status===1)return D._result.default;throw D._result}var ae={current:null},W={transition:null},ne={ReactCurrentDispatcher:ae,ReactCurrentBatchConfig:W,ReactCurrentOwner:H};function U(){throw Error("act(...) is not supported in production builds of React.")}return gt.Children={map:ge,forEach:function(D,z,q){ge(D,function(){z.apply(this,arguments)},q)},count:function(D){var z=0;return ge(D,function(){z++}),z},toArray:function(D){return ge(D,function(z){return z})||[]},only:function(D){if(!Z(D))throw Error("React.Children.only expected to receive a single React element child.");return D}},gt.Component=b,gt.Fragment=i,gt.Profiler=c,gt.PureComponent=B,gt.StrictMode=l,gt.Suspense=g,gt.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=ne,gt.act=U,gt.cloneElement=function(D,z,q){if(D==null)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+D+".");var $=N({},D.props),ue=D.key,pe=D.ref,Ae=D._owner;if(z!=null){if(z.ref!==void 0&&(pe=z.ref,Ae=H.current),z.key!==void 0&&(ue=""+z.key),D.type&&D.type.defaultProps)var me=D.type.defaultProps;for(xe in z)M.call(z,xe)&&!V.hasOwnProperty(xe)&&($[xe]=z[xe]===void 0&&me!==void 0?me[xe]:z[xe])}var xe=arguments.length-2;if(xe===1)$.children=q;else if(1<xe){me=Array(xe);for(var Be=0;Be<xe;Be++)me[Be]=arguments[Be+2];$.children=me}return{$$typeof:n,type:D.type,key:ue,ref:pe,props:$,_owner:Ae}},gt.creatLine truncated
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var Yp;function Ey(){if(Yp)return el;Yp=1;var n=I0(),s=Symbol.for("react.element"),i=Symbol.for("react.fragment"),l=Object.prototype.hasOwnProperty,c=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,u={key:!0,ref:!0,__self:!0,__source:!0};function p(d,g,m){var x,A={},w=null,k=null;m!==void 0&&(w=""+m),g.key!==void 0&&(w=""+g.key),g.ref!==void 0&&(k=g.ref);for(x in g)l.call(g,x)&&!u.hasOwnProperty(x)&&(A[x]=g[x]);if(d&&d.defaultProps)for(x in g=d.defaultProps,g)A[x]===void 0&&(A[x]=g[x]);return{$$typeof:s,type:d,key:w,ref:k,props:A,_owner:c.current}}return el.Fragment=i,el.jsx=p,el.jsxs=p,el}var Xp;function ky(){return Xp||(Xp=1,Yf.exports=Ey()),Yf.exports}var _=ky(),R=I0();const Pe=aa(R),O0=by({__proto__:null,default:Pe},[R]);var Vc={},Jf={exports:{}},Qn={},e0={exports:{}},t0={};/**
* @license React
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var Jp;function Sy(){return Jp||(Jp=1,(function(n){function s(W,ne){var U=W.length;W.push(ne);e:for(;0<U;){var D=U-1>>>1,z=W[D];if(0<c(z,ne))W[D]=ne,W[U]=z,U=D;else break e}}function i(W){return W.length===0?null:W[0]}function l(W){if(W.length===0)return null;var ne=W[0],U=W.pop();if(U!==ne){W[0]=U;e:for(var D=0,z=W.length,q=z>>>1;D<q;){var $=2*(D+1)-1,ue=W[$],pe=$+1,Ae=W[pe];if(0>c(ue,U))pe<z&&0>c(Ae,ue)?(W[D]=Ae,W[pe]=U,D=pe):(W[D]=ue,W[$]=U,D=$);else if(pe<z&&0>c(Ae,U))W[D]=Ae,W[pe]=U,D=pe;else break e}}return ne}function c(W,ne){var U=W.sortIndex-ne.sortIndex;return U!==0?U:W.id-ne.id}if(typeof performance=="object"&&typeof performance.now=="function"){var u=performance;n.unstable_now=function(){return u.now()}}else{var p=Date,d=p.now();n.unstable_now=function(){return p.now()-d}}var g=[],m=[],x=1,A=null,w=3,k=!1,N=!1,C=!1,b=typeof setTimeout=="function"?setTimeout:null,S=typeof clearTimeout=="function"?clearTimeout:null,B=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function T(W){for(var ne=i(m);ne!==null;){if(ne.callback===null)l(m);else if(ne.startTime<=W)l(m),ne.sortIndex=ne.expirationTime,s(g,ne);else break;ne=i(m)}}function F(W){if(C=!1,T(W),!N)if(i(g)!==null)N=!0,G(M);else{var ne=i(m);ne!==null&&ae(F,ne.startTime-W)}}function M(W,ne){N=!1,C&&(C=!1,S(j),j=-1),k=!0;var U=w;try{for(T(ne),A=i(g);A!==null&&(!(A.expirationTime>ne)||W&&!Q());){var D=A.callback;if(typeof D=="function"){A.callback=null,w=A.priorityLevel;var z=D(A.expirationTime<=ne);ne=n.unstable_now(),typeof z=="function"?A.callback=z:A===i(g)&&l(g),T(ne)}else l(g);A=i(g)}if(A!==null)var q=!0;else{var $=i(m);$!==null&&ae(F,$.startTime-ne),q=!1}return q}finally{A=null,w=U,k=!1}}var H=!1,V=null,j=-1,ee=5,Z=-1;function Q(){return!(n.unstable_now()-Z<ee)}function J(){if(V!==null){var W=n.unstable_now();Z=W;var ne=!0;try{ne=V(!0,W)}finally{ne?K():(H=!1,V=null)}}else H=!1}var K;if(typeof B=="function")K=function(){B(J)};else if(typeof MessageChannel<"u"){var oe=new MessageChannel,ge=oe.port2;oe.port1.onmessage=J,K=function(){ge.postMessage(null)}}else K=function(){b(J,0)};function G(W){V=W,H||(H=!0,K())}function ae(W,ne){j=b(function(){W(n.unstable_now())},ne)}n.unstable_IdlePriority=5,n.unstable_ImmediatePriority=1,n.unstable_LowPriority=4,n.unstable_NormalPriority=3,n.unstable_Profiling=null,n.unstable_UserBlockingPriority=2,n.unstable_cancelCallback=function(W){W.callback=null},n.unstable_continueExecution=function(){N||k||(N=!0,G(M))},n.unstable_forceFrameRate=function(W){0>W||125<W?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):ee=0<W?Math.floor(1e3/W):5},n.unstable_getCurrentPriorityLevel=function(){return w},n.unstable_getFirstCallbackNode=function(){return i(g)},n.unstable_next=function(W){switch(w){case 1:case 2:case 3:var ne=3;break;default:ne=w}var U=w;w=ne;try{return W()}finally{w=U}},n.unstable_pauseExecution=function(){},n.unstable_requestPaint=function(){},n.unstable_runWithPriority=function(W,ne){switch(W){case 1:case 2:case 3:case 4:case 5:break;default:W=3}var U=w;w=W;try{return ne()}finally{w=U}},n.unstable_scheduleCallback=function(W,ne,U){var D=n.unstable_now();switch(typeof U=="object"&&U!==null?(U=U.delay,U=typeof U=="number"&&0<U?D+U:D):U=D,W){case 1:var z=-1;break;case 2:z=250;break;case 5:z=1073741823;break;case 4:z=1e4;break;default:z=5e3}return z=U+z,W={id:x++,callback:ne,priorityLevel:W,startTime:U,expirationTime:z,sortIndex:-1},U>D?(W.sortIndex=U,s(m,W),i(g)===null&&W===i(m)&&(C?(S(j),j=-1):C=!0,ae(F,U-D))):(W.sortIndex=z,s(g,W),N||k||(N=!0,G(M))),W},n.unstable_shouldYield=Q,n.unstable_wrapCallback=function(W){var ne=w;return function(){var U=w;w=ne;try{return W.apply(this,arguments)}finally{w=U}}}})(t0)),t0}var em;function By(){return em||(em=1,e0.exports=Sy()),e0.exports}/**
* @license React
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var tm;function Py(){if(tm)return Qn;tm=1;var n=I0(),s=By();function i(e){for(var r="https://reactjs.org/docs/error-decoder.html?invariant="+e,a=1;a<arguments.length;a++)r+="&args[]="+encodeURIComponent(arguments[a]);return"Minified React error #"+e+"; visit "+r+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var l=new Set,c={};function u(e,r){p(e,r),p(e+"Capture",r)}function p(e,r){for(c[e]=r,e=0;e<r.length;e++)l.add(r[e])}var d=!(typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),g=Object.prototype.hasOwnProperty,m=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,x={},A={};function w(e){return g.call(A,e)?!0:g.call(x,e)?!1:m.test(e)?A[e]=!0:(x[e]=!0,!1)}function k(e,r,a,h){if(a!==null&&a.type===0)return!1;switch(typeof r){case"function":case"symbol":return!0;case"boolean":return h?!1:a!==null?!a.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function N(e,r,a,h){if(r===null||typeof r>"u"||k(e,r,a,h))return!0;if(h)return!1;if(a!==null)switch(a.type){case 3:return!r;case 4:return r===!1;case 5:return isNaN(r);case 6:return isNaN(r)||1>r}return!1}function C(e,r,a,h,y,E,I){this.acceptsBooleans=r===2||r===3||r===4,this.attributeName=h,this.attributeNamespace=y,this.mustUseProperty=a,this.propertyName=e,this.type=r,this.sanitizeURL=E,this.removeEmptyString=I}var b={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){b[e]=new C(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var r=e[0];b[r]=new C(r,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){b[e]=new C(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){b[e]=new C(e,2,!1,e,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){b[e]=new C(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){b[e]=new C(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){b[e]=new C(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){b[e]=new C(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){b[e]=new C(e,5,!1,e.toLowerCase(),null,!1,!1)});var S=/[\-:]([a-z])/g;function B(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var r=e.replace(S,B);b[r]=new C(r,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var r=e.replace(S,B);b[r]=new C(r,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var r=e.replace(S,B);b[r]=new C(r,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){b[e]=new C(e,1,!1,e.toLowerCase(),null,!1,!1)}),b.xlinkHref=new C("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){b[e]=new C(e,1,!1,e.toLowerCase(),null,!0,!0)});function T(e,r,a,h){var y=b.hasOwnProperty(r)?b[r]:null;(y!==null?y.type!==0:h||!(2<r.length)||r[0]!=="o"&&r[0]!=="O"||r[1]!=="n"&&r[1]!= Line truncated
`+D+e}var q=!1;function $(e,r){if(!e||q)return"";q=!0;var a=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(r)if(r=function(){throw Error()},Object.defineProperty(r.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(r,[])}catch(he){var h=he}Reflect.construct(e,[],r)}else{try{r.call()}catch(he){h=he}e.call(r.prototype)}else{try{throw Error()}catch(he){h=he}e()}}catch(he){if(he&&h&&typeof he.stack=="string"){for(var y=he.stack.split(`
`),E=h.stack.split(`
`),I=y.length-1,Y=E.length-1;1<=I&&0<=Y&&y[I]!==E[Y];)Y--;for(;1<=I&&0<=Y;I--,Y--)if(y[I]!==E[Y]){if(I!==1||Y!==1)do if(I--,Y--,0>Y||y[I]!==E[Y]){var te=`
`+y[I].replace(" at new "," at ");return e.displayName&&te.includes("<anonymous>")&&(te=te.replace("<anonymous>",e.displayName)),te}while(1<=I&&0<=Y);break}}}finally{q=!1,Error.prepareStackTrace=a}return(e=e?e.displayName||e.name:"")?z(e):""}function ue(e){switch(e.tag){case 5:return z(e.type);case 16:return z("Lazy");case 13:return z("Suspense");case 19:return z("SuspenseList");case 0:case 2:case 15:return e=$(e.type,!1),e;case 11:return e=$(e.type.render,!1),e;case 1:return e=$(e.type,!0),e;default:return""}}function pe(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case V:return"Fragment";case H:return"Portal";case ee:return"Profiler";case j:return"StrictMode";case K:return"Suspense";case oe:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case Q:return(e.displayName||"Context")+".Consumer";case Z:return(e._context.displayName||"Context")+".Provider";case J:var r=e.render;return e=e.displayName,e||(e=r.displayName||r.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case ge:return r=e.displayName||null,r!==null?r:pe(e.type)||"Memo";case G:r=e._payload,e=e._init;try{return pe(e(r))}catch{}}return null}function Ae(e){var r=e.type;switch(e.tag){case 24:return"Cache";case 9:return(r.displayName||"Context")+".Consumer";case 10:return(r._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=r.render,e=e.displayName||e.name||"",r.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return r;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return pe(r);case 8:return r===j?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof r=="function")return r.displayName||r.name||null;if(typeof r=="string")return r}return null}function me(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function xe(e){var r=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(r==="checkbox"||r==="radio")}function Be(e){var r=xe(e)?"checked":"value",a=Object.getOwnPropertyDescriptor(e.constructor.prototype,r),h=""+e[r];if(!e.hasOwnProperty(r)&&typeof a<"u"&&typeof a.get=="function"&&typeof a.set=="function"){var y=a.get,E=a.set;return Object.defineProperty(e,r,{configurable:!0,get:function(){return y.call(this)},set:function(I){h=""+I,E.call(this,I)}}),Object.defineProperty(e,r,{enumerable:a.enumerable}),{getValue:function(){return h},setValue:function(I){h=""+I},stopTracking:function(){e._valueTracker=null,delete e[r]}}}}function We(e){e._valueTracker||(e._valueTracker=Be(e))}function Ke(e){if(!e)return!1;var r=e._valueTracker;if(!r)return!0;var a=r.getValue(),h="";return e&&(h=xe(e)?e.checked?"true":"false":e.value),e=h,e!==a?(r.setValue(e),!0):!1}function Ee(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function Ue(e,r){var a=r.checked;return U({},r,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:a??e._wrapperState.initialChecked})}function ot(e,r){var a=r.defaultValue==null?"":r.defaultValue,h=r.checked!=null?r.checked:r.defaultChecked;a=me(r.value!=null?r.value:a),e._wrapperState={initialChecked:h,initialValue:a,controlled:r.type==="checkbox"||r.type==="radio"?r.checked!=null:r.value!=null}}function ht(e,r){r=r.checked,r!=null&&T(e,"checked",r,!1)}function Je(e,r){ht(e,r);var a=me(r.value),h=r.type;if(a!=null)h==="number"?(a===0&&e.value===""||e.value!=a)&&(e.value=""+a):e.value!==""+a&&(e.value=""+a);else if(h==="submit"||h==="reset"){e.removeAttribute("value");return}r.hasOwnProperty("value")?Ge(e,r.type,a):r.hasOwnProperty("defaultValue")&&Ge(e,r.type,me(r.defaultValue)),r.checked==null&&r.defaultChecked!=null&&(e.defaultChecked=!!r.defaultChecked)}function st(e,r,a){if(r.hasOwnProperty("value")||r.hasOwnProperty("defaultValue")){var h=r.type;if(!(h!=="submit"&&h!=="reset"||r.value!==void 0&&r.value!==null))return;r=""+e._wrapperState.initialValue,a||r===e.value||(e.value=r),e.defaultValue=r}a=e.name,a!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,a!==""&&(e.name=a)}function Ge(e,r,a){(r!=="number"||Ee(e.ownerDocument)!==e)&&(a==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+a&&(e.defaultValue=""+a))}var $e=Array.isArray;function et(e,r,a,h){if(e=e.options,r){r={};for(var y=0;y<a.length;y++)r["$"+a[y]]=!0;for(a=0;a<e.length;a++)y=r.hasOwnProperty("$"+e[a].value),e[a].selected!==y&&(e[a].selected=y),y&&h&&(e[a].defaultSelected=!0)}else{for(a=""+me(a),r=null,y=0;y<e.length;y++){if(e[y].value===a){e[y].selected=!0,h&&(e[y].defaultSelected=!0);return}r!==null||e[y].disabled||(r=e[y])}r!==null&&(r.selected=!0)}}function Oe(e,r){if(r.dangerouslySetInner Line truncated
`).replace(X,"")}function fe(e,r,a){if(r=le(r),le(e)!==r&&a)throw Error(i(425))}function we(){}var Ne=null,Qe=null;function ct(e,r){return e==="textarea"||e==="noscript"||typeof r.children=="string"||typeof r.children=="number"||typeof r.dangerouslySetInnerHTML=="object"&&r.dangerouslySetInnerHTML!==null&&r.dangerouslySetInnerHTML.__html!=null}var ln=typeof setTimeout=="function"?setTimeout:void 0,rn=typeof clearTimeout=="function"?clearTimeout:void 0,In=typeof Promise=="function"?Promise:void 0,Sn=typeof queueMicrotask=="function"?queueMicrotask:typeof In<"u"?function(e){return In.resolve(null).then(e).catch(Ji)}:ln;function Ji(e){setTimeout(function(){throw e})}function ja(e,r){var a=r,h=0;do{var y=a.nextSibling;if(e.removeChild(a),y&&y.nodeType===8)if(a=y.data,a==="/$"){if(h===0){e.removeChild(y),nr(r);return}h--}else a!=="$"&&a!=="$?"&&a!=="$!"||h++;a=y}while(a);nr(r)}function Yr(e){for(;e!=null;e=e.nextSibling){var r=e.nodeType;if(r===1||r===3)break;if(r===8){if(r=e.data,r==="$"||r==="$!"||r==="$?")break;if(r==="/$")return null}}return e}function rc(e){e=e.previousSibling;for(var r=0;e;){if(e.nodeType===8){var a=e.data;if(a==="$"||a==="$!"||a==="$?"){if(r===0)return e;r--}else a==="/$"&&r++}e=e.previousSibling}return null}var mi=Math.random().toString(36).slice(2),xr="__reactFiber$"+mi,eo="__reactProps$"+mi,kt="__reactContainer$"+mi,to="__reactEvents$"+mi,Zd="__reactListeners$"+mi,Wd="__reactHandles$"+mi;function gi(e){var r=e[xr];if(r)return r;for(var a=e.parentNode;a;){if(r=a[kt]||a[xr]){if(a=r.alternate,r.child!==null||a!==null&&a.child!==null)for(e=rc(e);e!==null;){if(a=e[xr])return a;e=rc(e)}return r}e=a,a=e.parentNode}return null}function xi(e){return e=e[xr]||e[kt],!e||e.tag!==5&&e.tag!==6&&e.tag!==13&&e.tag!==3?null:e}function Ai(e){if(e.tag===5||e.tag===6)return e.stateNode;throw Error(i(33))}function Ns(e){return e[eo]||null}var qd=[],Fs=-1;function no(e){return{current:e}}function zt(e){0>Fs||(e.current=qd[Fs],qd[Fs]=null,Fs--)}function Mt(e,r){Fs++,qd[Fs]=e.current,e.current=r}var ro={},Bn=no(ro),Wn=no(!1),Lo=ro;function Ls(e,r){var a=e.type.contextTypes;if(!a)return ro;var h=e.stateNode;if(h&&h.__reactInternalMemoizedUnmaskedChildContext===r)return h.__reactInternalMemoizedMaskedChildContext;var y={},E;for(E in a)y[E]=r[E];return h&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=r,e.__reactInternalMemoizedMaskedChildContext=y),y}function qn(e){return e=e.childContextTypes,e!=null}function ic(){zt(Wn),zt(Bn)}function xh(e,r,a){if(Bn.current!==ro)throw Error(i(168));Mt(Bn,r),Mt(Wn,a)}function Ah(e,r,a){var h=e.stateNode;if(r=r.childContextTypes,typeof h.getChildContext!="function")return a;h=h.getChildContext();for(var y in h)if(!(y in r))throw Error(i(108,Ae(e)||"Unknown",y));return U({},a,h)}function oc(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||ro,Lo=Bn.current,Mt(Bn,e),Mt(Wn,Wn.current),!0}function vh(e,r,a){var h=e.stateNode;if(!h)throw Error(i(169));a?(e=Ah(e,r,Lo),h.__reactInternalMemoizedMergedChildContext=e,zt(Wn),zt(Bn),Mt(Bn,e)):zt(Wn),Mt(Wn,a)}var vi=null,sc=!1,Gd=!1;function yh(e){vi===null?vi=[e]:vi.push(e)}function zv(e){sc=!0,yh(e)}function io(){if(!Gd&&vi!==null){Gd=!0;var e=0,r=_t;try{var a=vi;for(_t=1;e<a.length;e++){var h=a[e];do h=h(!0);while(h!==null)}vi=null,sc=!1}catch(y){throw vi!==null&&(vi=vi.slice(e+1)),Nl(pa,io),y}finally{_t=r,Gd=!1}}return null}var Ms=[],Is=0,ac=null,lc=0,Ar=[],vr=0,Mo=null,yi=1,_i="";function Io(e,r){Ms[Is++]=lc,Ms[Is++]=ac,ac=e,lc=r}function _h(e,r,a){Ar[vr++]=yi,Ar[vr++]=_i,Ar[vr++]=Mo,Mo=e;var h=yi;e=_i;var y=32-at(h)-1;h&=~(1<<y),a+=1;var E=32-at(r)+y;if(30<E){var I=y-y%5;E=(h&(1<<I)-1).toString(32),h>>=I,y-=I,yi=1<<32-at(r)+y|a<<y|h,_i=E+e}else yi=1<<E|a<<y|h,_i=e}function $d(e){e.return!==null&&(Io(e,1),_h(e,1,0))}function Kd(e){for(;e===ac;)ac=Ms[--Is],Ms[Is]=null,lc=Ms[--Is],Ms[Is]=null;for(;e===Mo;)Mo=Ar[--vr],Ar[vr]=null,_i=Ar[--vr],Ar[vr]=null,yi=Ar[--vr],Ar[vr]=null}var ar=null,lr=null,Zt=!1,Nr=null;function wh(e,r){var a=br(5,null,null,0);a.elementType="DELETED",a.stateNode=r,a.return=e,r=e.deletions,r===null?(e.deletions=[a],e.flags|=16):r.push(a)}function bh(e,r){switch(e.tag){case 5:var a=e.type;return r=r.nodeType!==1||a.toLowerCase()!==r.nodeName.toLowerCase()?null:r,r!==null?(e.stateNode=r,ar=e,lr=Yr(r.firstChild),!0):!1;case 6:return r=e.pendingProps===""||r.nodeType!==3?null:r,r!==null?(e.stateNode=r,ar=e,lr=null,!0):!1;case 13:return r=r.nodeType!==8?null:r,r!==null?(a=Mo!==null?{id:yi,overflow:_i}:null,e.memoizedState={dehydrated:r,treeContext:a,retryLane:1073741824},a=br(18,null,null,0),a.stateNode=r,a.return=e,e.child=a,ar=e,lr=null,!0):!1;default:return!1}}function Qd(e){return(e.mode&1)!==0&&(e.flags&128)===0}function Yd(e){if(Zt){var r=lr;if(r){var a=r;if(!bh(e,r)){if(Qd(e))throw Error(i(418));r=Yr(a.nextSibling);var h=ar;r&&bh(e,r)?wh(h,a):(e.flags=e.flags&-4097|2,Zt=!1,ar=e)}}else{if(Qd(e))throw Error(i(418));e.flags=e.flags&-4097|2,Zt=!1,ar=e}}}function Ch(e){for(e=e.r Line truncated
Error generating stack: `+E.message+`
`+E.stack}return{value:e,source:r,stack:y,digest:null}}function yf(e,r,a){return{value:e,source:null,stack:a??null,digest:r??null}}function _f(e,r){try{console.error(r.value)}catch(a){setTimeout(function(){throw a})}}var Kv=typeof WeakMap=="function"?WeakMap:Map;function ip(e,r,a){a=bi(-1,a),a.tag=3,a.payload={element:null};var h=r.value;return a.callback=function(){Bc||(Bc=!0,Mf=h),_f(e,r)},a}function op(e,r,a){a=bi(-1,a),a.tag=3;var h=e.type.getDerivedStateFromError;if(typeof h=="function"){var y=r.value;a.payload=function(){return h(y)},a.callback=function(){_f(e,r)}}var E=e.stateNode;return E!==null&&typeof E.componentDidCatch=="function"&&(a.callback=function(){_f(e,r),typeof h!="function"&&(lo===null?lo=new Set([this]):lo.add(this));var I=r.stack;this.componentDidCatch(r.value,{componentStack:I!==null?I:""})}),a}function sp(e,r,a){var h=e.pingCache;if(h===null){h=e.pingCache=new Kv;var y=new Set;h.set(r,y)}else y=h.get(r),y===void 0&&(y=new Set,h.set(r,y));y.has(a)||(y.add(a),e=cy.bind(null,e,r,a),r.then(e,e))}function ap(e){do{var r;if((r=e.tag===13)&&(r=e.memoizedState,r=r!==null?r.dehydrated!==null:!0),r)return e;e=e.return}while(e!==null);return null}function lp(e,r,a,h,y){return(e.mode&1)===0?(e===r?e.flags|=65536:(e.flags|=128,a.flags|=131072,a.flags&=-52805,a.tag===1&&(a.alternate===null?a.tag=17:(r=bi(-1,1),r.tag=2,so(a,r,1))),a.lanes|=1),e):(e.flags|=65536,e.lanes=y,e)}var Qv=F.ReactCurrentOwner,Gn=!1;function On(e,r,a,h){r.child=e===null?Bh(r,null,a,h):js(r,e.child,a,h)}function cp(e,r,a,h,y){a=a.render;var E=r.ref;return Hs(r,y),h=ff(e,r,a,h,E,y),a=hf(),e!==null&&!Gn?(r.updateQueue=e.updateQueue,r.flags&=-2053,e.lanes&=~y,Ci(e,r,y)):(Zt&&a&&$d(r),r.flags|=1,On(e,r,h,y),r.child)}function up(e,r,a,h,y){if(e===null){var E=a.type;return typeof E=="function"&&!Uf(E)&&E.defaultProps===void 0&&a.compare===null&&a.defaultProps===void 0?(r.tag=15,r.type=E,dp(e,r,E,h,y)):(e=Fc(a.type,null,h,r,r.mode,y),e.ref=r.ref,e.return=r,r.child=e)}if(E=e.child,(e.lanes&y)===0){var I=E.memoizedProps;if(a=a.compare,a=a!==null?a:$r,a(I,h)&&e.ref===r.ref)return Ci(e,r,y)}return r.flags|=1,e=ho(E,h),e.ref=r.ref,e.return=r,r.child=e}function dp(e,r,a,h,y){if(e!==null){var E=e.memoizedProps;if($r(E,h)&&e.ref===r.ref)if(Gn=!1,r.pendingProps=h=E,(e.lanes&y)!==0)(e.flags&131072)!==0&&(Gn=!0);else return r.lanes=e.lanes,Ci(e,r,y)}return wf(e,r,a,h,y)}function fp(e,r,a){var h=r.pendingProps,y=h.children,E=e!==null?e.memoizedState:null;if(h.mode==="hidden")if((r.mode&1)===0)r.memoizedState={baseLanes:0,cachePool:null,transitions:null},Mt(Ws,cr),cr|=a;else{if((a&1073741824)===0)return e=E!==null?E.baseLanes|a:a,r.lanes=r.childLanes=1073741824,r.memoizedState={baseLanes:e,cachePool:null,transitions:null},r.updateQueue=null,Mt(Ws,cr),cr|=e,null;r.memoizedState={baseLanes:0,cachePool:null,transitions:null},h=E!==null?E.baseLanes:a,Mt(Ws,cr),cr|=h}else E!==null?(h=E.baseLanes|a,r.memoizedState=null):h=a,Mt(Ws,cr),cr|=h;return On(e,r,y,a),r.child}function hp(e,r){var a=r.ref;(e===null&&a!==null||e!==null&&e.ref!==a)&&(r.flags|=512,r.flags|=2097152)}function wf(e,r,a,h,y){var E=qn(a)?Lo:Bn.current;return E=Ls(r,E),Hs(r,y),a=ff(e,r,a,h,E,y),h=hf(),e!==null&&!Gn?(r.updateQueue=e.updateQueue,r.flags&=-2053,e.lanes&=~y,Ci(e,r,y)):(Zt&&h&&$d(r),r.flags|=1,On(e,r,a,y),r.child)}function pp(e,r,a,h,y){if(qn(a)){var E=!0;oc(r)}else E=!1;if(Hs(r,y),r.stateNode===null)bc(e,r),np(r,a,h),vf(r,a,h,y),h=!0;else if(e===null){var I=r.stateNode,Y=r.memoizedProps;I.props=Y;var te=I.context,he=a.contextType;typeof he=="object"&&he!==null?he=yr(he):(he=qn(a)?Lo:Bn.current,he=Ls(r,he));var Ce=a.getDerivedStateFromProps,Se=typeof Ce=="function"||typeof I.getSnapshotBeforeUpdate=="function";Se||typeof I.UNSAFE_componentWillReceiveProps!="function"&&typeof I.componentWillReceiveProps!="function"||(Y!==h||te!==he)&&rp(r,I,h,he),oo=!1;var be=r.memoizedState;I.state=be,pc(r,h,I,y),te=r.memoizedState,Y!==h||be!==te||Wn.current||oo?(typeof Ce=="function"&&(Af(r,a,Ce,h),te=r.memoizedState),(Y=oo||tp(r,a,Y,h,be,te,he))?(Se||typeof I.UNSAFE_componentWillMount!="function"&&typeof I.componentWillMount!="function"||(typeof I.componentWillMount=="function"&&I.componentWillMount(),typeof I.UNSAFE_componentWillMount=="function"&&I.UNSAFE_componentWillMount()),typeof I.componentDidMount=="function"&&(r.flags|=4194308)):(typeof I.componentDidMount=="function"&&(r.flags|=4194308),r.memoizedProps=h,r.memoizedState=te),I.props=h,I.state=te,I.context=he,h=Y):(typeof I.componentDidMount=="function"&&(r.flags|=4194308),h=!1)}else{I=r.stateNode,Th(e,r),Y=r.memoizedProps,he=r.type===r.elementType?Y:Fr(r.type,Y),I.props=he,Se=r.pendingProps,be=I.context,te=a.contextType,typeof te=="object"&&te!==null?te=yr(te):(te=qn(a)?Lo:Bn.current,te=Ls(r,te));var Me=a.getDerivedStateFromProps;(Ce=typeof Me=="function"||typeof I.getSnapshotBeforeUpdate=="function")||typeof I.UNSAFE_componentWillReceiveProps!="function"&&typeof I.componentWillReceiveProps!="function"||(Y!==Se||be!==te)&&rp(r,I, Line truncated
`)}function $s(n,s,i){const l=Math.floor(Date.now()/1e3);return{id:-Date.now(),type:"PRIV",conversation_key:n,text:s,sender_timestamp:l,received_at:l,paths:null,txt_type:0,signature:null,outgoing:i,acked:1}}function Oy(n){const s=R.useRef(null),i=R.useRef(null),l=R.useCallback(()=>{i.current!==null&&(clearInterval(i.current),i.current=null),s.current=null},[]),c=R.useCallback(async()=>{const p=s.current;if(!p)return;let d=null,g=null;for(let m=0;m<2;m++)try{d=await it.requestTelemetry(p.conversationId,"");break}catch(x){g=x instanceof Error?x:new Error("Unknown error"),m===0&&await new Promise(A=>setTimeout(A,2e3))}if(d){const m=$s(p.conversationId,Iy(p,d),!1);n(x=>[...x,m])}else{const m=$s(p.conversationId,`Duty cycle poll failed after retry: ${(g==null?void 0:g.message)??"Unknown error"}`,!1);n(x=>[...x,m])}},[n]),u=R.useCallback(async(p,d)=>{const g=p.trim().toLowerCase();if(g==="dutycycle_start"){l();let m=null,x=null;for(let k=0;k<2;k++)try{m=await it.requestTelemetry(d,"");break}catch(N){x=N instanceof Error?N:new Error("Unknown error"),k===0&&await new Promise(C=>setTimeout(C,2e3))}if(!m){const k=$s(d,`Failed to start duty cycle tracking after retry: ${(x==null?void 0:x.message)??"Unknown error"}`,!1);return n(N=>[...N,k]),!0}const A=Math.floor(Date.now()/1e3);s.current={startTime:A,uptime:m.uptime_seconds,txAirtime:m.airtime_seconds,rxAirtime:m.rx_airtime_seconds,sentFlood:m.sent_flood,sentDirect:m.sent_direct,recvFlood:m.recv_flood,recvDirect:m.recv_direct,conversationId:d};const w=$s(d,`Airtime/duty cycle statistics gathering begins at ${A}. Logs will follow every 5 minutes. To stop, run dutycycle_stop or navigate away from this conversation.`,!1);return n(k=>[...k,w]),i.current=window.setInterval(c,Ly),!0}if(g==="dutycycle_stop"){if(s.current&&s.current.conversationId===d){await c(),l();const m=$s(d,"Airtime/duty cycle statistics gathering stopped.",!1);n(x=>[...x,m])}else{const m=$s(d,"Duty cycle tracking is not active.",!1);n(x=>[...x,m])}return!0}return!1},[n,l,c]);return R.useEffect(()=>()=>{i.current!==null&&clearInterval(i.current)},[]),{handleAirtimeCommand:u,stopTracking:l}}function ru(n){if(n<60)return`${n}s`;const s=Math.floor(n/86400),i=Math.floor(n%86400/3600),l=Math.floor(n%3600/60);return s>0?i>0&&l>0?`${s}d${i}h${l}m`:i>0?`${s}d${i}h`:l>0?`${s}d${l}m`:`${s}d`:i>0?l>0?`${i}h${l}m`:`${i}h`:`${l}m`}function jy(n){return["Telemetry",`Battery Voltage: ${n.battery_volts.toFixed(3)}V`,`Uptime: ${ru(n.uptime_seconds)}`,...n.clock_output?[`Clock: ${n.clock_output}`]:[],`TX Airtime: ${ru(n.airtime_seconds)}`,`RX Airtime: ${ru(n.rx_airtime_seconds)}`,"",`Noise Floor: ${n.noise_floor_dbm} dBm`,`Last RSSI: ${n.last_rssi_dbm} dBm`,`Last SNR: ${n.last_snr_db.toFixed(1)} dB`,"",`Packets: ${n.packets_received.toLocaleString()} rx / ${n.packets_sent.toLocaleString()} tx`,`Flood: ${n.recv_flood.toLocaleString()} rx / ${n.sent_flood.toLocaleString()} tx`,`Direct: ${n.recv_direct.toLocaleString()} rx / ${n.sent_direct.toLocaleString()} tx`,`Duplicates: ${n.flood_dups.toLocaleString()} flood / ${n.direct_dups.toLocaleString()} direct`,"",`TX Queue: ${n.tx_queue_len}`,`Debug Flags: ${n.full_events}`].join(`
`)}function zy(n){if(n.length===0)return`Neighbors
No neighbors reported`;const s=[...n].sort((l,c)=>c.snr-l.snr),i=[`Neighbors (${s.length})`];for(const l of s){const c=l.name||l.pubkey_prefix,u=l.snr>=0?`+${l.snr.toFixed(1)}`:l.snr.toFixed(1);i.push(`${c}, ${u} dB [${ru(l.last_heard_seconds)} ago]`)}return i.join(`
`)}function Hy(n){if(n.length===0)return`ACL
No ACL entries`;const s=[`ACL (${n.length})`];for(const i of n){const l=i.name||i.pubkey_prefix;s.push(`${l}: ${i.permission_name}`)}return s.join(`
`)}function Go(n,s,i,l=0){const c=Math.floor(Date.now()/1e3);return{id:-Date.now()-l,type:"PRIV",conversation_key:n,text:s,sender_timestamp:c,received_at:c,paths:null,txt_type:0,signature:null,outgoing:i,acked:1}}function Vy(n,s,i){const[l,c]=R.useState(!1),{handleAirtimeCommand:u,stopTracking:p}=Oy(i);R.useEffect(()=>{c(!1),p()},[n==null?void 0:n.id,p]);const d=R.useMemo(()=>{if(!n||n.type!=="contact")return!1;const x=s.find(A=>A.public_key===n.id);return(x==null?void 0:x.type)===id},[n,s]),g=R.useCallback(async x=>{if(!(!n||n.type!=="contact")&&d)try{const A=await it.requestTelemetry(n.id,x),w=Go(n.id,jy(A),!1,0),k=Go(n.id,zy(A.neighbors),!1,1),N=Go(n.id,Hy(A.acl),!1,2);i(C=>[...C,w,k,N]),c(!0)}catch(A){const w=Go(n.id,`Telemetry request failed: ${A instanceof Error?A.message:"Unknown error"}`,!1,0);i(k=>[...k,w])}},[n,d,i]),m=R.useCallback(async x=>{if(!n||n.type!=="contact"||!d||!l||await u(x,n.id))return;const w=Go(n.id,`> ${x}`,!0,0);i(k=>[...k,w]);try{const k=await it.sendRepeaterCommand(n.id,x),N=Go(n.id,k.response,!1,1);k.sender_timestamp&&(N.sender_timestamp=k.sender_timestamp),i(C=>[...C,N])}catch(k){const N=Go(n.id,`Command failed: ${k instanceof Error?k.message:"Unknown error"}`,!1,1);i(C=>[...C,N])}},[n,d,l,i,u]);return{repeaterLoggedIn:l,activeContactIsRepeater:d,handleTelemetryRequest:g,handleRepeaterCommand:m}}const _x="remoteterm-lastMessageTime",wx="remoteterm-sortOrder";let $u={};function om(n){$u={...n}}function sm(){return{...$u}}function n0(n,s){return $u[n]=s,{...$u}}function jr(n,s){return`${n}-${s}`}function Uy(){try{const n=localStorage.getItem(_x);return n?JSON.parse(n):{}}catch{return{}}}function Zy(){try{return localStorage.getItem(wx)==="alpha"?"alpha":"recent"}catch{return"recent"}}function am(){try{localStorage.removeItem(_x),localStorage.removeItem(wx)}catch{}}function lm(n,s){if(!s)return!1;const i=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`@\\[${i}\\]`,"i").test(n)}function Wy(n,s,i,l=null){const[c,u]=R.useState({}),[p,d]=R.useState({}),[g,m]=R.useState(sm),x=R.useRef(l);R.useEffect(()=>{x.current=l},[l]);const A=R.useRef(new Set),w=R.useRef(new Set);R.useEffect(()=>{const S=n.filter(F=>!A.current.has(F.key)),B=s.filter(F=>F.public_key&&!w.current.has(F.public_key));if(S.length===0&&B.length===0)return;S.forEach(F=>A.current.add(F.key)),B.forEach(F=>w.current.add(F.public_key)),(async()=>{const F=[...S.map(M=>({type:"CHAN",conversation_key:M.key})),...B.map(M=>({type:"PRIV",conversation_key:M.public_key}))];if(F.length!==0)try{const H={};for(let Z=0;Z<F.length;Z+=200){const Q=F.slice(Z,Z+200),J=await it.getMessagesBulk(Q,j0);Object.assign(H,J)}const V={},j={},ee={};for(const Z of S){const Q=H[`CHAN:${Z.key}`]||[];if(Q.length>0){const J=jr("channel",Z.key),K=Z.last_read_at||0,oe=Q.filter(G=>!G.outgoing&&G.received_at>K);oe.length>0&&(V[J]=oe.length,oe.some(G=>lm(G.text,x.current))&&(j[J]=!0));const ge=Math.max(...Q.map(G=>G.received_at));ee[J]=ge,n0(J,ge)}}for(const Z of B){const Q=H[`PRIV:${Z.public_key}`]||[];if(Q.length>0){const J=jr("contact",Z.public_key),K=Z.last_read_at||0,oe=Q.filter(G=>!G.outgoing&&G.received_at>K);oe.length>0&&(V[J]=oe.length,oe.some(G=>lm(G.text,x.current))&&(j[J]=!0));const ge=Math.max(...Q.map(G=>G.received_at));ee[J]=ge,n0(J,ge)}}Object.keys(V).length>0&&u(Z=>({...Z,...V})),Object.keys(j).length>0&&d(Z=>({...Z,...j})),m(sm())}catch(M){console.error("Failed to fetch messages bulk:",M)}})()},[n,s]),R.useEffect(()=>{if(i&&i.type!=="raw"&&i.type!=="map"){const S=jr(i.type,i.id);u(B=>{if(B[S]){const T={...B};return delete T[S],T}return B}),d(B=>{if(B[S]){const T={...B};return delete T[S],T}return B}),i.type==="channel"?it.markChannelRead(i.id).catch(B=>{console.error("Failed to mark channel as read on server:",B)}):i.type==="contact"&&it.markContactRead(i.id).catch(B=>{console.error("Failed to mark contact as read on server:",B)})}},[i]);const k=R.useCallback((S,B)=>{u(T=>({...T,[S]:(T[S]||0)+1})),B&&d(T=>({...T,[S]:!0}))},[]),N=R.useCallback(()=>{u({}),d({}),it.markAllRead().catch(S=>{console.error("Failed to mark all as read on server:",S)})},[]),C=R.useCallback(S=>{if(S.type==="raw"||S.type==="map")return;const B=jr(S.type,S.id);u(T=>{if(T[B]){const F={...T};return delete F[B],F}return T}),d(T=>{if(T[B]){const F={...T};return delete F[B],F}return T}),S.type==="channel"?it.markChannelRead(S.id).catch(T=>{console.error("Failed to mark channel as read on server:",T)}):S.type==="contact"&&it.markContactRead(S.id).catch(T=>{console.error("Failed to mark contact as read on server:",T)})},[]),b=R.useCallback(S=>{let B=null;if(S.type==="CHAN"&&S.conversation_key?B=jr("channel",S.conversation_key):S.type==="PRIV"&&S.conversation_key&&(B=jr("contact",S.conversation_key)),B){const T=S.received_at||Math.floor(Date.now()/1e3),F=n0(B,T);m(F)}},[]);return{unreadCounts:c,mentions:p,lastMessageTimes:g,incrementUnread:k,markAllRead:N,markConversationRead:C,trackNewMessage:b}}var z0=yx();const bx=aa(z0);function qy(n){if(typeof document>"u")retur Line truncated
* @license lucide-react v0.562.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const __=n=>n.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),w_=n=>n.replace(/^([A-Z])|[\s-_]+(\w)/g,(s,i,l)=>l?l.toUpperCase():i.toLowerCase()),dm=n=>{const s=w_(n);return s.charAt(0).toUpperCase()+s.slice(1)},Cx=(...n)=>n.filter((s,i,l)=>!!s&&s.trim()!==""&&l.indexOf(s)===i).join(" ").trim(),b_=n=>{for(const s in n)if(s.startsWith("aria-")||s==="role"||s==="title")return!0};/**
* @license lucide-react v0.562.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/var C_={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};/**
* @license lucide-react v0.562.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const E_=R.forwardRef(({color:n="currentColor",size:s=24,strokeWidth:i=2,absoluteStrokeWidth:l,className:c="",children:u,iconNode:p,...d},g)=>R.createElement("svg",{ref:g,...C_,width:s,height:s,stroke:n,strokeWidth:l?Number(i)*24/Number(s):i,className:Cx("lucide",c),...!u&&!b_(d)&&{"aria-hidden":"true"},...d},[...p.map(([m,x])=>R.createElement(m,x)),...Array.isArray(u)?u:[u]]));/**
* @license lucide-react v0.562.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const H0=(n,s)=>{const i=R.forwardRef(({className:l,...c},u)=>R.createElement(E_,{ref:u,iconNode:s,className:Cx(`lucide-${__(dm(n))}`,`lucide-${n}`,l),...c}));return i.displayName=dm(n),i};/**
* @license lucide-react v0.562.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const k_=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],S_=H0("check",k_);/**
* @license lucide-react v0.562.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const B_=[["path",{d:"M4 5h16",key:"1tepv9"}],["path",{d:"M4 12h16",key:"1lakjw"}],["path",{d:"M4 19h16",key:"1djgab"}]],P_=H0("menu",B_);/**
* @license lucide-react v0.562.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const T_=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],Ex=H0("x",T_);function D_({health:n,config:s,onSettingsClick:i,onMenuClick:l}){const c=(n==null?void 0:n.radio_connected)??!1,[u,p]=R.useState(!1),d=async()=>{p(!0);try{const g=await it.reconnectRadio();g.connected&&xt.success("Reconnected",{description:g.message})}catch(g){xt.error("Reconnection failed",{description:g instanceof Error?g.message:"Check radio connection and power"})}finally{p(!1)}};return _.jsxs("div",{className:"flex items-center gap-4 px-4 py-2 bg-[#252525] border-b border-[#333] text-xs",children:[l&&_.jsx("button",{onClick:l,className:"md:hidden p-1 bg-transparent border-none text-[#e0e0e0] cursor-pointer","aria-label":"Open menu",children:_.jsx(P_,{className:"h-5 w-5"})}),_.jsx("h1",{className:"text-base font-semibold mr-auto",children:"RemoteTerm"}),_.jsxs("div",{className:"flex items-center gap-1 text-[#888]",children:[_.jsx("div",{className:`w-2 h-2 rounded-full ${c?"bg-[#4caf50]":"bg-[#666]"}`}),_.jsx("span",{className:"hidden lg:inline text-[#e0e0e0]",children:c?"Connected":"Disconnected"})]}),s&&_.jsxs("div",{className:"hidden lg:flex items-center gap-2 text-[#888]",children:[_.jsx("span",{className:"text-[#e0e0e0]",children:s.name||"Unnamed"}),_.jsx("span",{className:"font-mono text-[#888] cursor-pointer hover:text-[#4a9eff]",onClick:()=>{navigator.clipboard.writeText(s.public_key),xt.success("Public key copied!")},title:"Click to copy public key",children:s.public_key.toLowerCase()})]}),!c&&_.jsx("button",{onClick:d,disabled:u,className:"px-3 py-1 bg-[#4a3000] border border-[#6b4500] text-[#ffa500] rounded text-xs cursor-pointer hover:bg-[#5a3a00] disabled:opacity-50 disabled:cursor-not-allowed",children:u?"Reconnecting...":"Reconnect"}),_.jsxs("button",{onClick:i,className:"px-3 py-1 bg-[#333] border border-[#444] text-[#e0e0e0] rounded text-xs cursor-pointer hover:bg-[#444]",children:[_.jsx("span",{role:"img","aria-label":"Settings",children:"🔧"})," ","Radio & Config"]})]})}const R_=12;function N_(n){return n.slice(0,R_)}function Ri(n,s){return n||N_(s)}const na=2,F_={text:"🛜",background:"#444444",textColor:"#ffffff"};function L_(n){let s=0;for(let i=0;i<n.length;i++){const l=n.charCodeAt(i);s=(s<<5)-s+l,s=s&s}return Math.abs(s)}const M_=/[\u{1F1E0}-\u{1F1FF}]{2}|[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]|[\u{1F600}-\u{1F64F}]|[\u{1F680}-\u{1F6FF}]/u;function I_(n,s){if(!n)return s.slice(0,2).toUpperCase();const i=n.match(M_);if(i)return i[0];const l=n.match(/[a-zA-Z]/g);if(!l||l.length===0)return s.slice(0,2).toUpperCase();const c=n.indexOf(" ");if(c!==-1){const u=l[0],p=n.slice(c+1).match(/[a-zA-Z]/);if(p)return(u+p[0]).toUpperCase()}return l[0].toUpperCase()}function O_(n){const s=L_(n),i=s%360,l=50+(s>>8)%30,c=35+(s>>16)%20,u=`hsl(${i}, ${l}%, ${c}%)`,p=c<45?"#ffffff":"#000000";return{background:u,text:p}}function j_(n,s,i){if(i===na)return F_;const l=I_(n,s),c=O_(s);return{text:l,background:c.background,textColor:c.text}}function y0({name:n,publicKey:s,size:i=28,contactType:l}){const c=j_(n,s,l);return _.jsx("div",{className:"flex items-center justify-center rounded-full font-semibold flex-shrink-0 select-none",style:{backgroundColor:c.background,color:c.textColor,width:i,height:i,fontSize:i*.45},children:c.text})}const kx="remoteterm-favorites";function ts(n,s,i){return n.some(l=>l.type===s&&l.id===i)}function z_(){try{const n=localStorage.getItem(kx);return n?JSON.parse(n):[]}catch{return[]}}function fm(){try{localStorage.removeItem(kx)}catch{}}function Sx(n){var s,i,l="";if(typeof n=="string"||typeof n=="number")l+=n;else if(typeof n=="object")if(Array.isArray(n)){var c=n.length;for(s=0;s<c;s++)n[s]&&(i=Sx(n[s]))&&(l&&(l+=" "),l+=i)}else for(i in n)n[i]&&(l&&(l+=" "),l+=i);return l}function Bx(){for(var n,s,i=0,l="",c=arguments.length;i<c;i++)(n=arguments[i])&&(s=Sx(n))&&(l&&(l+=" "),l+=s);return l}const H_=(n,s)=>{const i=new Array(n.length+s.length);for(let l=0;l<n.length;l++)i[l]=n[l];for(let l=0;l<s.length;l++)i[n.length+l]=s[l];return i},V_=(n,s)=>({classGroupId:n,validator:s}),Px=(n=new Map,s=null,i)=>({nextPart:n,validators:s,classGroupId:i}),Ku="-",hm=[],U_="arbitrary..",Z_=n=>{const s=q_(n),{conflictingClassGroups:i,conflictingClassGroupModifiers:l}=n;return{getClassGroupId:p=>{if(p.startsWith("[")&&p.endsWith("]"))return W_(p);const d=p.split(Ku),g=d[0]===""&&d.length>1?1:0;return Tx(d,g,s)},getConflictingClassGroupIds:(p,d)=>{if(d){const g=l[p],m=i[p];return g?m?H_(m,g):g:m||hm}return i[p]||hm}}},Tx=(n,s,i)=>{if(n.length-s===0)return i.classGroupId;const c=n[s],u=i.nextPart.get(c);if(u){const m=Tx(n,s+1,u);if(m)return m}const p=i.validators;if(p===null)return;const d=s===0?n.join(Ku):n.slice(s).join(Ku),g=p.length;for(let m=0;m<g;m++){const x=p[m];if(x.validator(d))return x.classGroupId}},W_=n=>n.slice(1,-1).indexOf(":")===-1?void 0:(()=>{const s=n.slice(1,-1),i=s.indexOf(":"),l=s.slice(0,i);return l?U_+l:void 0})(),q_=n=>{const{theme:s,classLine truncated
.`.concat(Bw,` {
overflow: hidden `).concat(l,`;
padding-right: `).concat(d,"px ").concat(l,`;
}
body[`).concat(ea,`] {
overflow: hidden `).concat(l,`;
overscroll-behavior: contain;
`).concat([s&&"position: relative ".concat(l,";"),i==="margin"&&`
padding-left: `.concat(c,`px;
padding-top: `).concat(u,`px;
padding-right: `).concat(p,`px;
margin-left:0;
margin-top:0;
margin-right: `).concat(d,"px ").concat(l,`;
`),i==="padding"&&"padding-right: ".concat(d,"px ").concat(l,";")].filter(Boolean).join(""),`
}
.`).concat(ou,` {
right: `).concat(d,"px ").concat(l,`;
}
.`).concat(su,` {
margin-right: `).concat(d,"px ").concat(l,`;
}
.`).concat(ou," .").concat(ou,` {
right: 0 `).concat(l,`;
}
.`).concat(su," .").concat(su,` {
margin-right: 0 `).concat(l,`;
}
body[`).concat(ea,`] {
`).concat(Pw,": ").concat(d,`px;
}
`)},Tm=function(){var n=parseInt(document.body.getAttribute(ea)||"0",10);return isFinite(n)?n:0},$w=function(){R.useEffect(function(){return document.body.setAttribute(ea,(Tm()+1).toString()),function(){var n=Tm()-1;n<=0?document.body.removeAttribute(ea):document.body.setAttribute(ea,n.toString())}},[])},Kw=function(n){var s=n.noRelative,i=n.noImportant,l=n.gapMode,c=l===void 0?"margin":l;$w();var u=R.useMemo(function(){return Ww(c)},[c]);return R.createElement(qw,{styles:Gw(u,!s,c,i?"":"!important")})},b0=!1;if(typeof window<"u")try{var Qc=Object.defineProperty({},"passive",{get:function(){return b0=!0,!0}});window.addEventListener("test",Qc,Qc),window.removeEventListener("test",Qc,Qc)}catch{b0=!1}var Qs=b0?{passive:!1}:!1,Qw=function(n){return n.tagName==="TEXTAREA"},Xx=function(n,s){if(!(n instanceof Element))return!1;var i=window.getComputedStyle(n);return i[s]!=="hidden"&&!(i.overflowY===i.overflowX&&!Qw(n)&&i[s]==="visible")},Yw=function(n){return Xx(n,"overflowY")},Xw=function(n){return Xx(n,"overflowX")},Dm=function(n,s){var i=s.ownerDocument,l=s;do{typeof ShadowRoot<"u"&&l instanceof ShadowRoot&&(l=l.host);var c=Jx(n,l);if(c){var u=eA(n,l),p=u[1],d=u[2];if(p>d)return!0}l=l.parentNode}while(l&&l!==i.body);return!1},Jw=function(n){var s=n.scrollTop,i=n.scrollHeight,l=n.clientHeight;return[s,i,l]},eb=function(n){var s=n.scrollLeft,i=n.scrollWidth,l=n.clientWidth;return[s,i,l]},Jx=function(n,s){return n==="v"?Yw(s):Xw(s)},eA=function(n,s){return n==="v"?Jw(s):eb(s)},tb=function(n,s){return n==="h"&&s==="rtl"?-1:1},nb=function(n,s,i,l,c){var u=tb(n,window.getComputedStyle(s).direction),p=u*l,d=i.target,g=s.contains(d),m=!1,x=p>0,A=0,w=0;do{if(!d)break;var k=eA(n,d),N=k[0],C=k[1],b=k[2],S=C-b-u*N;(N||S)&&Jx(n,d)&&(A+=S,w+=N);var B=d.parentNode;d=B&&B.nodeType===Node.DOCUMENT_FRAGMENT_NODE?B.host:B}while(!g&&d!==document.body||g&&(s.contains(d)||s===d));return(x&&Math.abs(A)<1||!x&&Math.abs(w)<1)&&(m=!0),m},Yc=function(n){return"changedTouches"in n?[n.changedTouches[0].clientX,n.changedTouches[0].clientY]:[0,0]},Rm=function(n){return[n.deltaX,n.deltaY]},Nm=function(n){return n&&"current"in n?n.current:n},rb=function(n,s){return n[0]===s[0]&&n[1]===s[1]},ib=function(n){return`
.block-interactivity-`.concat(n,` {pointer-events: none;}
.allow-interactivity-`).concat(n,` {pointer-events: all;}
`)},ob=0,Ys=[];function sb(n){var s=R.useRef([]),i=R.useRef([0,0]),l=R.useRef(),c=R.useState(ob++)[0],u=R.useState(Yx)[0],p=R.useRef(n);R.useEffect(function(){p.current=n},[n]),R.useEffect(function(){if(n.inert){document.body.classList.add("block-interactivity-".concat(c));var C=Sw([n.lockRef.current],(n.shards||[]).map(Nm),!0).filter(Boolean);return C.forEach(function(b){return b.classList.add("allow-interactivity-".concat(c))}),function(){document.body.classList.remove("block-interactivity-".concat(c)),C.forEach(function(b){return b.classList.remove("allow-interactivity-".concat(c))})}}},[n.inert,n.lockRef.current,n.shards]);var d=R.useCallback(function(C,b){if("touches"in C&&C.touches.length===2||C.type==="wheel"&&C.ctrlKey)return!p.current.allowPinchZoom;var S=Yc(C),B=i.current,T="deltaX"in C?C.deltaX:B[0]-S[0],F="deltaY"in C?C.deltaY:B[1]-S[1],M,H=C.target,V=Math.abs(T)>Math.abs(F)?"h":"v";if("touches"in C&&V==="h"&&H.type==="range")return!1;var j=window.getSelection(),ee=j&&j.anchorNode,Z=ee?ee===H||ee.contains(H):!1;if(Z)return!1;var Q=Dm(V,H);if(!Q)return!0;if(Q?M=V:(M=V==="v"?"h":"v",Q=Dm(V,H)),!Q)return!1;if(!l.current&&"changedTouches"in C&&(T||F)&&(l.current=M),!M)return!0;var J=l.current||M;return nb(J,b,C,J==="h"?T:F)},[]),g=R.useCallback(function(C){var b=C;if(!(!Ys.length||Ys[Ys.length-1]!==u)){var S="deltaY"in b?Rm(b):Yc(b),B=s.current.filter(function(M){return M.name===b.type&&(M.target===b.target||b.target===M.shadowParent)&&rb(M.delta,S)})[0];if(B&&B.should){b.cancelable&&b.preventDefault();return}if(!B){var T=(p.current.shards||[]).map(Nm).filter(Boolean).filter(function(M){return M.contains(b.target)}),F=T.length>0?d(b,T[0]):!p.current.noIsolation;F&&b.cancelable&&b.preventDefault()}}},[]),m=R.useCallback(function(C,b,S,B){var T={name:C,delta:b,target:S,should:B,shadowParent:ab(S)};s.current.push(T),setTimeout(function(){s.current=s.current.filter(function(F){return F!==T})},1)},[]),x=R.useCallback(function(C){i.current=Yc(C),l.current=void 0},[]),A=R.useCallback(function(C){m(C.type,Rm(C),C.target,d(C,n.lockRef.current))},[]),w=R.useCallback(function(C){m(C.type,Yc(C),C.target,d(C,n.lockRef.current))},[]);R.useEffect(function(){return Ys.push(u),n.setCallbacks({onScrollCapture:A,onWheelCapture:A,onTouchMoveCapture:w}),document.addEventListener("wheel",g,Qs),document.addEventListener("touchmove",g,Qs),document.addEventListener("touchstart",x,Qs),function(){Ys=Ys.filter(function(C){return C!==u}),document.removeEventListener("wheel",g,Qs),document.removeEventListener("touchmove",g,Qs),document.removeEventListener("touchstart",x,Qs)}},[]);var k=n.removeScrollBar,N=n.inert;return R.createElement(R.Fragment,null,N?R.createElement(u,{styles:ib(c)}):null,k?R.createElement(Kw,{noRelative:n.noRelative,gapMode:n.gapMode}):null)}function ab(n){for(var s=null;n!==null;)n instanceof ShadowRoot&&(s=n.host,n=n.host),n=n.parentNode;return s}const lb=Mw(Qx,sb);var tA=R.forwardRef(function(n,s){return R.createElement(sd,ii({},n,{ref:s,sideCar:lb}))});tA.classNames=sd.classNames;var cb=function(n){if(typeof document>"u")return null;var s=Array.isArray(n)?n[0]:n;return s.ownerDocument.body},Xs=new WeakMap,Xc=new WeakMap,Jc={},d0=0,nA=function(n){return n&&(n.host||nA(n.parentNode))},ub=function(n,s){return s.map(function(i){if(n.contains(i))return i;var l=nA(i);return l&&n.contains(l)?l:(console.error("aria-hidden",i,"in not contained inside",n,". Doing nothing"),null)}).filter(function(i){return!!i})},db=function(n,s,i,l){var c=ub(s,Array.isArray(n)?n:[n]);Jc[i]||(Jc[i]=new WeakMap);var u=Jc[i],p=[],d=new Set,g=new Set(c),m=function(A){!A||d.has(A)||(d.add(A),m(A.parentNode))};c.forEach(m);var x=function(A){!A||g.has(A)||Array.prototype.forEach.call(A.children,function(w){if(d.has(w))x(w);else try{var k=w.getAttribute(l),N=k!==null&&k!=="false",C=(Xs.get(w)||0)+1,b=(u.get(w)||0)+1;Xs.set(w,C),u.set(w,b),p.push(w),C===1&&N&&Xc.set(w,!0),b===1&&w.setAttribute(i,"true"),N||w.setAttribute(l,"true")}catch(S){console.error("aria-hidden: cannot operate on ",w,S)}})};return x(s),d.clear(),d0++,function(){p.forEach(function(A){var w=Xs.get(A)-1,k=u.get(A)-1;Xs.set(A,w),u.set(A,k),w||(Xc.has(A)||A.removeAttribute(l),Xc.delete(A)),k||A.removeAttribute(i)}),d0--,d0||(Xs=new WeakMap,Xs=new WeakMap,Xc=new WeakMap,Jc={})}},fb=function(n,s,i){i===void 0&&(i="data-aria-hidden");var l=Array.from(Array.isArray(n)?n:[n]),c=cb(n);return c?(l.push.apply(l,Array.from(c.querySelectorAll("[aria-live], script"))),db(l,c,i,"aria-hidden")):function(){return null}};function hb(n){const s=pb(n),i=R.forwardRef((l,c)=>{const{children:u,...p}=l,d=R.Children.toArray(u),g=d.find(gb);if(g){const m=g.props.children,x=d.map(A=>A===g?R.Children.count(m)>1?R.Children.only(null):R.isValidElement(m)?m.props.children:null:A);return _.jsx(s,{...p,ref:c,children:R.isValidElement(m)?R.cloneElement(m,void 0,x):null})}return _.jsx(s,{...p,ref:c,children:u})});return i.displayName=`${n}.Slot`,i}function pb(n){const s=R.forwardRef((i,l)=>{const{childr Line truncated
If you want to hide the \`${s.titleName}\`, you can wrap it with our VisuallyHidden component.
For more information, see https://radix-ui.com/primitives/docs/components/${s.docsSlug}`;return R.useEffect(()=>{n&&(document.getElementById(n)||console.error(i))},[i,n]),null},Sb="DialogDescriptionWarning",Bb=({contentRef:n,descriptionId:s})=>{const l=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${xA(Sb).contentName}}.`;return R.useEffect(()=>{var u;const c=(u=n.current)==null?void 0:u.getAttribute("aria-describedby");s&&c&&(document.getElementById(s)||console.warn(l))},[l,n,s]),null},AA=iA,vA=aA,ld=lA,cd=cA,ud=dA,dd=hA,yA=mA;const $0=AA,Pb=vA,_A=R.forwardRef(({className:n,...s},i)=>_.jsx(ld,{ref:i,className:ut("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",n),...s}));_A.displayName=ld.displayName;const fd=R.forwardRef(({className:n,children:s,...i},l)=>_.jsxs(Pb,{children:[_.jsx(_A,{}),_.jsxs(cd,{ref:l,className:ut("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",n),...i,children:[s,_.jsxs(yA,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",children:[_.jsx(Ex,{className:"h-4 w-4"}),_.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));fd.displayName=cd.displayName;const hd=({className:n,...s})=>_.jsx("div",{className:ut("flex flex-col space-y-1.5 text-center sm:text-left",n),...s});hd.displayName="DialogHeader";const K0=({className:n,...s})=>_.jsx("div",{className:ut("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",n),...s});K0.displayName="DialogFooter";const pd=R.forwardRef(({className:n,...s},i)=>_.jsx(ud,{ref:i,className:ut("text-lg font-semibold leading-none tracking-tight",n),...s}));pd.displayName=ud.displayName;const md=R.forwardRef(({className:n,...s},i)=>_.jsx(dd,{ref:i,className:ut("text-sm text-muted-foreground",n),...s}));md.displayName=dd.displayName;function Tb(){const n=window.location.hash.slice(1);if(!n)return null;if(n==="raw")return{type:"raw",name:"raw"};if(n==="map")return{type:"map",name:"map"};if(n==="visualizer")return{type:"visualizer",name:"visualizer"};if(n.startsWith("map/focus/")){const c=n.slice(10);return c?{type:"map",name:"map",mapFocusKey:decodeURIComponent(c)}:{type:"map",name:"map"}}const s=n.indexOf("/");if(s===-1)return null;const i=n.slice(0,s),l=decodeURIComponent(n.slice(s+1));return(i==="channel"||i==="contact")&&l?{type:i,name:l}:null}function wA(n){return`#map/focus/${encodeURIComponent(n)}`}function Db(n){if(!n)return"";if(n.type==="raw")return"#raw";if(n.type==="map")return"#map";if(n.type==="visualizer")return"#visualizer";const s=n.type==="channel"&&n.name.startsWith("#")?n.name.slice(1):n.name;return`#${n.type}/${encodeURIComponent(s)}`}function Rb(n){const s=Db(n);s!==window.location.hash&&window.history.replaceState(null,"",s||window.location.pathname)}function Nb({open:n,onClose:s,paths:i,senderInfo:l,contacts:c,config:u}){const p=i.map(g=>({...g,resolved:Z1(g.path,l,c,u)})),d=i.length===1;return _.jsx($0,{open:n,onOpenChange:g=>!g&&s(),children:_.jsxs(fd,{className:"max-w-md max-h-[80vh] flex flex-col",children:[_.jsxs(hd,{children:[_.jsxs(pd,{children:["Message Path",!d&&`s (${i.length})`]}),_.jsx(md,{children:d?_.jsxs(_.Fragment,{children:["This shows ",_.jsx("em",{children:"one route"})," that this message traveled through the mesh network. Routers may be incorrectly identified due to prefix collisions between heard and non-heard router advertisements."]}):_.jsxs(_.Fragment,{children:["This message was received via ",_.jsxs("strong",{children:[i.length," different routes"]}),". Routers may be incorrectly identified due to prefix collisions."]})})]}),_.jsxs("div",{className:"flex-1 overflow-y-auto py-2 space-y-4",children:[p.map((g,m)=>_.jsxs("div",{children:[!d&&_.jsxs("div",{className:"text-xs text-muted-foreground font-medium mb-2 pb-1 border-b border-border",children:["Path ",m+1," — received ",ra(g.received_at)]}),_.jsx(Fb,{resolved:g.resolved,senderInfo:l,hideStraightLine:!d})]},m)),!d&&p.length>0&&(()=>{const g=p[0].resolved;return Bt(g.sender.lat,g.sender.lon)&&Bt(g.receiver.lat,g.receiver.lon)?_.jsxs("div",{className:"pt-3 mt-1 border-t border-border",children:[_.jsx("span",{className:"text-sm text-muted-foreground",children:"Straight-line distance: "}),_.jsx("span",{className:"text-sm font-medium",c Line truncated
`).map(($,ue,pe)=>_.jsxs("span",{children:[Ib($,d),ue<pe.length-1&&_.jsx("br",{})]},ue)),!ne&&_.jsxs(_.Fragment,{children:[_.jsx("span",{className:"text-[10px] text-muted-foreground/50 ml-2",children:ra(j.sender_timestamp||j.received_at)}),!j.outgoing&&j.paths&&j.paths.length>0&&_.jsx(Im,{paths:j.paths,variant:"inline",onClick:()=>C({paths:j.paths,senderInfo:M(j,Z,J)})})]}),j.outgoing&&(j.acked>0?` ✓${j.acked>1?j.acked:""}`:" ?")]})]})]},j.id)})]}),w&&_.jsx("button",{onClick:B,className:"absolute bottom-4 right-4 w-10 h-10 rounded-full bg-muted hover:bg-accent border border-border flex items-center justify-center shadow-lg transition-opacity",title:"Scroll to bottom",children:_.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"text-muted-foreground",children:_.jsx("polyline",{points:"6 9 12 15 18 9"})})}),N&&_.jsx(Nb,{open:!0,onClose:()=>C(null),paths:N.paths,senderInfo:N.senderInfo,contacts:s,config:g??null})]})}const Om=156,jb=140,zb=156,Hb=120,Vb=8,Ub=R.forwardRef(function({onSend:s,disabled:i,placeholder:l,isRepeaterMode:c,conversationType:u,senderName:p},d){const[g,m]=R.useState(""),[x,A]=R.useState(!1),w=R.useRef(null);R.useImperativeHandle(d,()=>({appendText:M=>{var H;m(V=>V+M),(H=w.current)==null||H.focus()}}));const k=R.useMemo(()=>{if(u==="contact")return{warningAt:jb,dangerAt:Om,hardLimit:Om};if(u==="channel"){const M=(p==null?void 0:p.length)??10,H=Math.max(1,zb-M-2);return{warningAt:Hb,dangerAt:Math.max(1,H-Vb),hardLimit:H}}return null},[u,p]),{limitState:N,warningMessage:C}=R.useMemo(()=>{if(!k)return{limitState:"normal",warningMessage:null};const M=g.length;return M>=k.hardLimit?{limitState:"error",warningMessage:"likely truncated by radio"}:M>=k.dangerAt?{limitState:"danger",warningMessage:"may impact multi-repeater hop delivery"}:M>=k.warningAt?{limitState:"warning",warningMessage:"may impact multi-repeater hop delivery"}:{limitState:"normal",warningMessage:null}},[g.length,k]),b=k?k.hardLimit-g.length:0,S=R.useCallback(async M=>{M.preventDefault();const H=g.trim();if(c){if(x||i)return;A(!0);try{await s(H),m("")}catch(V){console.error("Failed to request telemetry:",V),xt.error("Failed to request telemetry",{description:V instanceof Error?V.message:"Check radio connection"});return}finally{A(!1)}setTimeout(()=>{var V;return(V=w.current)==null?void 0:V.focus()},0)}else{if(!H||x||i)return;A(!0);try{await s(H),m("")}catch(V){console.error("Failed to send message:",V),xt.error("Failed to send message",{description:V instanceof Error?V.message:"Check radio connection"});return}finally{A(!1)}setTimeout(()=>{var V;return(V=w.current)==null?void 0:V.focus()},0)}},[g,x,i,s,c]),B=R.useCallback(M=>{M.key==="Enter"&&!M.shiftKey&&(M.preventDefault(),S(M))},[S]),T=c?!0:g.trim().length>0,F=!c&&k!==null;return _.jsxs("form",{className:"px-4 py-3 border-t border-border flex flex-col gap-1",onSubmit:S,children:[_.jsxs("div",{className:"flex gap-2",children:[_.jsx(Xt,{ref:w,type:c?"password":"text",autoComplete:c?"off":void 0,value:g,onChange:M=>m(M.target.value),onKeyDown:B,placeholder:l||(c?"Enter password for admin login...":"Type a message..."),disabled:i||x,className:"flex-1 min-w-0"}),_.jsx(Jt,{type:"submit",disabled:i||x||!T,className:"flex-shrink-0",children:x?c?"Logging in...":"Sending...":c?g.trim()?"Log in with password":"Log in as guest/use repeater ACLs":"Send"})]}),F&&_.jsxs("div",{className:"flex items-center justify-end gap-2 text-xs",children:[_.jsxs("span",{className:ut("tabular-nums",N==="error"||N==="danger"?"text-red-500 font-medium":N==="warning"?"text-yellow-500":"text-muted-foreground"),children:[g.length,"/",k.hardLimit,b<0&&` (${b})`]}),C&&_.jsxs("span",{className:ut(N==="error"?"text-red-500":"text-yellow-500"),children:["— ",C]})]})]})});function jm(n){const s=Zb(n),i=R.forwardRef((l,c)=>{const{children:u,...p}=l,d=R.Children.toArray(u),g=d.find(qb);if(g){const m=g.props.children,x=d.map(A=>A===g?R.Children.count(m)>1?R.Children.only(null):R.isValidElement(m)?m.props.children:null:A);return _.jsx(s,{...p,ref:c,children:R.isValidElement(m)?R.cloneElement(m,void 0,x):null})}return _.jsx(s,{...p,ref:c,children:u})});return i.displayName=`${n}.Slot`,i}function Zb(n){const s=R.forwardRef((i,l)=>{const{children:c,...u}=i;if(R.isValidElement(c)){const p=$b(c),d=Gb(u,c.props);return c.type!==R.Fragment&&(d.ref=l?El(l,p):p),R.cloneElement(c,d)}return R.Children.count(c)>1?R.Children.only(null):null});return s.displayName=`${n}.SlotClone`,s}var Wb=Symbol("radix.slottable");function qb(n){return R.isValidElement(n)&&typeof n.type=="function"&&"__radixId"in n.type&&n.type.__radixId===Wb}function Gb(n,s){const i={...s};for(const l in s){const c=n[l],u=s[l];/^on[A-Z]/.test(l)?c&&u?i[l]=(...d)=>{const g=u(...d);return c(...d),g}:c&&(i[l]=c):l==="style"?i[l]={...c,...u}:l==="className"&&(i[l]=[c,u].filter(Boolean).join(" "))}return{...n,...i}}function Line truncated
sender_name: str | None,
sender_key: str | None,
message_text: str,
is_dm: bool,
channel_key: str | None,
channel_name: str | None,
sender_timestamp: int | None,
path: str | None,
) -> str | list[str] | None:
"""
Process incoming messages and optionally return a reply.
Args:
sender_name: Display name of sender (may be None)
sender_key: 64-char hex public key (None for channel msgs)
message_text: The message content
is_dm: True for direct messages, False for channel
channel_key: 32-char hex key for channels, None for DMs
channel_name: Channel name with hash (e.g. "#bot"), None for DMs
sender_timestamp: Sender's timestamp (unix seconds, may be None)
path: Hex-encoded routing path (may be None)
Returns:
None for no reply, a string for a single reply,
or a list of strings to send multiple messages in order
"""
# Example: Only respond in #bot channel to "!pling" command
if channel_name == "#bot" and "!pling" in message_text.lower():
return "[BOT] Plong!"
return None`,[Je,st]=R.useState([]),[Ge,$e]=R.useState(null),[et,Oe]=R.useState(null),[wt,It]=R.useState("");R.useEffect(()=>{s&&(C(s.name),S(String(s.lat)),T(String(s.lon)),M(String(s.tx_power)),V(String(s.radio.freq)),ee(String(s.radio.bw)),Q(String(s.radio.sf)),K(String(s.radio.cr)))},[s]),R.useEffect(()=>{l&&(ae(String(l.max_radio_contacts)),Ee(l.auto_decrypt_dm_on_advert),ot(String(l.advert_interval)),st(l.bots||[]))},[l]),R.useEffect(()=>{n&&A()},[n,A]);const Nn=R.useMemo(()=>{const se=parseFloat(H),Te=parseFloat(j),pt=parseInt(Z,10),Ft=parseInt(J,10);for(const nn of h0)if(nn.freq===se&&nn.bw===Te&&nn.sf===pt&&nn.cr===Ft)return nn.name;return"custom"},[H,j,Z,J]),Ot=se=>{if(se==="custom")return;const Te=h0.find(pt=>pt.name===se);Te&&(V(String(Te.freq)),ee(String(Te.bw)),Q(String(Te.sf)),K(String(Te.cr)))},en=()=>{if(!navigator.geolocation){xt.error("Geolocation not supported",{description:"Your browser does not support geolocation"});return}ue(!0),navigator.geolocation.getCurrentPosition(se=>{S(se.coords.latitude.toFixed(6)),T(se.coords.longitude.toFixed(6)),ue(!1),xt.success("Location updated")},se=>{ue(!1),xt.error("Failed to get location",{description:se.message})},{enableHighAccuracy:!0,timeout:1e4})},sn=async()=>{Ae(""),ne(!0);try{const se={lat:parseFloat(b),lon:parseFloat(B),tx_power:parseInt(F,10),radio:{freq:parseFloat(H),bw:parseFloat(j),sf:parseInt(Z,10),cr:parseInt(J,10)}};await u(se),xt.success("Radio config saved, rebooting..."),ne(!1),D(!0),await g(),c()}catch(se){Ae(se instanceof Error?se.message:"Failed to save"),ne(!1)}finally{D(!1)}},yn=async()=>{Ae(""),ne(!0);try{await u({name:N});const Te=parseInt(Ue,10);!isNaN(Te)&&Te!==(l==null?void 0:l.advert_interval)&&await p({advert_interval:Te}),xt.success("Identity settings saved")}catch(se){Ae(se instanceof Error?se.message:"Failed to save")}finally{ne(!1)}},Ht=async()=>{Ae(""),ne(!0);try{const se=parseInt(G,10);!isNaN(se)&&se!==(l==null?void 0:l.max_radio_contacts)&&await p({max_radio_contacts:se}),xt.success("Serial settings saved")}catch(se){Ae(se instanceof Error?se.message:"Failed to save")}finally{ne(!1)}},Pt=async()=>{if(!oe.trim()){Ae("Private key is required");return}Ae(""),ne(!0);try{await d(oe.trim()),ge(""),xt.success("Private key set, rebooting..."),ne(!1),D(!0),await g(),c()}catch(se){Ae(se instanceof Error?se.message:"Failed to set private key"),ne(!1)}finally{D(!1)}},Vt=async()=>{if(confirm("Are you sure you want to reboot the radio? The connection will drop temporarily.")){Ae(""),D(!0);try{await g(),c()}catch(se){Ae(se instanceof Error?se.message:"Failed to reboot radio")}finally{D(!1)}}},Fn=async()=>{q(!0);try{await m()}finally{q(!1)}},pn=async()=>{const se=parseInt(me,10);if(isNaN(se)||se<1){xt.error("Invalid retention days",{description:"Retention days must be at least 1"});return}We(!0);try{const Te=await it.runMaintenance(se);xt.success("Database cleanup complete",{description:`Deleted ${Te.packets_deleted} old packet${Te.packets_deleted===1?"":"s"}`}),await x()}catch(Te){console.error("Failed to run maintenance:",Te),xt.error("Database cleanup failed",{description:Te instanceof Error?Te.message:"Unknown error"})}finally{We(!1)}},ve=async()=>{ne(!0),Ae("");try{await p({auto_decrypt_dm_on_advert:Ke}),xt.success("Database settings saved")}catch(se){console.error("Failed to save database settings:",se),Ae(se instanceof Error?se.message:"Failed to save"),xt.error("Failed to save settings")}finally{ne(!1)}},ke=async()=>{ne(!0),Ae("");try{await p({bots:Je}),xt.success("Bot settings saved")}catch(se){console.error("Failed to save bot settings:",se);const Te=se instanceof Error?se.message:"Failed to save";Ae(Te),xt.error(Te)}finally{ne(!1)}},Fe=()=>{const se={id:crypto.randomUUID(),name:`Bot ${Je.length+1}`,enabled:!1,code:ht};st([...Je,se]),$e(se.id)},lt=se=>{const Te=Je.find(pt=>pt.id===se);Te&&Te.code.trim()&&Te.code!==ht&&!confirm(`Delete "${Te.name}"? This will remove all its code.`)||(st(Je.filter(pt=>pt.id!==se)),Ge===se&&$e(null))},re=se=>{st(Je.map(Te=>Te.id===se?{...Te,enabled:!Te.enabled}:Te))},ye=(se,Te)=>{st(Je.map(pt=>pt.id===se?{...pt,code:Te}:pt))},_e=se=>{Oe(se.id),It(se.name)},Re=()=>{et&&wt.trim()&&st(Je.map(se=>se.id===et?{...se,name:wt.trim()}:se)),Oe(null),It("")},ft=se=>{st(Je.map(Te=>Te.id===se?{...Te,code:ht}:Te))};return _.jsx($0,{open:n,onOpenChange:se=>!se&&c(),children:_.jsxs(fd,{className:"sm:max-w-[50vw] sm:min-w-[500px] max-h-[90vh] overflow-y-auto",children:[_.jsxs(hd,{children:[_.jsx(pd,{children:"Radio & Settings"}),_.jsxs(md,{className:"sr-only",children:[w==="radio"&&"Configure radio frequency, power, and location settings",w==="identity"&&"Manage radio name, public key, private key, and advertising settings",w==="serial"&&"View serial port connection and configure contact sync",w==="database"&&"View database statistics and clean up old packets",w==="bot"&&"Configure automatic message bot with Python code"]})]}),s?_.jsxs(Y0,{value:w,onValueChange:se=>k(se),className:"w-full",children:[ Line truncated
(c) 2012 by Cédric Mesnil. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/return(function(l){var c=i,u=c.lib,p=u.WordArray,d=u.Hasher,g=c.algo,m=p.create([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8,3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12,1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2,4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13]),x=p.create([5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12,6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2,15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13,8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14,12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11]),A=p.create([11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6]),w=p.create([8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]),k=p.create([0,1518500249,1859775393,2400959708,2840853838]),N=p.create([1352829926,1548603684,1836072691,2053994217,0]),C=g.RIPEMD160=d.extend({_doReset:function(){this._hash=p.create([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(H,V){for(var j=0;j<16;j++){var ee=V+j,Z=H[ee];H[ee]=(Z<<8|Z>>>24)&16711935|(Z<<24|Z>>>8)&4278255360}var Q=this._hash.words,J=k.words,K=N.words,oe=m.words,ge=x.words,G=A.words,ae=w.words,W,ne,U,D,z,q,$,ue,pe,Ae;q=W=Q[0],$=ne=Q[1],ue=U=Q[2],pe=D=Q[3],Ae=z=Q[4];for(var me,j=0;j<80;j+=1)me=W+H[V+oe[j]]|0,j<16?me+=b(ne,U,D)+J[0]:j<32?me+=S(ne,U,D)+J[1]:j<48?me+=B(ne,U,D)+J[2]:j<64?me+=T(ne,U,D)+J[3]:me+=F(ne,U,D)+J[4],me=me|0,me=M(me,G[j]),me=me+z|0,W=z,z=D,D=M(U,10),U=ne,ne=me,me=q+H[V+ge[j]]|0,j<16?me+=F($,ue,pe)+K[0]:j<32?me+=T($,ue,pe)+K[1]:j<48?me+=B($,ue,pe)+K[2]:j<64?me+=S($,ue,pe)+K[3]:me+=b($,ue,pe)+K[4],me=me|0,me=M(me,ae[j]),me=me+Ae|0,q=Ae,Ae=pe,pe=M(ue,10),ue=$,$=me;me=Q[1]+U+pe|0,Q[1]=Q[2]+D+Ae|0,Q[2]=Q[3]+z+q|0,Q[3]=Q[4]+W+$|0,Q[4]=Q[0]+ne+ue|0,Q[0]=me},_doFinalize:function(){var H=this._data,V=H.words,j=this._nDataBytes*8,ee=H.sigBytes*8;V[ee>>>5]|=128<<24-ee%32,V[(ee+64>>>9<<4)+14]=(j<<8|j>>>24)&16711935|(j<<24|j>>>8)&4278255360,H.sigBytes=(V.length+1)*4,this._process();for(var Z=this._hash,Q=Z.words,J=0;J<5;J++){var K=Q[J];Q[J]=(K<<8|K>>>24)&16711935|(K<<24|K>>>8)&4278255360}return Z},clone:function(){var H=d.clone.call(this);return H._hash=this._hash.clone(),H}});function b(H,V,j){return H^V^j}function S(H,V,j){return H&V|~H&j}function B(H,V,j){return(H|~V)^j}function T(H,V,j){return H&j|V&~j}function F(H,V,j){return H^(V|~j)}function M(H,V){return H<<V|H>>>32-V}c.RIPEMD160=d._createHelper(C),c.HmacRIPEMD160=d._createHmacHelper(C)})(),i.RIPEMD160})})(_u)),_u.exports}var wu={exports:{}},tC=wu.exports,og;function yd(){return og||(og=1,(function(n,s){(function(i,l){n.exports=l(vt())})(tC,function(i){(function(){var l=i,c=l.lib,u=c.Base,p=l.enc,d=p.Utf8,g=l.algo;g.HMAC=u.extend({init:function(m,x){m=this._hasher=new m.init,typeof x=="string"&&(x=d.parse(x));var A=m.blockSize,w=A*4;x.sigBytes>w&&(x=m.finalize(x)),x.clamp();for(var k=this._oKey=x.clone(),N=this._iKey=x.clone(),C=k.words,b=N.words,S=0;S<A;S++)C[S]^=1549556828,b[S]^=909522486;k.sigBytes=N.sigBytes=w,this.reset()},reset:function(){var m=this._hasher;m.reset(),m.update(this._iKey)},update:function(m){return this._hasher.update(m),this},finalize:function(m){var x=this._hasher,A=x.finalize(m);x.reset();var w=x.finalize(this._oKey.clone().concat(A));return w}})})()})})(wu)),wu.exports}var bu={exports:{}},nC=bu.exports,sg;function rC(){return sg||(sg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),Bl(),yd())})(nC,function(i){return(function(){var l=i,c=l.lib,u=c.Base,p=c.WordArray,d=l.algo,g=d.SHA256,m=d.HMAC,x=d.PBKDF2=u.extend({cfg:u.extend({keySize:128/32,hasher:g,iterations:25e4}),init:function(A){this.cfg=this.cfg.extend(A)},compute:function(A,w){for(var k=this.cfg,N=m.create(k.hasher,A),C=p.create(),b=p.create([1]),S=C.words,B=b.words,T=k.keySize,F=k.iterations;S.length<T;){var M=N.update(w).finalize(b);N.reset();for(var H=M.words,V=H.length,j=M,ee=1;ee<F;ee++){j=N.finalize(j),N.reset();for(var Z=j.words,Q=0;Q<V;Q++)H[Q]^=Z[Q]}C.concat(M),B[0]++}return C.sigBytes=T*4,C}});l.PBKDF2=function(A,w,k){return x.create(k).compute(A,w)}})(),i.PBKDF2})})(bu)),bu.exports}var Cu={exports:{}},iC=Cu.exports,ag;function yo(){return ag||(ag=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),tv(),yd())})(iC,function(i){return(function(){var l=i,c=l.lib,u=c.Base,p=c.WordArray,d=l.algo,g=d.MD5,m=d.EvpKDF=u.extend({cfg:u.extend({keySize:128/32,hasher:g,iterations:1}),init:function(x){this.cfg=this.cfg.extend(x)},compute:function(x,A){for(var w,k=this.cfg,N=k.hasher.create(),C=p.create(),b=C.words,S=k.keySize,B=k.iterations;b.length<S;){w&&N.update(w),w=N.update(x).finalize(A),N.reset();for(var T=1;T<B;T++)w=N.finalize(w),N.reset();C.concat(w)}return C.sigBytes=S*4,C}});l.EvpKDF=function(x,A,w){return m.create(w).compute(x,A)}})(),i.EvpKDF})})(Cu)),Cu.exports}var Eu={exports:{}},oC=Eu.exports,lg;Line truncated
* Counter block mode compatible with Dr Brian Gladman fileenc.c
* derived from CryptoJS.mode.CTR
* Jan Hruby jhruby.web@gmail.com
*/return i.mode.CTRGladman=(function(){var l=i.lib.BlockCipherMode.extend();function c(d){if((d>>24&255)===255){var g=d>>16&255,m=d>>8&255,x=d&255;g===255?(g=0,m===255?(m=0,x===255?x=0:++x):++m):++g,d=0,d+=g<<16,d+=m<<8,d+=x}else d+=1<<24;return d}function u(d){return(d[0]=c(d[0]))===0&&(d[1]=c(d[1])),d}var p=l.Encryptor=l.extend({processBlock:function(d,g){var m=this._cipher,x=m.blockSize,A=this._iv,w=this._counter;A&&(w=this._counter=A.slice(0),this._iv=void 0),u(w);var k=w.slice(0);m.encryptBlock(k,0);for(var N=0;N<x;N++)d[g+N]^=k[N]}});return l.Decryptor=p,l})(),i.mode.CTRGladman})})(Bu)),Bu.exports}var Pu={exports:{}},fC=Pu.exports,fg;function hC(){return fg||(fg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(fC,function(i){return i.mode.OFB=(function(){var l=i.lib.BlockCipherMode.extend(),c=l.Encryptor=l.extend({processBlock:function(u,p){var d=this._cipher,g=d.blockSize,m=this._iv,x=this._keystream;m&&(x=this._keystream=m.slice(0),this._iv=void 0),d.encryptBlock(x,0);for(var A=0;A<g;A++)u[p+A]^=x[A]}});return l.Decryptor=c,l})(),i.mode.OFB})})(Pu)),Pu.exports}var Tu={exports:{}},pC=Tu.exports,hg;function mC(){return hg||(hg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(pC,function(i){return i.mode.ECB=(function(){var l=i.lib.BlockCipherMode.extend();return l.Encryptor=l.extend({processBlock:function(c,u){this._cipher.encryptBlock(c,u)}}),l.Decryptor=l.extend({processBlock:function(c,u){this._cipher.decryptBlock(c,u)}}),l})(),i.mode.ECB})})(Tu)),Tu.exports}var Du={exports:{}},gC=Du.exports,pg;function xC(){return pg||(pg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(gC,function(i){return i.pad.AnsiX923={pad:function(l,c){var u=l.sigBytes,p=c*4,d=p-u%p,g=u+d-1;l.clamp(),l.words[g>>>2]|=d<<24-g%4*8,l.sigBytes+=d},unpad:function(l){var c=l.words[l.sigBytes-1>>>2]&255;l.sigBytes-=c}},i.pad.Ansix923})})(Du)),Du.exports}var Ru={exports:{}},AC=Ru.exports,mg;function vC(){return mg||(mg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(AC,function(i){return i.pad.Iso10126={pad:function(l,c){var u=c*4,p=u-l.sigBytes%u;l.concat(i.lib.WordArray.random(p-1)).concat(i.lib.WordArray.create([p<<24],1))},unpad:function(l){var c=l.words[l.sigBytes-1>>>2]&255;l.sigBytes-=c}},i.pad.Iso10126})})(Ru)),Ru.exports}var Nu={exports:{}},yC=Nu.exports,gg;function _C(){return gg||(gg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(yC,function(i){return i.pad.Iso97971={pad:function(l,c){l.concat(i.lib.WordArray.create([2147483648],1)),i.pad.ZeroPadding.pad(l,c)},unpad:function(l){i.pad.ZeroPadding.unpad(l),l.sigBytes--}},i.pad.Iso97971})})(Nu)),Nu.exports}var Fu={exports:{}},wC=Fu.exports,xg;function bC(){return xg||(xg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(wC,function(i){return i.pad.ZeroPadding={pad:function(l,c){var u=c*4;l.clamp(),l.sigBytes+=u-(l.sigBytes%u||u)},unpad:function(l){for(var c=l.words,u=l.sigBytes-1,u=l.sigBytes-1;u>=0;u--)if(c[u>>>2]>>>24-u%4*8&255){l.sigBytes=u+1;break}}},i.pad.ZeroPadding})})(Fu)),Fu.exports}var Lu={exports:{}},CC=Lu.exports,Ag;function EC(){return Ag||(Ag=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(CC,function(i){return i.pad.NoPadding={pad:function(){},unpad:function(){}},i.pad.NoPadding})})(Lu)),Lu.exports}var Mu={exports:{}},kC=Mu.exports,vg;function SC(){return vg||(vg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),vn())})(kC,function(i){return(function(l){var c=i,u=c.lib,p=u.CipherParams,d=c.enc,g=d.Hex,m=c.format;m.Hex={stringify:function(x){return x.ciphertext.toString(g)},parse:function(x){var A=g.parse(x);return p.create({ciphertext:A})}}})(),i.format.Hex})})(Mu)),Mu.exports}var Iu={exports:{}},BC=Iu.exports,yg;function PC(){return yg||(yg=1,(function(n,s){(function(i,l,c){n.exports=l(vt(),ss(),as(),yo(),vn())})(BC,function(i){return(function(){var l=i,c=l.lib,u=c.BlockCipher,p=l.algo,d=[],g=[],m=[],x=[],A=[],w=[],k=[],N=[],C=[],b=[];(function(){for(var T=[],F=0;F<256;F++)F<128?T[F]=F<<1:T[F]=F<<1^283;for(var M=0,H=0,F=0;F<256;F++){var V=H^H<<1^H<<2^H<<3^H<<4;V=V>>>8^V&255^99,d[M]=V,g[V]=M;var j=T[M],ee=T[j],Z=T[ee],Q=T[V]*257^V*16843008;m[M]=Q<<24|Q>>>8,x[M]=Q<<16|Q>>>16,A[M]=Q<<8|Q>>>24,w[M]=Q;var Q=Z*16843009^ee*65537^j*257^M*16843008;k[V]=Q<<24|Q>>>8,N[V]=Q<<16|Q>>>16,C[V]=Q<<8|Q>>>24,b[V]=Q,M?(M=j^T[T[T[Z^j]]],H^=T[T[H]]):M=H=1}})();var S=[0,1,2,4,8,16,32,64,128,27,54],B=p.AES=u.extend({_doReset:function(){var T;if(!(this._nRounds&&this._keyPriorReset===this._key)){for(var F=this._keyPriorReset=this._key,M=F.words,H=F.sigBytes/4,V=this._nRounds=H+6,j=(V+1)*4,ee=this._keySchedule=[],Z=0;Z<j;Z++)Z<H?ee[Z]=M[Z]:(T=ee[Z-1],Z%H?H>6&&Z%H==4&&(T=d[T>>>24]<<24|d[T>>>16&255]<<16|d[T>>>8&255]<<8|d[T&255]):(T=T<<8|T>>>24,T=d[T>>>24]<<24|d[T>>>16&255]<<16|d[T>>>8&255]<<8|d[T&255],T^=S[Z/H|0]<<24),ee[Z]=ee[Z-H]^T);for(var Q=this._invKeySchedule=[],J=0;J<j;J++){var Z=j-J;if(J%4)var T=ee[Z];else var T=ee[Z-4];J<4||Z<=4?Q[J]=T:Q[J]=k[d[T>>>24]]^N[d[T>>>16&255]]^C[d[T>>>8&255]]^b[d[T&255]]}}},encLine truncated
• Timestamp (4 bytes) - send time as unix timestamp
• Request Type (1 byte) - type of request (GetStats, GetTelemetryData, etc.)
• Request Data (remaining bytes) - additional request-specific data`,startByte:d+g,endByte:d+c.length-1,value:w});const k={type:n.PayloadType.Request,version:n.PayloadVersion.Version1,isValid:!0,timestamp:0,requestType:n.RequestType.GetStats,requestData:"",destinationHash:m,sourceHash:x,cipherMac:A,ciphertext:w};return u!=null&&u.includeSegments&&(k.segments=p),k}catch(p){return{type:n.PayloadType.Request,version:n.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode request payload"],timestamp:0,requestType:n.RequestType.GetStats,requestData:"",destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:""}}}}return ll.RequestPayloadDecoder=i,ll}var cl={},Ug;function dE(){if(Ug)return cl;Ug=1,Object.defineProperty(cl,"__esModule",{value:!0}),cl.ResponsePayloadDecoder=void 0;const n=dr(),s=Cn();class i{static decode(c,u){try{if(c.length<4){const N={type:n.PayloadType.Response,version:n.PayloadVersion.Version1,isValid:!1,errors:["Response payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return u!=null&&u.includeSegments&&(N.segments=[{name:"Invalid Response Data",description:"Response payload too short (minimum 4 bytes required)",startByte:u.segmentOffset||0,endByte:(u.segmentOffset||0)+c.length-1,value:(0,s.bytesToHex)(c)}]),N}const p=[],d=(u==null?void 0:u.segmentOffset)||0;let g=0;const m=(0,s.byteToHex)(c[g]);u!=null&&u.includeSegments&&p.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:d+g,endByte:d+g,value:m}),g+=1;const x=(0,s.byteToHex)(c[g]);u!=null&&u.includeSegments&&p.push({name:"Source Hash",description:"First byte of source node public key",startByte:d+g,endByte:d+g,value:x}),g+=1;const A=(0,s.bytesToHex)(c.subarray(g,g+2));u!=null&&u.includeSegments&&p.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:d+g,endByte:d+g+1,value:A}),g+=2;const w=(0,s.bytesToHex)(c.subarray(g));u!=null&&u.includeSegments&&c.length>g&&p.push({name:"Ciphertext",description:"Encrypted response data (tag + content)",startByte:d+g,endByte:d+c.length-1,value:w});const k={type:n.PayloadType.Response,version:n.PayloadVersion.Version1,isValid:!0,destinationHash:m,sourceHash:x,cipherMac:A,ciphertext:w,ciphertextLength:c.length-4};return u!=null&&u.includeSegments&&(k.segments=p),k}catch(p){return{type:n.PayloadType.Response,version:n.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode response payload"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return cl.ResponsePayloadDecoder=i,cl}var ul={},Zg;function fE(){if(Zg)return ul;Zg=1,Object.defineProperty(ul,"__esModule",{value:!0}),ul.AnonRequestPayloadDecoder=void 0;const n=dr(),s=Cn();class i{static decode(c,u){try{if(c.length<35){const N={type:n.PayloadType.AnonRequest,version:n.PayloadVersion.Version1,isValid:!1,errors:["AnonRequest payload too short (minimum 35 bytes: dest + public key + MAC)"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return u!=null&&u.includeSegments&&(N.segments=[{name:"Invalid AnonRequest Data",description:"AnonRequest payload too short (minimum 35 bytes required: 1 for dest hash + 32 for public key + 2 for MAC)",startByte:u.segmentOffset||0,endByte:(u.segmentOffset||0)+c.length-1,value:(0,s.bytesToHex)(c)}]),N}const p=[],d=(u==null?void 0:u.segmentOffset)||0;let g=0;const m=(0,s.byteToHex)(c[0]);u!=null&&u.includeSegments&&p.push({name:"Destination Hash",description:`First byte of destination node public key: 0x${m}`,startByte:d+g,endByte:d+g,value:m}),g+=1;const x=(0,s.bytesToHex)(c.subarray(1,33));u!=null&&u.includeSegments&&p.push({name:"Sender Public Key",description:"Ed25519 public key of the sender (32 bytes)",startByte:d+g,endByte:d+g+31,value:x}),g+=32;const A=(0,s.bytesToHex)(c.subarray(33,35));u!=null&&u.includeSegments&&p.push({name:"Cipher MAC",description:"MAC for encrypted data verification (2 bytes)",startByte:d+g,endByte:d+g+1,value:A}),g+=2;const w=(0,s.bytesToHex)(c.subarray(35));u!=null&&u.includeSegments&&c.length>35&&p.push({name:"Ciphertext",description:`Encrypted message data (${c.length-35} bytes). Contains encrypted plaintext with this structure:
• Timestamp (4 bytes) - send time as unix timestamp
• Sync Timestamp (4 bytes) - room server only, sender's "sync messages SINCE x" timestamp
• Password (remaining bytes) - password for repeater/room`,startByte:d+g,endByte:d+c.length-1,value:w});const k={type:n.PayloadType.AnonRequest,version:n.PayloadVersion.Version1,isValid:!0,destinationHash:m,senderPublicKey:x,cipherMac:A,ciphertext:w,ciphertextLength:c.length-35};return u!=null&&u.includeSegments&&(k.segments=p),k}catch(p){return{type:n.PayloadType.AnonRequest,version:n.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode AnonRequest payload"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return ul.AnonRequestPayloadDecoder=i,ul}var dl={},Wg;function hE(){if(Wg)return dl;Wg=1,Object.defineProperty(dl,"__esModule",{value:!0}),dl.AckPayloadDecoder=void 0;const n=dr(),s=Cn();class i{static decode(c,u){try{if(c.length<4){const x={type:n.PayloadType.Ack,version:n.PayloadVersion.Version1,isValid:!1,errors:["Ack payload too short (minimum 4 bytes for checksum)"],checksum:""};return u!=null&&u.includeSegments&&(x.segments=[{name:"Invalid Ack Data",description:"Ack payload too short (minimum 4 bytes required for checksum)",startByte:u.segmentOffset||0,endByte:(u.segmentOffset||0)+c.length-1,value:(0,s.bytesToHex)(c)}]),x}const p=[],d=(u==null?void 0:u.segmentOffset)||0,g=(0,s.bytesToHex)(c.subarray(0,4));u!=null&&u.includeSegments&&p.push({name:"Checksum",description:`CRC checksum of message timestamp, text, and sender pubkey: 0x${g}`,startByte:d,endByte:d+3,value:g}),u!=null&&u.includeSegments&&c.length>4&&p.push({name:"Additional Data",description:"Extra data in Ack payload",startByte:d+4,endByte:d+c.length-1,value:(0,s.bytesToHex)(c.subarray(4))});const m={type:n.PayloadType.Ack,version:n.PayloadVersion.Version1,isValid:!0,checksum:g};return u!=null&&u.includeSegments&&(m.segments=p),m}catch(p){return{type:n.PayloadType.Ack,version:n.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode Ack payload"],checksum:""}}}}return dl.AckPayloadDecoder=i,dl}var fl={},qg;function pE(){if(qg)return fl;qg=1,Object.defineProperty(fl,"__esModule",{value:!0}),fl.PathPayloadDecoder=void 0;const n=dr(),s=Cn();class i{static decode(c){try{if(c.length<2)return{type:n.PayloadType.Path,version:n.PayloadVersion.Version1,isValid:!1,errors:["Path payload too short (minimum 2 bytes: path length + extra type)"],pathLength:0,pathHashes:[],extraType:0,extraData:""};const u=c[0];if(c.length<1+u+1)return{type:n.PayloadType.Path,version:n.PayloadVersion.Version1,isValid:!1,errors:[`Path payload too short (need ${1+u+1} bytes for path length + path + extra type)`],pathLength:u,pathHashes:[],extraType:0,extraData:""};const p=[];for(let m=0;m<u;m++)p.push((0,s.byteToHex)(c[1+m]));const d=c[1+u];let g="";return c.length>1+u+1&&(g=(0,s.bytesToHex)(c.subarray(1+u+1))),{type:n.PayloadType.Path,version:n.PayloadVersion.Version1,isValid:!0,pathLength:u,pathHashes:p,extraType:d,extraData:g}}catch(u){return{type:n.PayloadType.Path,version:n.PayloadVersion.Version1,isValid:!1,errors:[u instanceof Error?u.message:"Failed to decode Path payload"],pathLength:0,pathHashes:[],extraType:0,extraData:""}}}}return fl.PathPayloadDecoder=i,fl}var hl={},Gg;function mE(){if(Gg)return hl;Gg=1,Object.defineProperty(hl,"__esModule",{value:!0}),hl.TextMessagePayloadDecoder=void 0;const n=dr(),s=Cn();class i{static decode(c,u){try{if(c.length<4){const N={type:n.PayloadType.TextMessage,version:n.PayloadVersion.Version1,isValid:!1,errors:["TextMessage payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return u!=null&&u.includeSegments&&(N.segments=[{name:"Invalid TextMessage Data",description:"TextMessage payload too short (minimum 4 bytes required)",startByte:u.segmentOffset||0,endByte:(u.segmentOffset||0)+c.length-1,value:(0,s.bytesToHex)(c)}]),N}const p=[],d=(u==null?void 0:u.segmentOffset)||0;let g=0;const m=(0,s.byteToHex)(c[g]);u!=null&&u.includeSegments&&p.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:d+g,endByte:d+g,value:m}),g+=1;const x=(0,s.byteToHex)(c[g]);u!=null&&u.includeSegments&&p.push({name:"Source Hash",description:"First byte of source node public key",startByte:d+g,endByte:d+g,value:x}),g+=1;const A=(0,s.bytesToHex)(c.subarray(g,g+2));u!=null&&u.includeSegments&&p.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:d+g,endByte:d+g+1,value:A}),g+=2;const w=(0,s.bytesToHex)(c.subarray(g));u!=null&&u.includeSegments&&c.length>g&&p.push({name:"Ciphertext",description:"Encrypted message data (timestamp + message text)",startByte:d+g,endByte:d+c.length-1,value:w});const k={type:n.PayloadType.TextMessage,version:n.PayloadVersion.Version1,isValid:!0,destinationHash:m,sourceHash:x,cipherMac:A,ciphertext:w,ciphertextLength:c.length-4};return u!=null&&u.includeSegments&&(k.segments=p),k}catch(p){return{type:n.PayloadType.TextMessage,version:n.PayloadVersion.Version1,i Line truncated
* Leaflet 1.9.4, a JS library for interactive maps. https://leafletjs.com
* (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade
*/var DE=gl.exports,ex;function RE(){return ex||(ex=1,(function(n,s){(function(i,l){l(s)})(DE,(function(i){var l="1.9.4";function c(t){var o,f,v,P;for(f=1,v=arguments.length;f<v;f++){P=arguments[f];for(o in P)t[o]=P[o]}return t}var u=Object.create||(function(){function t(){}return function(o){return t.prototype=o,new t}})();function p(t,o){var f=Array.prototype.slice;if(t.bind)return t.bind.apply(t,f.call(arguments,1));var v=f.call(arguments,2);return function(){return t.apply(o,v.length?v.concat(f.call(arguments)):arguments)}}var d=0;function g(t){return"_leaflet_id"in t||(t._leaflet_id=++d),t._leaflet_id}function m(t,o,f){var v,P,O,X;return X=function(){v=!1,P&&(O.apply(f,P),P=!1)},O=function(){v?P=arguments:(t.apply(f,arguments),setTimeout(X,o),v=!0)},O}function x(t,o,f){var v=o[1],P=o[0],O=v-P;return t===v&&f?t:((t-P)%O+O)%O+P}function A(){return!1}function w(t,o){if(o===!1)return t;var f=Math.pow(10,o===void 0?6:o);return Math.round(t*f)/f}function k(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}function N(t){return k(t).split(/\s+/)}function C(t,o){Object.prototype.hasOwnProperty.call(t,"options")||(t.options=t.options?u(t.options):{});for(var f in o)t.options[f]=o[f];return t.options}function b(t,o,f){var v=[];for(var P in t)v.push(encodeURIComponent(f?P.toUpperCase():P)+"="+encodeURIComponent(t[P]));return(!o||o.indexOf("?")===-1?"?":"&")+v.join("&")}var S=/\{ *([\w_ -]+) *\}/g;function B(t,o){return t.replace(S,function(f,v){var P=o[v];if(P===void 0)throw new Error("No value provided for variable "+f);return typeof P=="function"&&(P=P(o)),P})}var T=Array.isArray||function(t){return Object.prototype.toString.call(t)==="[object Array]"};function F(t,o){for(var f=0;f<t.length;f++)if(t[f]===o)return f;return-1}var M="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";function H(t){return window["webkit"+t]||window["moz"+t]||window["ms"+t]}var V=0;function j(t){var o=+new Date,f=Math.max(0,16-(o-V));return V=o+f,window.setTimeout(t,f)}var ee=window.requestAnimationFrame||H("RequestAnimationFrame")||j,Z=window.cancelAnimationFrame||H("CancelAnimationFrame")||H("CancelRequestAnimationFrame")||function(t){window.clearTimeout(t)};function Q(t,o,f){if(f&&ee===j)t.call(o);else return ee.call(window,p(t,o))}function J(t){t&&Z.call(window,t)}var K={__proto__:null,extend:c,create:u,bind:p,get lastId(){return d},stamp:g,throttle:m,wrapNum:x,falseFn:A,formatNum:w,trim:k,splitWords:N,setOptions:C,getParamString:b,template:B,isArray:T,indexOf:F,emptyImageUrl:M,requestFn:ee,cancelFn:Z,requestAnimFrame:Q,cancelAnimFrame:J};function oe(){}oe.extend=function(t){var o=function(){C(this),this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()},f=o.__super__=this.prototype,v=u(f);v.constructor=o,o.prototype=v;for(var P in this)Object.prototype.hasOwnProperty.call(this,P)&&P!=="prototype"&&P!=="__super__"&&(o[P]=this[P]);return t.statics&&c(o,t.statics),t.includes&&(ge(t.includes),c.apply(null,[v].concat(t.includes))),c(v,t),delete v.statics,delete v.includes,v.options&&(v.options=f.options?u(f.options):{},c(v.options,t.options)),v._initHooks=[],v.callInitHooks=function(){if(!this._initHooksCalled){f.callInitHooks&&f.callInitHooks.call(this),this._initHooksCalled=!0;for(var O=0,X=v._initHooks.length;O<X;O++)v._initHooks[O].call(this)}},o},oe.include=function(t){var o=this.prototype.options;return c(this.prototype,t),t.options&&(this.prototype.options=o,this.mergeOptions(t.options)),this},oe.mergeOptions=function(t){return c(this.prototype.options,t),this},oe.addInitHook=function(t){var o=Array.prototype.slice.call(arguments,1),f=typeof t=="function"?t:function(){this[t].apply(this,o)};return this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(f),this};function ge(t){if(!(typeof L>"u"||!L||!L.Mixin)){t=T(t)?t:[t];for(var o=0;o<t.length;o++)t[o]===L.Mixin.Events&&console.warn("Deprecated include of L.Mixin.Events: this property will be removed in future releases, please inherit from L.Evented instead.",new Error().stack)}}var G={on:function(t,o,f){if(typeof t=="object")for(var v in t)this._on(v,t[v],o);else{t=N(t);for(var P=0,O=t.length;P<O;P++)this._on(t[P],o,f)}return this},off:function(t,o,f){if(!arguments.length)delete this._events;else if(typeof t=="object")for(var v in t)this._off(v,t[v],o);else{t=N(t);for(var P=arguments.length===1,O=0,X=t.length;O<X;O++)P?this._off(t[O]):this._off(t[O],o,f)}return this},_on:function(t,o,f,v){if(typeof o!="function"){console.warn("wrong listener type: "+typeof o);return}if(this._listens(t,o,f)===!1){f===this&&(f=void 0);var P={fn:o,ctx:f};v&&(P.once=!0),this._events=this._events||{},this._events[t]=this._events[t]||[],this._events[t].push(P)}},_off:function(t,o,f){var v,P,O;if(this._events&&(v=this._events[t],!!v)){if(arguments.length===1){if(this._firingCount)for(P=0,O=v.length;P<O;P++)v[P].fn=A;delete this._events[t];return}if(typeof o!="function"){console.warn("wrong listener type: "+typeof o);return}var X=thisLine truncated
// SHA256 round constants
const K: array<u32, 64> = array<u32, 64>(
0x428a2f98u, 0x71374491u, 0xb5c0fbcfu, 0xe9b5dba5u, 0x3956c25bu, 0x59f111f1u, 0x923f82a4u, 0xab1c5ed5u,
0xd807aa98u, 0x12835b01u, 0x243185beu, 0x550c7dc3u, 0x72be5d74u, 0x80deb1feu, 0x9bdc06a7u, 0xc19bf174u,
0xe49b69c1u, 0xefbe4786u, 0x0fc19dc6u, 0x240ca1ccu, 0x2de92c6fu, 0x4a7484aau, 0x5cb0a9dcu, 0x76f988dau,
0x983e5152u, 0xa831c66du, 0xb00327c8u, 0xbf597fc7u, 0xc6e00bf3u, 0xd5a79147u, 0x06ca6351u, 0x14292967u,
0x27b70a85u, 0x2e1b2138u, 0x4d2c6dfcu, 0x53380d13u, 0x650a7354u, 0x766a0abbu, 0x81c2c92eu, 0x92722c85u,
0xa2bfe8a1u, 0xa81a664bu, 0xc24b8b70u, 0xc76c51a3u, 0xd192e819u, 0xd6990624u, 0xf40e3585u, 0x106aa070u,
0x19a4c116u, 0x1e376c08u, 0x2748774cu, 0x34b0bcb5u, 0x391c0cb3u, 0x4ed8aa4au, 0x5b9cca4fu, 0x682e6ff3u,
0x748f82eeu, 0x78a5636fu, 0x84c87814u, 0x8cc70208u, 0x90befffau, 0xa4506cebu, 0xbef9a3f7u, 0xc67178f2u
);
// Character lookup table (a-z = 0-25, 0-9 = 26-35, dash = 36)
const CHARS: array<u32, 37> = array<u32, 37>(
0x61u, 0x62u, 0x63u, 0x64u, 0x65u, 0x66u, 0x67u, 0x68u, 0x69u, 0x6au, // a-j
0x6bu, 0x6cu, 0x6du, 0x6eu, 0x6fu, 0x70u, 0x71u, 0x72u, 0x73u, 0x74u, // k-t
0x75u, 0x76u, 0x77u, 0x78u, 0x79u, 0x7au, // u-z
0x30u, 0x31u, 0x32u, 0x33u, 0x34u, 0x35u, 0x36u, 0x37u, 0x38u, 0x39u, // 0-9
0x2du // dash
);
struct Params {
target_channel_hash: u32,
batch_offset: u32,
name_length: u32,
batch_size: u32,
target_mac: u32, // First 2 bytes of target MAC (in high 16 bits)
ciphertext_words: u32, // Number of 32-bit words in ciphertext
ciphertext_len_bits: u32, // Length of ciphertext in bits
verify_mac: u32, // 1 to verify MAC, 0 to skip
}
@group(0) @binding(0) var<uniform> params: Params;
@group(0) @binding(1) var<storage, read_write> match_count: atomic<u32>;
@group(0) @binding(2) var<storage, read_write> match_indices: array<u32>;
@group(0) @binding(3) var<storage, read> ciphertext: array<u32>; // Ciphertext data
fn rotr(x: u32, n: u32) -> u32 {
return (x >> n) | (x << (32u - n));
}
fn ch(x: u32, y: u32, z: u32) -> u32 {
return (x & y) ^ (~x & z);
}
fn maj(x: u32, y: u32, z: u32) -> u32 {
return (x & y) ^ (x & z) ^ (y & z);
}
fn sigma0(x: u32) -> u32 {
return rotr(x, 2u) ^ rotr(x, 13u) ^ rotr(x, 22u);
}
fn sigma1(x: u32) -> u32 {
return rotr(x, 6u) ^ rotr(x, 11u) ^ rotr(x, 25u);
}
fn gamma0(x: u32) -> u32 {
return rotr(x, 7u) ^ rotr(x, 18u) ^ (x >> 3u);
}
fn gamma1(x: u32) -> u32 {
return rotr(x, 17u) ^ rotr(x, 19u) ^ (x >> 10u);
}
// Convert index to room name bytes, returns the hash as a u32 for the first byte check
fn index_to_room_name(idx: u32, length: u32, msg: ptr<function, array<u32, 16>>) -> bool {
// Message starts with '#' (0x23)
var byte_pos = 0u;
var word_idx = 0u;
var current_word = 0x23000000u; // '#' in big-endian position 0
byte_pos = 1u;
var remaining = idx;
var prev_was_dash = false;
// Generate room name from index
for (var i = 0u; i < length; i++) {
let char_count = select(37u, 36u, i == 0u || i == length - 1u); // no dash at start/end
var char_idx = remaining % char_count;
remaining = remaining / char_count;
// Check for consecutive dashes (invalid)
let is_dash = char_idx == 36u && i > 0u && i < length - 1u;
if (is_dash && prev_was_dash) {
return false; // Invalid: consecutive dashes
}
prev_was_dash = is_dash;
// Map char index to actual character
let c = CHARS[char_idx];
// Pack byte into current word (big-endian)
let shift = (3u - byte_pos % 4u) * 8u;
if (byte_pos % 4u == 0u && byte_pos > 0u) {
(*msg)[word_idx] = current_word;
word_idx = word_idx + 1u;
current_word = 0u;
}
current_word = current_word | (c << shift);
byte_pos = byte_pos + 1u;
}
// Add padding: 0x80 followed by zeros, then length in bits
let msg_len_bits = (length + 1u) * 8u; // +1 for '#'
// Add 0x80 padding byte
let shift = (3u - byte_pos % 4u) * 8u;
if (byte_pos % 4u == 0u) {
(*msg)[word_idx] = current_word;
word_idx = word_idx + 1u;
current_word = 0x80000000u;
} else {
current_word = current_word | (0x80u << shift);
}
byte_pos = byte_pos + 1u;
// Store current word
if (byte_pos % 4u == 0u || word_idx < 14u) {
(*msg)[word_idx] = current_word;
word_idx = word_idx + 1u;
}
// Zero-fill until word 14
for (var i = word_idx; i < 14u; i++) {
(*msg)[i] = 0u;
}
// Length in bits (64-bit, but we only use lower 32 bits for short messages)
(*msg)[14u] = 0u;
(*msg)[15u] = msg_len_bits;
return true;
}
fn sha256_block(msg: ptr<function, array<u32, 16>>) -> array<u32, 8> {
// Initialize hash values
var h: array<u32, 8> = array<u32, 8>(
0x6a09e667u, 0xbb67ae85u, 0x3c6ef372u, 0xa54ff53au,
0x510e527fu, 0x9b05688cu, 0x1f83d9abu, 0x5be0cd19u
);
// Message schedule
var w: array<u32, 64>;
for (var i = 0u; i < 16u; i++) {
w[i] = (*msg)[i];
}
for (var i = 16u; i < 64u; i++) {
w[i] = gamma1(w[i-2u]) + w[i-7u] + gamma0(w[i-15u]) + w[i-16u];
}
// Compression
var a = h[0]; var b = h[1]; var c = h[2]; var d = h[3];
var e = h[4]; var f = h[5]; var g = h[6]; var hh = h[7];
for (var i = 0u; i < 64u; i++) {
let t1 = hh + sigma1(e) + ch(e, f, g) + K[i] + w[i];
let t2 = sigma0(a) + maj(a, b, c);
hh = g; g = f; f = e; e = d + t1;
d = c; c = b; b = a; a = t1 + t2;
}
h[0] = h[0] + a; h[1] = h[1] + b; h[2] = h[2] + c; h[3] = h[3] + d;
h[4] = h[4] + e; h[5] = h[5] + f; h[6] = h[6] + g; h[7] = h[7] + hh;
return h;
}
// Compute SHA256 of the key (16 bytes) to get channel hash
fn sha256_key(key: array<u32, 4>) -> u32 {
var msg: array<u32, 16>;
// Key bytes (16 bytes = 4 words)
msg[0] = key[0];
msg[1] = key[1];
msg[2] = key[2];
msg[3] = key[3];
// Padding: 0x80 followed by zeros
msg[4] = 0x80000000u;
for (var i = 5u; i < 14u; i++) {
msg[i] = 0u;
}
// Length: 128 bits
msg[14] = 0u;
msg[15] = 128u;
let hash = sha256_block(&msg);
// Return first byte of hash (big-endian)
return hash[0] >> 24u;
}
// HMAC-SHA256 for MAC verification
// Key is 16 bytes (4 words), padded to 32 bytes with zeros for MeshCore
// Returns first 2 bytes of HMAC (as u32 in high 16 bits)
fn hmac_sha256_mac(key: array<u32, 4>, ciphertext_len: u32) -> u32 {
// HMAC: H((K' ^ opad) || H((K' ^ ipad) || message))
// K' is 64 bytes (32 bytes key + 32 bytes zero padding for MeshCore, then padded to 64)
// ipad = 0x36 repeated, opad = 0x5c repeated
// Build padded key (64 bytes = 16 words)
// MeshCore uses 32-byte secret: 16-byte key + 16 zero bytes
var k_pad: array<u32, 16>;
k_pad[0] = key[0];
k_pad[1] = key[1];
k_pad[2] = key[2];
k_pad[3] = key[3];
for (var i = 4u; i < 16u; i++) {
k_pad[i] = 0u;
}
// Inner hash: SHA256((K' ^ ipad) || message)
// First block: K' ^ ipad (64 bytes)
var inner_block: array<u32, 16>;
for (var i = 0u; i < 16u; i++) {
inner_block[i] = k_pad[i] ^ 0x36363636u;
}
// Initialize hash state with first block
var h: array<u32, 8> = sha256_block(&inner_block);
// Process ciphertext blocks (continuing from h state)
let ciphertext_words = params.ciphertext_words;
var word_idx = 0u;
// Process full 64-byte blocks of ciphertext
while (word_idx + 16u <= ciphertext_words) {
var block: array<u32, 16>;
for (var i = 0u; i < 16u; i++) {
block[i] = ciphertext[word_idx + i];
}
h = sha256_block_continue(&block, h);
word_idx = word_idx + 16u;
}
// Final block with remaining ciphertext + padding
var final_block: array<u32, 16>;
var remaining = ciphertext_words - word_idx;
for (var i = 0u; i < 16u; i++) {
if (i < remaining) {
final_block[i] = ciphertext[word_idx + i];
} else if (i == remaining) {
// Add 0x80 padding
final_block[i] = 0x80000000u;
} else {
final_block[i] = 0u;
}
}
// Add length (64 bytes of ipad + ciphertext length)
let total_bits = 512u + params.ciphertext_len_bits;
if (remaining < 14u) {
final_block[14] = 0u;
final_block[15] = total_bits;
h = sha256_block_continue(&final_block, h);
} else {
// Need extra block for length
h = sha256_block_continue(&final_block, h);
var len_block: array<u32, 16>;
for (var i = 0u; i < 14u; i++) {
len_block[i] = 0u;
}
len_block[14] = 0u;
len_block[15] = total_bits;
h = sha256_block_continue(&len_block, h);
}
let inner_hash = h;
// Outer hash: SHA256((K' ^ opad) || inner_hash)
var outer_block: array<u32, 16>;
for (var i = 0u; i < 16u; i++) {
outer_block[i] = k_pad[i] ^ 0x5c5c5c5cu;
}
h = sha256_block(&outer_block);
// Second block: inner_hash (32 bytes) + padding
var hash_block: array<u32, 16>;
for (var i = 0u; i < 8u; i++) {
hash_block[i] = inner_hash[i];
}
hash_block[8] = 0x80000000u;
for (var i = 9u; i < 14u; i++) {
hash_block[i] = 0u;
}
hash_block[14] = 0u;
hash_block[15] = 512u + 256u; // 64 bytes opad + 32 bytes inner hash
h = sha256_block_continue(&hash_block, h);
// Return first 2 bytes (high 16 bits of first word)
return h[0] & 0xFFFF0000u;
}
// SHA256 block computation continuing from existing state
fn sha256_block_continue(msg: ptr<function, array<u32, 16>>, h_in: array<u32, 8>) -> array<u32, 8> {
var h = h_in;
// Message schedule
var w: array<u32, 64>;
for (var i = 0u; i < 16u; i++) {
w[i] = (*msg)[i];
}
for (var i = 16u; i < 64u; i++) {
w[i] = gamma1(w[i-2u]) + w[i-7u] + gamma0(w[i-15u]) + w[i-16u];
}
// Compression
var a = h[0]; var b = h[1]; var c = h[2]; var d = h[3];
var e = h[4]; var f = h[5]; var g = h[6]; var hh = h[7];
for (var i = 0u; i < 64u; i++) {
let t1 = hh + sigma1(e) + ch(e, f, g) + K[i] + w[i];
let t2 = sigma0(a) + maj(a, b, c);
hh = g; g = f; f = e; e = d + t1;
d = c; c = b; b = a; a = t1 + t2;
}
h[0] = h[0] + a; h[1] = h[1] + b; h[2] = h[2] + c; h[3] = h[3] + d;
h[4] = h[4] + e; h[5] = h[5] + f; h[6] = h[6] + g; h[7] = h[7] + hh;
return h;
}
// Process a single candidate and record match if found
fn process_candidate(name_idx: u32) {
// Generate message for this room name
var msg: array<u32, 16>;
let valid = index_to_room_name(name_idx, params.name_length, &msg);
if (!valid) {
return;
}
// Compute SHA256("#roomname") - this gives us the key
let key_hash = sha256_block(&msg);
// Take first 16 bytes (4 words) as the key
var key: array<u32, 4>;
key[0] = key_hash[0];
key[1] = key_hash[1];
key[2] = key_hash[2];
key[3] = key_hash[3];
// Compute SHA256(key) to get channel hash
let channel_hash = sha256_key(key);
// Check if channel hash matches target
if (channel_hash != params.target_channel_hash) {
return;
}
// Channel hash matches - verify MAC if enabled
if (params.verify_mac == 1u) {
let computed_mac = hmac_sha256_mac(key, params.ciphertext_len_bits);
if (computed_mac != params.target_mac) {
return;
}
}
// Found a match - record the index
let match_idx = atomicAdd(&match_count, 1u);
if (match_idx < 1024u) { // Limit stored matches
match_indices[match_idx] = name_idx;
}
}
// Each thread processes 32 candidates to amortize thread overhead
const CANDIDATES_PER_THREAD: u32 = 32u;
@compute @workgroup_size(256)
fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
let base_idx = global_id.x * CANDIDATES_PER_THREAD;
for (var i = 0u; i < CANDIDATES_PER_THREAD; i++) {
let idx = base_idx + i;
if (idx >= params.batch_size) {
return;
}
let name_idx = params.batch_offset + idx;
process_candidate(name_idx);
}
}
`}async init(){if(!navigator.gpu)return console.warn("WebGPU not supported"),!1;try{const s=await navigator.gpu.requestAdapter();if(!s)return console.warn("No GPU adapter found"),!1;this.device=await s.requestDevice(),this.bindGroupLayout=this.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}}]}),this.paramsBuffer=this.device.createBuffer({size:32,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.matchCountBuffer=this.device.createBuffer({size:4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST}),this.matchIndicesBuffer=this.device.createBuffer({size:1024*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC});for(let c=0;c<2;c++)this.matchCountReadBuffers[c]=this.device.createBuffer({size:4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),this.matchIndicesReadBuffers[c]=this.device.createBuffer({size:1024*4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST});const i=this.device.createShaderModule({code:this.shaderCode}),l=this.device.createPipelineLayout({bindGroupLayouts:[this.bindGroupLayout]});return this.pipeline=this.device.createComputePipeline({layout:l,compute:{module:i,entryPoint:"main"}}),!0}catch(s){return console.error("WebGPU initialization failed:",s),!1}}isAvailable(){return this.device!==null&&this.pipeline!==null}indexToRoomName(s,i){return es(i,s)}countNamesForLength(s){return vl(s)}async runBatch(s,i,l,c,u,p){if(!this.device||!this.pipeline||!this.bindGroupLayout||!this.paramsBuffer||!this.matchCountBuffer||!this.matchIndicesBuffer||!this.matchCountReadBuffers[0]||!this.matchCountReadBuffers[1]||!this.matchIndicesReadBuffers[0]||!this.matchIndicesReadBuffers[1])throw new Error("GPU not initialized");const d=this.currentReadBufferIndex;this.currentReadBufferIndex=1-this.currentReadBufferIndex;const g=this.matchCountReadBuffers[d],m=this.matchIndicesReadBuffers[d],x=u&&p?1:0;let A,w=0,k=0;if(x){const M=new Uint8Array(u.length/2);for(let Z=0;Z<M.length;Z++)M[Z]=parseInt(u.substr(Z*2,2),16);w=M.length*8;const H=Math.ceil(M.length/4)*4,V=new Uint8Array(H);V.set(M),A=new Uint32Array(H/4);for(let Z=0;Z<A.length;Z++)A[Z]=V[Z*4]<<24|V[Z*4+1]<<16|V[Z*4+2]<<8|V[Z*4+3];const j=parseInt(p.substr(0,2),16),ee=parseInt(p.substr(2,2),16);k=j<<24|ee<<16}else A=new Uint32Array([0]);const N=Math.max(A.length*4,4);(!this.ciphertextBuffer||this.ciphertextBufferSize<N)&&(this.ciphertextBuffer&&this.ciphertextBuffer.destroy(),this.ciphertextBuffer=this.device.createBuffer({size:N,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.ciphertextBufferSize=N,this.bindGroupDirty=!0);const C=new Uint32Array([s,l,i,c,k,A.length,w,x]);this.device.queue.writeBuffer(this.paramsBuffer,0,C),this.device.queue.writeBuffer(this.ciphertextBuffer,0,A),this.device.queue.writeBuffer(this.matchCountBuffer,0,kd.ZERO_DATA),(this.bindGroupDirty||!this.bindGroup)&&(this.bindGroup=this.device.createBindGroup({layout:this.bindGroupLayout,entries:[{binding:0,resource:{buffer:this.paramsBuffer}},{binding:1,resource:{buffer:this.matchCountBuffer}},{binding:2,resource:{buffer:this.matchIndicesBuffer}},{binding:3,resource:{buffer:this.ciphertextBuffer}}]}),this.bindGroupDirty=!1);const b=this.device.createCommandEncoder(),S=b.beginComputePass();S.setPipeline(this.pipeline),S.setBindGroup(0,this.bindGroup),S.dispatchWorkgroups(Math.ceil(c/(256*32))),S.end(),b.copyBufferToBuffer(this.matchCountBuffer,0,g,0,4),b.copyBufferToBuffer(this.matchIndicesBuffer,0,m,0,1024*4),this.device.queue.submit([b.finish()]),await g.mapAsync(GPUMapMode.READ);const T=new Uint32Array(g.getMappedRange())[0];g.unmap();const F=[];if(T>0){await m.mapAsync(GPUMapMode.READ);const M=new Uint32Array(m.getMappedRange());for(let H=0;H<Math.min(T,1024);H++)F.push(M[H]);m.unmap()}return F}destroy(){var s,i,l,c,u,p,d,g;(s=this.paramsBuffer)==null||s.destroy(),(i=this.matchCountBuffer)==null||i.destroy(),(l=this.matchIndicesBuffer)==null||l.destroy(),(c=this.ciphertextBuffer)==null||c.destroy(),(u=this.matchCountReadBuffers[0])==null||u.destroy(),(p=this.matchCountReadBuffers[1])==null||p.destroy(),(d=this.matchIndicesReadBuffers[0])==null||d.destroy(),(g=this.matchIndicesReadBuffers[1])==null||g.destroy(),this.paramsBuffer=null,this.matchCountBuffer=null,this.matchIndicesBuffer=null,this.ciphertextBuffer=null,this.ciphertextBufferSize=0,this.matchCountReadBuffers=[null,null],this.matchIndicesReadBuffers=[null,null],this.currentReadBufferIndex=0,this.bindGroup=null,this.bindGroupDirty=!0,this.device&&(this.device.destroy(),this.device=null),this.pipeline=null,this.bindGroupLayout=null}}kd.ZERO_DATA=new Uint32Array([0]);function lS(){return typeof navigator<"u"&&"gpu"in navigator}class px{runBatch(s,i,l,c,u,p){const d=[],g=s.toString(16).padStart(2,"0 Line truncated
`).map(u=>u.trim().toLowerCase()).filter(u=>u.length>0);this.wordlist=c.filter(mx)}setWordlist(s){this.wordlist=s.map(i=>i.trim().toLowerCase()).filter(mx)}abort(){this.abortFlag=!0}isGpuAvailable(){return lS()}async decodePacket(s){var l;const i=s.trim().replace(/\s+/g,"").replace(/^0x/i,"");if(!i||!/^[0-9a-fA-F]+$/.test(i))return null;try{const u=(l=(await yt.MeshCorePacketDecoder.decodeWithVerification(i,{})).payload)==null?void 0:l.decoded;return!(u!=null&&u.channelHash)||!(u!=null&&u.ciphertext)||!(u!=null&&u.cipherMac)?null:{channelHash:u.channelHash,ciphertext:u.ciphertext,cipherMac:u.cipherMac,isGroupText:!0}}catch{return null}}async crack(s,i,l){this.abortFlag=!1,this.useTimestampFilter=(i==null?void 0:i.useTimestampFilter)??!0,this.useUtf8Filter=(i==null?void 0:i.useUtf8Filter)??!0,this.useSenderFilter=(i==null?void 0:i.useSenderFilter)??!0,this.validSeconds=(i==null?void 0:i.validSeconds)??F0,this.useCpu=(i==null?void 0:i.forceCpu)??!1;const c=(i==null?void 0:i.maxLength)??8,u=(i==null?void 0:i.startingLength)??1,p=(i==null?void 0:i.useDictionary)??!0,d=(i==null?void 0:i.startFromType)??"bruteforce",g=s.toLowerCase(),m=await this.decodePacket(g);if(!m)return{found:!1,error:"Invalid packet or not a GroupText packet"};const{channelHash:x,ciphertext:A,cipherMac:w}=m,k=parseInt(x,16);this.useCpu?this.cpuInstance||(this.cpuInstance=new px):this.gpuInstance||(this.gpuInstance=new kd,await this.gpuInstance.init()||(this.useCpu=!0,this.cpuInstance=new px));const N=performance.now();let C=0,b=performance.now(),S=u,B=0,T=0,F=!1;if(i!=null&&i.startFrom){const K=i.startFrom.toLowerCase();if(d==="dictionary"){const oe=this.wordlist.indexOf(K);oe>=0&&(T=oe+1)}else{F=!0;const oe=oS(K);oe&&(S=Math.max(u,oe.length),B=oe.index+1,B>=vl(S)&&(S++,B=0))}}let M=0;p&&!F&&this.wordlist.length>0&&(M+=this.wordlist.length-T);for(let K=S;K<=c;K++)M+=vl(K);M-=B;const H=(K,oe,ge)=>{if(!l)return;const ae=(performance.now()-N)/1e3,W=ae>0?Math.round(C/ae):0,ne=M-C,U=W>0?ne/W:0;l({checked:C,total:M,percent:M>0?Math.min(100,C/M*100):0,rateKeysPerSec:W,etaSeconds:U,elapsedSeconds:ae,currentLength:oe,currentPosition:ge,phase:K})},V=K=>{if(!Lv(A,w,K))return{valid:!1};const oe=yt.ChannelCrypto.decryptGroupTextMessage(A,w,K);return!oe.success||!oe.data?{valid:!1}:this.useTimestampFilter&&!sS(oe.data.timestamp,this.validSeconds)?{valid:!1}:this.useUtf8Filter&&!aS(oe.data.message)?{valid:!1}:this.useSenderFilter&&!oe.data.sender?{valid:!1}:{valid:!0,message:oe.data.sender?`${oe.data.sender}: ${oe.data.message}`:oe.data.message}};if(!F&&T===0&&S===u&&B===0){H("public-key",0,N0);const K=M0(Gu);if(x===K){const oe=V(Gu);if(oe.valid)return{found:!0,roomName:N0,key:Gu,decryptedMessage:oe.message}}}if(p&&!F&&this.wordlist.length>0)for(let K=T;K<this.wordlist.length;K++){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:this.wordlist[K],resumeType:"dictionary"};const oe=this.wordlist[K],ge=L0("#"+oe),G=M0(ge);if(parseInt(G,16)===k){const W=V(ge);if(W.valid)return{found:!0,roomName:oe,key:ge,decryptedMessage:W.message,resumeFrom:oe,resumeType:"dictionary"}}C++;const ae=performance.now();ae-b>=200&&(H("wordlist",oe.length,oe),b=ae,await new Promise(W=>setTimeout(W,0)))}const j=this.useCpu?1024:32768,ee=(i==null?void 0:i.gpuDispatchMs)??1e3;let Z=j,Q=!1;for(let K=S;K<=c;K++){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:es(K,0)||void 0,resumeType:"bruteforce"};const oe=vl(K);let ge=K===S?B:0;for(;ge<oe;){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:es(K,ge)||void 0,resumeType:"bruteforce"};const G=Math.min(Z,oe-ge),ae=performance.now();let W;this.useCpu?W=this.cpuInstance.runBatch(k,K,ge,G,A,w):W=await this.gpuInstance.runBatch(k,K,ge,G,A,w);const ne=performance.now()-ae;if(C+=G,!this.useCpu&&!Q&&G>=j&&ne>0){const D=ee/ne,z=Math.round(G*D),q=Math.pow(2,Math.round(Math.log2(Math.max(j,z))));Z=Math.max(j,q),Q=!0}for(const D of W){const z=es(K,D);if(!z)continue;const q=L0("#"+z),$=V(q);if($.valid)return{found:!0,roomName:z,key:q,decryptedMessage:$.message,resumeFrom:z,resumeType:"bruteforce"}}ge+=G;const U=performance.now();if(U-b>=200){const D=es(K,Math.min(ge,oe-1))||"";H("bruteforce",K,D),b=U,await new Promise(z=>setTimeout(z,0))}}}return{found:!1,resumeFrom:es(c,vl(c)-1)||void 0,resumeType:"bruteforce"}}destroy(){this.gpuInstance&&(this.gpuInstance.destroy(),this.gpuInstance=null),this.cpuInstance&&(this.cpuInstance.destroy(),this.cpuInstance=null)}}var x0,gx;function hS(){return gx||(gx=1,x0={webm:"data:video/webm;base64,GkXfowEAAAAAAAAfQoaBAUL3gQFC8oEEQvOBCEKChHdlYm1Ch4EEQoWBAhhTgGcBAAAAAAAVkhFNm3RALE27i1OrhBVJqWZTrIHfTbuMU6uEFlSua1OsggEwTbuMU6uEHFO7a1OsghV17AEAAAAAAACkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmAQAAAAAAAEUq17GDD0JATYCNTGF2ZjU1LjMzLjEwMFdBjUxhdmY1NS4zMy4xMDBzpJBlrrXf3DCDVB8KcgbMpcr+RImIQJBgAAAAAAAWVK5rAQAAAAAAD++uAQAAAAAAADL Line truncated
NoSleep enabled for older iOS devices. This can interrupt
active or long-running network requests from completing successfully.
See https://github.com/richtr/NoSleep.js/issues/15 for more details.
`),this.noSleepTimer=window.setInterval(()=>{document.hidden||(window.location.href=window.location.href.split("#")[0],window.setTimeout(window.stop,0))},15e3),this.enabled=!0,Promise.resolve()):this.noSleepVideo.play().then(d=>(this.enabled=!0,d)).catch(d=>{throw this.enabled=!1,d})}disable(){l()?(this._wakeLock&&this._wakeLock.release(),this._wakeLock=null):i()?this.noSleepTimer&&(console.warn(`
NoSleep now disabled for older iOS devices.
`),window.clearInterval(this.noSleepTimer),this.noSleepTimer=null):this.noSleepVideo.pause(),this.enabled=!1}}return A0=c,A0}var mS=pS();const gS=aa(mS);function xS(n){if(n.length<4)return null;try{const i=parseInt(n.slice(0,2),16)&3;let l=2;if(i===0||i===3){if(n.length<l+8)return null;l+=8}if(n.length<l+2)return null;const c=parseInt(n.slice(l,l+2),16);l+=2;const u=c*2;return n.length<l+u?null:(l+=u,n.slice(l))}catch{return null}}function AS({packets:n,channels:s,onChannelCreate:i,onRunningChange:l,visible:c=!1}){const[u,p]=R.useState(!1),[d,g]=R.useState(6),[m,x]=R.useState(!1),[A,w]=R.useState(!0),[k,N]=R.useState(!1),[C,b]=R.useState(null),[S,B]=R.useState(new Map),[T,F]=R.useState([]),[M,H]=R.useState(!1),[V,j]=R.useState(null),[ee,Z]=R.useState(null),[Q,J]=R.useState(0),K=R.useRef(null),oe=R.useRef(null),ge=R.useRef(!1),G=R.useRef(!1),ae=R.useRef(!1),W=R.useRef(new Map),ne=R.useRef(!1),U=R.useRef(6),D=R.useRef(!0),z=R.useRef(!1),q=R.useRef(new Set),$=R.useRef(new Set);R.useEffect(()=>{const Ee=new fS;K.current=Ee,j(Ee.isGpuAvailable());const Ue=new gS;return oe.current=Ue,()=>{Ee.destroy(),K.current=null,Ue.disable(),oe.current=null}},[]),R.useEffect(()=>{!c||M||XA(async()=>{const{ENGLISH_WORDLIST:Ee}=await import("./wordlist-BtmChKSf.js");return{ENGLISH_WORDLIST:Ee}},[]).then(({ENGLISH_WORDLIST:Ee})=>{K.current&&(K.current.setWordlist(Ee),H(!0))}).catch(Ee=>{console.error("Failed to load wordlist:",Ee),xt.error("Failed to load wordlist",{description:"Cracking will not be available"})})},[c,M]),R.useEffect(()=>{const Ee=()=>{it.getUndecryptedPacketCount().then(({count:ot})=>Z(ot)).catch(()=>Z(null))};Ee();const Ue=setInterval(Ee,36e5);return()=>clearInterval(Ue)},[]);const ue=R.useMemo(()=>new Set(s.map(Ee=>Ee.key.toUpperCase())),[s]),pe=n.filter(Ee=>Ee.payload_type==="GROUP_TEXT"&&!Ee.decrypted);R.useEffect(()=>{let Ee=0;B(Ue=>{const ot=new Map(Ue);let ht=!1;for(const Je of pe)if(!ot.has(Je.id)){const st=xS(Je.data);if(st&&$.current.has(st)){Ee++;continue}st&&$.current.add(st),ot.set(Je.id,{packet:Je,attempts:0,lastAttemptLength:0,status:"pending"}),ht=!0}return ht?(W.current=ot,ot):Ue}),Ee>0&&J(Ue=>Ue+Ee)},[pe.length]),R.useEffect(()=>{W.current=S},[S]),R.useEffect(()=>{ne.current=m},[m]),R.useEffect(()=>{U.current=d},[d]),R.useEffect(()=>{D.current=A},[A]),R.useEffect(()=>{z.current=k},[k]),R.useEffect(()=>{q.current=new Set(pe.map(Ee=>Ee.id))},[pe]),R.useEffect(()=>{l==null||l(u)},[u,l]);const Ae=Array.from(S.values()).filter(Ee=>Ee.status==="pending").length,me=Array.from(S.values()).filter(Ee=>Ee.status==="cracked").length,xe=Array.from(S.values()).filter(Ee=>Ee.status==="failed").length,Be=R.useCallback(async()=>{if(ae.current||!K.current||!ge.current)return;const Ee=W.current;let Ue=null,ot=null;for(const[Ge,$e]of Ee.entries())if($e.status==="pending"){Ue=$e,ot=Ge;break}if(!Ue&&ne.current){const Ge=Array.from(Ee.entries()).filter(([,$e])=>$e.status==="failed"&&$e.lastAttemptLength<10);Ge.length>0&&(Ge.sort(($e,et)=>$e[1].lastAttemptLength-et[1].lastAttemptLength),[ot,Ue]=Ge[0])}if(!Ue||ot===null){ge.current&&setTimeout(()=>Be(),1e3);return}if(!q.current.has(ot)){B(Ge=>{const $e=new Map(Ge);return $e.delete(ot),$e}),ge.current&&setTimeout(()=>Be(),10);return}ae.current=!0;const ht=U.current,Je=Ue.lastAttemptLength>0,st=Je?Ue.lastAttemptLength+1:ht;try{const Ge=await K.current.crack(Ue.packet.data,{maxLength:st,useSenderFilter:!0,useTimestampFilter:!0,useUtf8Filter:!0,...z.current&&{gpuDispatchMs:1e4},...Je&&{useDictionary:!1,startingLength:st}},$e=>{b($e)});if(G.current){G.current=!1,ae.current=!1,b(null);return}if(Ge.found&&Ge.roomName&&Ge.key){B(Oe=>{const wt=new Map(Oe),It=wt.get(ot);return It&&wt.set(ot,{...It,status:"cracked",attempts:It.attempts+1,lastAttemptLength:st}),wt});const $e={roomName:Ge.roomName,key:Ge.key,packetId:ot,message:Ge.decryptedMessage||"",crackedAt:Date.now()};F(Oe=>[...Oe,$e]);const et=Ge.key.toUpperCase();if(!ue.has(et))try{const Oe="#"+Ge.roomName;await i(Oe,Ge.key),D.current&&await it.decryptHistoricalPackets({key_type:"channel",channel_name:Oe})}catch(Oe){console.error("Failed to create channel or decrypt historical:",Oe),xt.error("Failed to save cracked channel",{description:Oe instanceof Error?Oe.message:"Channel discovered but could not be saved"})}}else B($e=>{const et=new Map($e),Oe=et.get(ot);return Oe&&et.set(ot,{...Oe,status:"failed",attempts:Oe.attempts+1,lastAttemptLength:st}),et})}catch(Ge){console.error("Cracking error:",Ge),B($e=>{const et=new Map($e),Oe=et.get(ot);return Oe&&et.set(ot,{...Oe,status:"failed",attempts:Oe.attempts+1,lastAttemptLength:st}),et})}ae.current=!1,b(null),ge.current&&setTimeout(()=>Be(),100)},[ue,i]),We=()=>{var Ee;if(!V){xt.error("WebGPU not available",{description:"Cracking requires Chrome 113+ or Edge 113+ with WebGPU support."});return}p(!0),ge.current=!0,G.current=!1,(Ee=oe.current)==null||Ee.enable(),Be()},Ke=()=>{var Ee,Ue;p(!1),ge.current=!1,G.current=!0,(Ee=K.current)==null||Ee.abort(),(Ue=oe.current)==null| Line truncated
//# sourceMappingURL=index-CL0FbnNJ.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"mappings":";;;;;;;;6CASa,IAAIA,EAAE,OAAO,IAAI,eAAe,EAAEC,EAAE,OAAO,IAAI,cAAc,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,mBAAmB,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,eAAe,EAAEC,EAAE,OAAO,IAAI,mBAAmB,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,YAAY,EAAEC,EAAE,OAAO,IAAI,YAAY,EAAEC,EAAE,OAAO,SAAS,SAASC,EAAEC,EAAE,CAAC,OAAUA,IAAP,MAAqB,OAAOA,GAAlB,SAA2B,MAAKA,EAAEF,GAAGE,EAAEF,CAAC,GAAGE,EAAE,YAAY,EAAqB,OAAOA,GAApB,WAAsBA,EAAE,KAAI,CAC1e,IAAIC,EAAE,CAAC,UAAU,UAAU,CAAC,MAAM,EAAE,EAAE,mBAAmB,UAAU,GAAG,oBAAoB,UAAU,GAAG,gBAAgB,UAAU,EAAE,EAAEC,EAAE,OAAO,OAAOC,EAAE,GAAG,SAASC,EAAEJ,EAAEK,EAAEC,EAAE,CAAC,KAAK,MAAMN,EAAE,KAAK,QAAQK,EAAE,KAAK,KAAKF,EAAE,KAAK,QAAQG,GAAGL,CAAC,CAACG,EAAE,UAAU,iBAAiB,GACnQA,EAAE,UAAU,SAAS,SAASJ,EAAEK,EAAE,CAAC,GAAc,OAAOL,GAAlB,UAAkC,OAAOA,GAApB,YAA6BA,GAAN,KAAQ,MAAM,MAAM,uHAAuH,EAAE,KAAK,QAAQ,gBAAgB,KAAKA,EAAEK,EAAE,UAAU,CAAC,EAAED,EAAE,UAAU,YAAY,SAASJ,EAAE,CAAC,KAAK,QAAQ,mBAAmB,KAAKA,EAAE,aAAa,CAAC,EAAE,SAASO,GAAG,EAAEA,EAAE,UAAUH,EAAE,UAAU,SAASI,EAAER,EAAEK,EAAEC,EAAE,CAAC,KAAK,MAAMN,EAAE,KAAK,QAAQK,EAAE,KAAK,KAAKF,EAAE,KAAK,QAAQG,GAAGL,CAAC,CAAC,IAAIQ,EAAED,EAAE,UAAU,IAAID,EACrfE,EAAE,YAAYD,EAAEN,EAAEO,EAAEL,EAAE,SAAS,EAAEK,EAAE,qBAAqB,GAAG,IAAIC,EAAE,MAAM,QAAQC,EAAE,OAAO,UAAU,eAAeC,EAAE,CAAC,QAAQ,IAAI,EAAEC,EAAE,CAAC,IAAI,GAAG,IAAI,GAAG,OAAO,GAAG,SAAS,EAAE,EACxK,SAASC,EAAEd,EAAEK,EAAEC,EAAE,CAAC,IAAIS,EAAEC,GAAE,GAAGC,GAAE,KAAKC,GAAE,KAAK,GAASb,GAAN,KAAQ,IAAIU,KAAcV,EAAE,MAAX,SAAiBa,GAAEb,EAAE,KAAcA,EAAE,MAAX,SAAiBY,GAAE,GAAGZ,EAAE,KAAKA,EAAEM,EAAE,KAAKN,EAAEU,CAAC,GAAG,CAACF,EAAE,eAAeE,CAAC,IAAIC,GAAED,CAAC,EAAEV,EAAEU,CAAC,GAAG,IAAII,GAAE,UAAU,OAAO,EAAE,GAAOA,KAAJ,EAAMH,GAAE,SAASV,UAAU,EAAEa,GAAE,CAAC,QAAQC,GAAE,MAAMD,EAAC,EAAEE,GAAE,EAAEA,GAAEF,GAAEE,KAAID,GAAEC,EAAC,EAAE,UAAUA,GAAE,CAAC,EAAEL,GAAE,SAASI,EAAC,CAAC,GAAGpB,GAAGA,EAAE,aAAa,IAAIe,KAAKI,GAAEnB,EAAE,aAAamB,GAAWH,GAAED,CAAC,IAAZ,SAAgBC,GAAED,CAAC,EAAEI,GAAEJ,CAAC,GAAG,MAAM,CAAC,SAAS5B,EAAE,KAAKa,EAAE,IAAIiB,GAAE,IAAIC,GAAE,MAAMF,GAAE,OAAOJ,EAAE,OAAO,CAAC,CAC7a,SAASU,GAAEtB,EAAEK,EAAE,CAAC,MAAM,CAAC,SAASlB,EAAE,KAAKa,EAAE,KAAK,IAAIK,EAAE,IAAIL,EAAE,IAAI,MAAMA,EAAE,MAAM,OAAOA,EAAE,MAAM,CAAC,CAAC,SAASuB,EAAEvB,EAAE,CAAC,OAAiB,OAAOA,GAAlB,UAA4BA,IAAP,MAAUA,EAAE,WAAWb,CAAC,CAAC,SAASqC,EAAOxB,EAAE,CAAC,IAAIK,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,EAAE,MAAM,IAAIL,EAAE,QAAQ,QAAQ,SAASA,EAAE,CAAC,OAAOK,EAAEL,CAAC,CAAC,CAAC,CAAC,CAAC,IAAIyB,EAAE,OAAO,SAASC,EAAE1B,EAAEK,EAAE,CAAC,OAAiB,OAAOL,GAAlB,UAA4BA,IAAP,MAAgBA,EAAE,KAAR,KAAYwB,EAAO,GAAGxB,EAAE,GAAG,EAAEK,EAAE,SAAS,EAAE,CAAC,CAC/W,SAASsB,GAAE3B,EAAEK,EAAEC,EAAES,EAAEC,GAAE,CAAC,IAAIC,GAAE,OAAOjB,GAAmBiB,KAAd,aAA6BA,KAAZ,aAAcjB,EAAE,MAAK,IAAIkB,GAAE,GAAG,GAAUlB,IAAP,KAASkB,GAAE,OAAQ,QAAOD,GAAC,CAAE,IAAK,SAAS,IAAK,SAASC,GAAE,GAAG,MAAM,IAAK,SAAS,OAAOlB,EAAE,SAAQ,CAAE,KAAKb,EAAE,KAAKC,EAAE8B,GAAE,EAAE,CAAC,CAAC,GAAGA,GAAE,OAAOA,GAAElB,EAAEgB,GAAEA,GAAEE,EAAC,EAAElB,EAAOe,IAAL,GAAO,IAAIW,EAAER,GAAE,CAAC,EAAEH,EAAEL,EAAEM,EAAC,GAAGV,EAAE,GAASN,GAAN,OAAUM,EAAEN,EAAE,QAAQyB,EAAE,KAAK,EAAE,KAAKE,GAAEX,GAAEX,EAAEC,EAAE,GAAG,SAASN,GAAE,CAAC,OAAOA,EAAC,CAAC,GAASgB,IAAN,OAAUO,EAAEP,EAAC,IAAIA,GAAEM,GAAEN,GAAEV,GAAG,CAACU,GAAE,KAAKE,IAAGA,GAAE,MAAMF,GAAE,IAAI,IAAI,GAAGA,GAAE,KAAK,QAAQS,EAAE,KAAK,EAAE,KAAKzB,CAAC,GAAGK,EAAE,KAAKW,EAAC,GAAG,EAAyB,GAAvBE,GAAE,EAAEH,EAAOA,IAAL,GAAO,IAAIA,EAAE,IAAOL,EAAEV,CAAC,EAAE,QAAQmB,GAAE,EAAEA,GAAEnB,EAAE,OAAOmB,KAAI,CAACF,GACrfjB,EAAEmB,EAAC,EAAE,IAAIC,GAAEL,EAAEW,EAAET,GAAEE,EAAC,EAAED,IAAGS,GAAEV,GAAEZ,EAAEC,EAAEc,GAAEJ,EAAC,CAAC,SAASI,GAAErB,EAAEC,CAAC,EAAe,OAAOoB,IAApB,WAAsB,IAAIpB,EAAEoB,GAAE,KAAKpB,CAAC,EAAEmB,GAAE,EAAE,EAAEF,GAAEjB,EAAE,KAAI,GAAI,MAAMiB,GAAEA,GAAE,MAAMG,GAAEL,EAAEW,EAAET,GAAEE,IAAG,EAAED,IAAGS,GAAEV,GAAEZ,EAAEC,EAAEc,GAAEJ,EAAC,UAAqBC,KAAX,SAAa,MAAMZ,EAAE,OAAOL,CAAC,EAAE,MAAM,mDAAuEK,IAApB,kBAAsB,qBAAqB,OAAO,KAAKL,CAAC,EAAE,KAAK,IAAI,EAAE,IAAIK,GAAG,2EAA2E,EAAE,OAAOa,EAAC,CACzZ,SAASU,GAAE5B,EAAEK,EAAEC,EAAE,CAAC,GAASN,GAAN,KAAQ,OAAOA,EAAE,IAAIe,EAAE,GAAGC,GAAE,EAAE,OAAAW,GAAE3B,EAAEe,EAAE,GAAG,GAAG,SAASf,GAAE,CAAC,OAAOK,EAAE,KAAKC,EAAEN,GAAEgB,IAAG,CAAC,CAAC,EAASD,CAAC,CAAC,SAASc,EAAE7B,EAAE,CAAC,GAAQA,EAAE,UAAP,GAAe,CAAC,IAAIK,EAAEL,EAAE,QAAQK,EAAEA,EAAC,EAAGA,EAAE,KAAK,SAASA,EAAE,EAAQL,EAAE,UAAN,GAAoBA,EAAE,UAAP,MAAeA,EAAE,QAAQ,EAAEA,EAAE,QAAQK,EAAC,EAAE,SAASA,EAAE,EAAQL,EAAE,UAAN,GAAoBA,EAAE,UAAP,MAAeA,EAAE,QAAQ,EAAEA,EAAE,QAAQK,EAAC,CAAC,EAAOL,EAAE,UAAP,KAAiBA,EAAE,QAAQ,EAAEA,EAAE,QAAQK,EAAE,CAAC,GAAOL,EAAE,UAAN,EAAc,OAAOA,EAAE,QAAQ,QAAQ,MAAMA,EAAE,OAAQ,CAC5Z,IAAI8B,GAAE,CAAC,QAAQ,IAAI,EAAEC,EAAE,CAAC,WAAW,IAAI,EAAEC,GAAE,CAAC,uBAAuBF,GAAE,wBAAwBC,EAAE,kBAAkBnB,CAAC,EAAE,SAASqB,GAAG,CAAC,MAAM,MAAM,0DAA0D,CAAE,CACzM,OAAAC,GAAA,SAAiB,CAAC,IAAIN,GAAE,QAAQ,SAAS5B,EAAEK,EAAEC,EAAE,CAACsB,GAAE5B,EAAE,UAAU,CAACK,EAAE,MAAM,KAAK,SAAS,CAAC,EAAEC,CAAC,CAAC,EAAE,MAAM,SAASN,EAAE,CAAC,IAAIK,EAAE,EAAE,OAAAuB,GAAE5B,EAAE,UAAU,CAACK,GAAG,CAAC,EAASA,CAAC,EAAE,QAAQ,SAASL,EAAE,CAAC,OAAO4B,GAAE5B,EAAE,SAASA,EAAE,CAAC,OAAOA,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,SAASA,EAAE,CAAC,GAAG,CAACuB,EAAEvB,CAAC,EAAE,Line truncated
+1 -1
View File
@@ -13,7 +13,7 @@
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="manifest" href="/site.webmanifest" />
<script type="module" crossorigin src="/assets/index-CL0FbnNJ.js"></script>
<script type="module" crossorigin src="/assets/index-BrthzT77.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DJA5wYVF.css">
</head>
<body>
+94 -47
View File
@@ -282,12 +282,32 @@ export function App() {
}
}, []);
// Initial fetch for config and settings
// Fetch all contacts, paginating if >1000
const fetchAllContacts = useCallback(async (): Promise<Contact[]> => {
const pageSize = 1000;
const first = await api.getContacts(pageSize, 0);
if (first.length < pageSize) return first;
let all = [...first];
let offset = pageSize;
while (true) {
const page = await api.getContacts(pageSize, offset);
all = all.concat(page);
if (page.length < pageSize) break;
offset += pageSize;
}
return all;
}, []);
// Initial fetch for config, settings, and data
useEffect(() => {
fetchConfig();
fetchAppSettings();
fetchUndecryptedCount();
}, [fetchConfig, fetchAppSettings, fetchUndecryptedCount]);
// Fetch contacts and channels via REST (parallel, faster than WS serial push)
api.getChannels().then(setChannels).catch(console.error);
fetchAllContacts().then(setContacts).catch(console.error);
}, [fetchConfig, fetchAppSettings, fetchUndecryptedCount, fetchAllContacts]);
// One-time migration of localStorage preferences to server
const hasMigratedRef = useRef(false);
@@ -355,61 +375,53 @@ export function App() {
migratePreferences();
}, [appSettings]);
// Resolve URL hash to a conversation
const resolveHashToConversation = useCallback((): Conversation | null => {
const hashConv = parseHashConversation();
if (!hashConv) return null;
// Phase 1: Set initial conversation from URL hash or default to Public channel
// Only needs channels (fast path) - doesn't wait for contacts
const hasSetDefaultConversation = useRef(false);
useEffect(() => {
if (hasSetDefaultConversation.current || activeConversation) return;
if (channels.length === 0) return;
if (hashConv.type === 'raw') {
return { type: 'raw', id: 'raw', name: 'Raw Packet Feed' };
const hashConv = parseHashConversation();
// Handle non-data views immediately
if (hashConv?.type === 'raw') {
setActiveConversation({ type: 'raw', id: 'raw', name: 'Raw Packet Feed' });
hasSetDefaultConversation.current = true;
return;
}
if (hashConv.type === 'map') {
return {
if (hashConv?.type === 'map') {
setActiveConversation({
type: 'map',
id: 'map',
name: 'Node Map',
mapFocusKey: hashConv.mapFocusKey,
};
});
hasSetDefaultConversation.current = true;
return;
}
if (hashConv.type === 'visualizer') {
return { type: 'visualizer', id: 'visualizer', name: 'Mesh Visualizer' };
}
if (hashConv.type === 'channel') {
const channel = channels.find(
(c) => c.name === hashConv.name || c.name === `#${hashConv.name}`
);
if (channel) {
return { type: 'channel', id: channel.key, name: channel.name };
}
}
if (hashConv.type === 'contact') {
const contact = contacts.find(
(c) => getContactDisplayName(c.name, c.public_key) === hashConv.name
);
if (contact) {
return {
type: 'contact',
id: contact.public_key,
name: getContactDisplayName(contact.name, contact.public_key),
};
}
}
return null;
}, [channels, contacts]);
// Set initial conversation from URL hash or default to Public channel
const hasSetDefaultConversation = useRef(false);
useEffect(() => {
if (hasSetDefaultConversation.current || activeConversation) return;
if (channels.length === 0 && contacts.length === 0) return;
const conv = resolveHashToConversation();
if (conv) {
setActiveConversation(conv);
if (hashConv?.type === 'visualizer') {
setActiveConversation({ type: 'visualizer', id: 'visualizer', name: 'Mesh Visualizer' });
hasSetDefaultConversation.current = true;
return;
}
// Handle channel hash
if (hashConv?.type === 'channel') {
const channel = channels.find(
(c) => c.name === hashConv.name || c.name === `#${hashConv.name}`
);
if (channel) {
setActiveConversation({ type: 'channel', id: channel.key, name: channel.name });
hasSetDefaultConversation.current = true;
return;
}
}
// Contact hash — wait for phase 2
if (hashConv?.type === 'contact') return;
// No hash or unresolvable — default to Public
const publicChannel = channels.find((c) => c.name === 'Public');
if (publicChannel) {
setActiveConversation({
@@ -419,7 +431,42 @@ export function App() {
});
hasSetDefaultConversation.current = true;
}
}, [channels, contacts, activeConversation, resolveHashToConversation]);
}, [channels, activeConversation]);
// Phase 2: Resolve contact hash (only if phase 1 didn't set a conversation)
useEffect(() => {
if (hasSetDefaultConversation.current || activeConversation) return;
if (contacts.length === 0) return;
const hashConv = parseHashConversation();
if (hashConv?.type === 'contact') {
const contact = contacts.find(
(c) => getContactDisplayName(c.name, c.public_key) === hashConv.name
);
if (contact) {
setActiveConversation({
type: 'contact',
id: contact.public_key,
name: getContactDisplayName(contact.name, contact.public_key),
});
hasSetDefaultConversation.current = true;
return;
}
}
// Contact hash didn't match — fall back to Public if channels loaded
if (channels.length > 0) {
const publicChannel = channels.find((c) => c.name === 'Public');
if (publicChannel) {
setActiveConversation({
type: 'channel',
id: publicChannel.key,
name: publicChannel.name,
});
hasSetDefaultConversation.current = true;
}
}
}, [contacts, channels, activeConversation]);
// Keep ref in sync and update URL hash
useEffect(() => {
+5 -14
View File
@@ -13,13 +13,11 @@ import type {
RadioConfig,
RadioConfigUpdate,
TelemetryResponse,
UnreadCounts,
} from './types';
const API_BASE = '/api';
/** Max messages fetched per conversation for unread counting. If count equals this, there may be more. */
export const UNREAD_FETCH_LIMIT = 100;
async function fetchJson<T>(url: string, options?: RequestInit): Promise<T> {
const res = await fetch(`${API_BASE}${url}`, {
...options,
@@ -153,17 +151,6 @@ export const api = {
const query = searchParams.toString();
return fetchJson<Message[]>(`/messages${query ? `?${query}` : ''}`, { signal });
},
getMessagesBulk: (
conversations: Array<{ type: 'PRIV' | 'CHAN'; conversation_key: string }>,
limitPerConversation: number = UNREAD_FETCH_LIMIT
) =>
fetchJson<Record<string, Message[]>>(
`/messages/bulk?limit_per_conversation=${limitPerConversation}`,
{
method: 'POST',
body: JSON.stringify(conversations),
}
),
sendDirectMessage: (destination: string, text: string) =>
fetchJson<Message>('/messages/direct', {
method: 'POST',
@@ -193,6 +180,10 @@ export const api = {
}),
// Read State
getUnreads: (name?: string) => {
const params = name ? `?name=${encodeURIComponent(name)}` : '';
return fetchJson<UnreadCounts>(`/read-state/unreads${params}`);
},
markAllRead: () =>
fetchJson<{ status: string; timestamp: number }>('/read-state/mark-all-read', {
method: 'POST',
+2 -3
View File
@@ -5,7 +5,6 @@ import { getContactDisplayName } from '../utils/pubkey';
import { ContactAvatar } from './ContactAvatar';
import { CONTACT_TYPE_REPEATER } from '../utils/contactAvatar';
import { isFavorite } from '../utils/favorites';
import { UNREAD_FETCH_LIMIT } from '../api';
import { Input } from './ui/input';
import { Button } from './ui/button';
import { cn } from '@/lib/utils';
@@ -33,9 +32,9 @@ interface SidebarProps {
onSortOrderChange?: (order: SortOrder) => void;
}
/** Format unread count, showing "X+" if at the fetch limit (indicating there may be more) */
/** Format unread count for display */
function formatUnreadCount(count: number): string {
return count >= UNREAD_FETCH_LIMIT ? `${count}+` : `${count}`;
return `${count}`;
}
export function Sidebar({
+24 -106
View File
@@ -1,5 +1,5 @@
import { useState, useCallback, useEffect, useRef } from 'react';
import { api, UNREAD_FETCH_LIMIT } from '../api';
import { api } from '../api';
import {
getLastMessageTimes,
setLastMessageTime,
@@ -19,15 +19,6 @@ export interface UseUnreadCountsResult {
trackNewMessage: (msg: Message) => void;
}
/** Check if a message text contains a mention of the given name in @[name] format */
function messageContainsMention(text: string, name: string | null): boolean {
if (!name) return false;
// Escape special regex characters in the name
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const mentionPattern = new RegExp(`@\\[${escaped}\\]`, 'i');
return mentionPattern.test(text);
}
export function useUnreadCounts(
channels: Channel[],
contacts: Contact[],
@@ -44,106 +35,32 @@ export function useUnreadCounts(
myNameRef.current = myName;
}, [myName]);
// Track which channels/contacts we've already fetched unreads for
const fetchedChannels = useRef<Set<string>>(new Set());
const fetchedContacts = useRef<Set<string>>(new Set());
// Fetch unreads from the server-side endpoint
const fetchUnreads = useCallback(async () => {
try {
const data = await api.getUnreads(myNameRef.current ?? undefined);
// Fetch messages and count unreads for new channels/contacts
// Uses server-side last_read_at for consistent read state across devices
useEffect(() => {
const newChannels = channels.filter((c) => !fetchedChannels.current.has(c.key));
const newContacts = contacts.filter(
(c) => c.public_key && !fetchedContacts.current.has(c.public_key)
);
// Replace (not merge) — server counts are authoritative
setUnreadCounts(data.counts);
setMentions(data.mentions);
if (newChannels.length === 0 && newContacts.length === 0) return;
// Mark as fetched before starting (to avoid duplicate fetches if effect re-runs)
newChannels.forEach((c) => fetchedChannels.current.add(c.key));
newContacts.forEach((c) => fetchedContacts.current.add(c.public_key));
const fetchAndCountUnreads = async () => {
const conversations: Array<{ type: 'PRIV' | 'CHAN'; conversation_key: string }> = [
...newChannels.map((c) => ({ type: 'CHAN' as const, conversation_key: c.key })),
...newContacts.map((c) => ({ type: 'PRIV' as const, conversation_key: c.public_key })),
];
if (conversations.length === 0) return;
try {
// Fetch messages in chunks to avoid huge single requests
const chunkSize = 200;
const bulkMessages: Record<string, Message[]> = {};
for (let i = 0; i < conversations.length; i += chunkSize) {
const chunk = conversations.slice(i, i + chunkSize);
const chunkResult = await api.getMessagesBulk(chunk, UNREAD_FETCH_LIMIT);
Object.assign(bulkMessages, chunkResult);
}
const newUnreadCounts: Record<string, number> = {};
const newMentions: Record<string, boolean> = {};
const newLastMessageTimes: Record<string, number> = {};
// Process channel messages - use server-side last_read_at
for (const channel of newChannels) {
const msgs = bulkMessages[`CHAN:${channel.key}`] || [];
if (msgs.length > 0) {
const key = getStateKey('channel', channel.key);
// Use server-side last_read_at, fallback to 0 if never read
const lastRead = channel.last_read_at || 0;
const unreadMsgs = msgs.filter((m) => !m.outgoing && m.received_at > lastRead);
if (unreadMsgs.length > 0) {
newUnreadCounts[key] = unreadMsgs.length;
// Check if any unread message mentions the user
if (unreadMsgs.some((m) => messageContainsMention(m.text, myNameRef.current))) {
newMentions[key] = true;
}
}
const latestTime = Math.max(...msgs.map((m) => m.received_at));
newLastMessageTimes[key] = latestTime;
setLastMessageTime(key, latestTime);
}
}
// Process contact messages - use server-side last_read_at
for (const contact of newContacts) {
const msgs = bulkMessages[`PRIV:${contact.public_key}`] || [];
if (msgs.length > 0) {
const key = getStateKey('contact', contact.public_key);
// Use server-side last_read_at, fallback to 0 if never read
const lastRead = contact.last_read_at || 0;
const unreadMsgs = msgs.filter((m) => !m.outgoing && m.received_at > lastRead);
if (unreadMsgs.length > 0) {
newUnreadCounts[key] = unreadMsgs.length;
// Check if any unread message mentions the user
if (unreadMsgs.some((m) => messageContainsMention(m.text, myNameRef.current))) {
newMentions[key] = true;
}
}
const latestTime = Math.max(...msgs.map((m) => m.received_at));
newLastMessageTimes[key] = latestTime;
setLastMessageTime(key, latestTime);
}
}
if (Object.keys(newUnreadCounts).length > 0) {
setUnreadCounts((prev) => ({ ...prev, ...newUnreadCounts }));
}
if (Object.keys(newMentions).length > 0) {
setMentions((prev) => ({ ...prev, ...newMentions }));
if (Object.keys(data.last_message_times).length > 0) {
// Update in-memory cache and state
for (const [key, ts] of Object.entries(data.last_message_times)) {
setLastMessageTime(key, ts);
}
setLastMessageTimes(getLastMessageTimes());
} catch (err) {
console.error('Failed to fetch messages bulk:', err);
}
};
} catch (err) {
console.error('Failed to fetch unreads:', err);
}
}, []);
fetchAndCountUnreads();
}, [channels, contacts]);
// Fetch when channels or contacts arrive/change
useEffect(() => {
if (channels.length === 0 && contacts.length === 0) return;
fetchUnreads();
}, [channels, contacts, fetchUnreads]);
// Mark conversation as read when user views it
// Calls server API to persist read state across devices
@@ -151,7 +68,8 @@ export function useUnreadCounts(
if (
activeConversation &&
activeConversation.type !== 'raw' &&
activeConversation.type !== 'map'
activeConversation.type !== 'map' &&
activeConversation.type !== 'visualizer'
) {
const key = getStateKey(
activeConversation.type as 'channel' | 'contact',
@@ -221,7 +139,7 @@ export function useUnreadCounts(
// Mark a specific conversation as read
// Calls server API to persist read state across devices
const markConversationRead = useCallback((conv: Conversation) => {
if (conv.type === 'raw' || conv.type === 'map') return;
if (conv.type === 'raw' || conv.type === 'map' || conv.type === 'visualizer') return;
const key = getStateKey(conv.type as 'channel' | 'contact', conv.id);
+6
View File
@@ -209,3 +209,9 @@ export interface CommandResponse {
response: string;
sender_timestamp: number | null;
}
export interface UnreadCounts {
counts: Record<string, number>;
mentions: Record<string, boolean>;
last_message_times: Record<string, number>;
}
+190
View File
@@ -480,6 +480,196 @@ class TestReadStateEndpoints:
assert response.status_code == 404
assert "not found" in response.json()["detail"].lower()
@pytest.mark.asyncio
async def test_get_unreads_returns_counts_and_mentions(self):
"""GET /unreads returns unread counts, mentions, and last message times."""
import aiosqlite
from app.database import db
from app.repository import MessageRepository
conn = await aiosqlite.connect(":memory:")
conn.row_factory = aiosqlite.Row
# Create tables
await conn.execute("""
CREATE TABLE contacts (
public_key TEXT PRIMARY KEY,
name TEXT,
type INTEGER DEFAULT 0,
flags INTEGER DEFAULT 0,
last_path TEXT,
last_path_len INTEGER DEFAULT -1,
last_advert INTEGER,
lat REAL,
lon REAL,
last_seen INTEGER,
on_radio INTEGER DEFAULT 0,
last_contacted INTEGER,
last_read_at INTEGER
)
""")
await conn.execute("""
CREATE TABLE channels (
key TEXT PRIMARY KEY,
name TEXT NOT NULL,
is_hashtag INTEGER DEFAULT 0,
on_radio INTEGER DEFAULT 0,
last_read_at INTEGER
)
""")
await conn.execute("""
CREATE TABLE messages (
id INTEGER PRIMARY KEY,
type TEXT NOT NULL,
conversation_key TEXT NOT NULL,
text TEXT NOT NULL,
sender_timestamp INTEGER,
received_at INTEGER NOT NULL,
paths TEXT,
txt_type INTEGER DEFAULT 0,
signature TEXT,
outgoing INTEGER DEFAULT 0,
acked INTEGER DEFAULT 0,
UNIQUE(type, conversation_key, text, sender_timestamp)
)
""")
# Insert channel and contact
await conn.execute(
"INSERT INTO channels (key, name, last_read_at) VALUES (?, ?, ?)",
("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1", "Public", 1000),
)
await conn.execute(
"INSERT INTO contacts (public_key, name, last_read_at) VALUES (?, ?, ?)",
("abcd" * 16, "Alice", 1000),
)
# Insert messages: 2 unread channel msgs (after last_read_at=1000),
# 1 read (before), 1 outgoing (should not count)
await conn.execute(
"INSERT INTO messages (type, conversation_key, text, received_at, outgoing) VALUES (?, ?, ?, ?, ?)",
("CHAN", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1", "Bob: hello", 1001, 0),
)
await conn.execute(
"INSERT INTO messages (type, conversation_key, text, received_at, outgoing) VALUES (?, ?, ?, ?, ?)",
("CHAN", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1", "Bob: @[TestUser] hey", 1002, 0),
)
await conn.execute(
"INSERT INTO messages (type, conversation_key, text, received_at, outgoing) VALUES (?, ?, ?, ?, ?)",
("CHAN", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1", "Bob: old msg", 999, 0),
)
await conn.execute(
"INSERT INTO messages (type, conversation_key, text, received_at, outgoing) VALUES (?, ?, ?, ?, ?)",
("CHAN", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1", "Me: outgoing", 1003, 1),
)
# Insert 1 unread DM
await conn.execute(
"INSERT INTO messages (type, conversation_key, text, received_at, outgoing) VALUES (?, ?, ?, ?, ?)",
("PRIV", "abcd" * 16, "hi there", 1005, 0),
)
await conn.commit()
original_conn = db._connection
db._connection = conn
try:
result = await MessageRepository.get_unread_counts("TestUser")
# Channel: 2 unread (1001 and 1002), one has mention
assert result["counts"]["channel-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1"] == 2
assert result["mentions"]["channel-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1"] is True
# Contact: 1 unread
assert result["counts"][f"contact-{'abcd' * 16}"] == 1
# Last message times should include all conversations
assert "channel-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1" in result["last_message_times"]
assert result["last_message_times"]["channel-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1"] == 1003
assert f"contact-{'abcd' * 16}" in result["last_message_times"]
assert result["last_message_times"][f"contact-{'abcd' * 16}"] == 1005
finally:
db._connection = original_conn
await conn.close()
@pytest.mark.asyncio
async def test_get_unreads_no_name_skips_mentions(self):
"""GET /unreads without name param returns counts but no mention flags."""
import aiosqlite
from app.database import db
from app.repository import MessageRepository
conn = await aiosqlite.connect(":memory:")
conn.row_factory = aiosqlite.Row
await conn.execute("""
CREATE TABLE channels (
key TEXT PRIMARY KEY,
name TEXT NOT NULL,
is_hashtag INTEGER DEFAULT 0,
on_radio INTEGER DEFAULT 0,
last_read_at INTEGER
)
""")
await conn.execute("""
CREATE TABLE contacts (
public_key TEXT PRIMARY KEY,
name TEXT,
type INTEGER DEFAULT 0,
flags INTEGER DEFAULT 0,
last_path TEXT,
last_path_len INTEGER DEFAULT -1,
last_advert INTEGER,
lat REAL,
lon REAL,
last_seen INTEGER,
on_radio INTEGER DEFAULT 0,
last_contacted INTEGER,
last_read_at INTEGER
)
""")
await conn.execute("""
CREATE TABLE messages (
id INTEGER PRIMARY KEY,
type TEXT NOT NULL,
conversation_key TEXT NOT NULL,
text TEXT NOT NULL,
sender_timestamp INTEGER,
received_at INTEGER NOT NULL,
paths TEXT,
txt_type INTEGER DEFAULT 0,
signature TEXT,
outgoing INTEGER DEFAULT 0,
acked INTEGER DEFAULT 0,
UNIQUE(type, conversation_key, text, sender_timestamp)
)
""")
await conn.execute(
"INSERT INTO channels (key, name, last_read_at) VALUES (?, ?, ?)",
("CHAN1KEY1CHAN1KEY1CHAN1KEY1CHAN1KEY1", "Public", 0),
)
await conn.execute(
"INSERT INTO messages (type, conversation_key, text, received_at, outgoing) VALUES (?, ?, ?, ?, ?)",
("CHAN", "CHAN1KEY1CHAN1KEY1CHAN1KEY1CHAN1KEY1", "Bob: @[Alice] hey", 1001, 0),
)
await conn.commit()
original_conn = db._connection
db._connection = conn
try:
result = await MessageRepository.get_unread_counts(None)
assert result["counts"]["channel-CHAN1KEY1CHAN1KEY1CHAN1KEY1CHAN1KEY1"] == 1
# No mentions since name was None
assert len(result["mentions"]) == 0
finally:
db._connection = original_conn
await conn.close()
@pytest.mark.asyncio
async def test_mark_all_read_updates_all_conversations(self):
"""Bulk mark-all-read updates all contacts and channels."""