Path display improvements, focusable maps, contact distance display, click to copy keys

This commit is contained in:
Jack Kingsman committed 2026-01-18 16:08:39 -08:00
1 parent 05a830d63f
commit cc1a2c57c2
14 files changed
+971 -573

No files matched your search

@@ -1 +1 @@
.leaflet-pane,.leaflet-tile,.leaflet-marker-icon,.leaflet-marker-shadow,.leaflet-tile-container,.leaflet-pane>svg,.leaflet-pane>canvas,.leaflet-zoom-box,.leaflet-image-layer,.leaflet-layer{position:absolute;left:0;top:0}.leaflet-container{overflow:hidden}.leaflet-tile,.leaflet-marker-icon,.leaflet-marker-shadow{-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-user-drag:none}.leaflet-tile::-moz-selection{background:transparent}.leaflet-tile::selection{background:transparent}.leaflet-safari .leaflet-tile{image-rendering:-webkit-optimize-contrast}.leaflet-safari .leaflet-tile-container{width:1600px;height:1600px;-webkit-transform-origin:0 0}.leaflet-marker-icon,.leaflet-marker-shadow{display:block}.leaflet-container .leaflet-overlay-pane svg{max-width:none!important;max-height:none!important}.leaflet-container .leaflet-marker-pane img,.leaflet-container .leaflet-shadow-pane img,.leaflet-container .leaflet-tile-pane img,.leaflet-container img.leaflet-image-layer,.leaflet-container .leaflet-tile{max-width:none!important;max-height:none!important;width:auto;padding:0}.leaflet-container img.leaflet-tile{mix-blend-mode:plus-lighter}.leaflet-container.leaflet-touch-zoom{touch-action:pan-x pan-y}.leaflet-container.leaflet-touch-drag{touch-action:none;touch-action:pinch-zoom}.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom{touch-action:none}.leaflet-container{-webkit-tap-highlight-color:transparent}.leaflet-container a{-webkit-tap-highlight-color:rgba(51,181,229,.4)}.leaflet-tile{filter:inherit;visibility:hidden}.leaflet-tile-loaded{visibility:inherit}.leaflet-zoom-box{width:0;height:0;box-sizing:border-box;z-index:800}.leaflet-overlay-pane svg{-moz-user-select:none}.leaflet-pane{z-index:400}.leaflet-tile-pane{z-index:200}.leaflet-overlay-pane{z-index:400}.leaflet-shadow-pane{z-index:500}.leaflet-marker-pane{z-index:600}.leaflet-tooltip-pane{z-index:650}.leaflet-popup-pane{z-index:700}.leaflet-map-pane canvas{z-index:100}.leaflet-map-pane svg{z-index:200}.leaflet-vml-shape{width:1px;height:1px}.lvml{behavior:url(#default#VML);display:inline-block;position:absolute}.leaflet-control{position:relative;z-index:800;pointer-events:visiblePainted;pointer-events:auto}.leaflet-top,.leaflet-bottom{position:absolute;z-index:1000;pointer-events:none}.leaflet-top{top:0}.leaflet-right{right:0}.leaflet-bottom{bottom:0}.leaflet-left{left:0}.leaflet-control{float:left;clear:both}.leaflet-right .leaflet-control{float:right}.leaflet-top .leaflet-control{margin-top:10px}.leaflet-bottom .leaflet-control{margin-bottom:10px}.leaflet-left .leaflet-control{margin-left:10px}.leaflet-right .leaflet-control{margin-right:10px}.leaflet-fade-anim .leaflet-popup{opacity:0;transition:opacity .2s linear}.leaflet-fade-anim .leaflet-map-pane .leaflet-popup{opacity:1}.leaflet-zoom-animated{transform-origin:0 0}svg.leaflet-zoom-animated{will-change:transform}.leaflet-zoom-anim .leaflet-zoom-animated{transition:transform .25s cubic-bezier(0,0,.25,1)}.leaflet-zoom-anim .leaflet-tile,.leaflet-pan-anim .leaflet-tile{transition:none}.leaflet-zoom-anim .leaflet-zoom-hide{visibility:hidden}.leaflet-interactive{cursor:pointer}.leaflet-grab{cursor:grab}.leaflet-crosshair,.leaflet-crosshair .leaflet-interactive{cursor:crosshair}.leaflet-popup-pane,.leaflet-control{cursor:auto}.leaflet-dragging .leaflet-grab,.leaflet-dragging .leaflet-grab .leaflet-interactive,.leaflet-dragging .leaflet-marker-draggable{cursor:move;cursor:grabbing}.leaflet-marker-icon,.leaflet-marker-shadow,.leaflet-image-layer,.leaflet-pane>svg path,.leaflet-tile-container{pointer-events:none}.leaflet-marker-icon.leaflet-interactive,.leaflet-image-layer.leaflet-interactive,.leaflet-pane>svg path.leaflet-interactive,svg.leaflet-image-layer.leaflet-interactive path{pointer-events:visiblePainted;pointer-events:auto}.leaflet-container{background:#ddd;outline-offset:1px}.leaflet-container a{color:#0078a8}.leaflet-zoom-box{border:2px dotted #38f;background:#ffffff80}.leaflet-container{font-family:Helvetica Neue,Arial,Helvetica,sans-serif;font-size:12px;font-size:.75rem;line-height:1.5}.leaflet-bar{box-shadow:0 1px 5px #000000a6;border-radius:4px}.leaflet-bar a{background-color:#fff;border-bottom:1px solid #ccc;width:26px;height:26px;line-height:26px;display:block;text-align:center;text-decoration:none;color:#000}.leaflet-bar a,.leaflet-control-layers-toggle{background-position:50% 50%;background-repeat:no-repeat;display:block}.leaflet-bar a:hover,.leaflet-bar a:focus{background-color:#f4f4f4}.leaflet-bar a:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.leaflet-bar a:last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-bottom:none}.leaflet-bar a.leaflet-disabled{cursor:default;background-color:#f4f4f4;color:#bbb}.leaflet-touch .leaflet-bar a{width:30px;height:30px;line-height:30px}.leaflet-touch .leaflet-bar a:first-child{border-top-left-radius:2px;border-top-right-radius:2px}.leaflet-touch .leaflet-bar a:last-child{border-bottLine truncated
.leaflet-pane,.leaflet-tile,.leaflet-marker-icon,.leaflet-marker-shadow,.leaflet-tile-container,.leaflet-pane>svg,.leaflet-pane>canvas,.leaflet-zoom-box,.leaflet-image-layer,.leaflet-layer{position:absolute;left:0;top:0}.leaflet-container{overflow:hidden}.leaflet-tile,.leaflet-marker-icon,.leaflet-marker-shadow{-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-user-drag:none}.leaflet-tile::-moz-selection{background:transparent}.leaflet-tile::selection{background:transparent}.leaflet-safari .leaflet-tile{image-rendering:-webkit-optimize-contrast}.leaflet-safari .leaflet-tile-container{width:1600px;height:1600px;-webkit-transform-origin:0 0}.leaflet-marker-icon,.leaflet-marker-shadow{display:block}.leaflet-container .leaflet-overlay-pane svg{max-width:none!important;max-height:none!important}.leaflet-container .leaflet-marker-pane img,.leaflet-container .leaflet-shadow-pane img,.leaflet-container .leaflet-tile-pane img,.leaflet-container img.leaflet-image-layer,.leaflet-container .leaflet-tile{max-width:none!important;max-height:none!important;width:auto;padding:0}.leaflet-container img.leaflet-tile{mix-blend-mode:plus-lighter}.leaflet-container.leaflet-touch-zoom{touch-action:pan-x pan-y}.leaflet-container.leaflet-touch-drag{touch-action:none;touch-action:pinch-zoom}.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom{touch-action:none}.leaflet-container{-webkit-tap-highlight-color:transparent}.leaflet-container a{-webkit-tap-highlight-color:rgba(51,181,229,.4)}.leaflet-tile{filter:inherit;visibility:hidden}.leaflet-tile-loaded{visibility:inherit}.leaflet-zoom-box{width:0;height:0;box-sizing:border-box;z-index:800}.leaflet-overlay-pane svg{-moz-user-select:none}.leaflet-pane{z-index:400}.leaflet-tile-pane{z-index:200}.leaflet-overlay-pane{z-index:400}.leaflet-shadow-pane{z-index:500}.leaflet-marker-pane{z-index:600}.leaflet-tooltip-pane{z-index:650}.leaflet-popup-pane{z-index:700}.leaflet-map-pane canvas{z-index:100}.leaflet-map-pane svg{z-index:200}.leaflet-vml-shape{width:1px;height:1px}.lvml{behavior:url(#default#VML);display:inline-block;position:absolute}.leaflet-control{position:relative;z-index:800;pointer-events:visiblePainted;pointer-events:auto}.leaflet-top,.leaflet-bottom{position:absolute;z-index:1000;pointer-events:none}.leaflet-top{top:0}.leaflet-right{right:0}.leaflet-bottom{bottom:0}.leaflet-left{left:0}.leaflet-control{float:left;clear:both}.leaflet-right .leaflet-control{float:right}.leaflet-top .leaflet-control{margin-top:10px}.leaflet-bottom .leaflet-control{margin-bottom:10px}.leaflet-left .leaflet-control{margin-left:10px}.leaflet-right .leaflet-control{margin-right:10px}.leaflet-fade-anim .leaflet-popup{opacity:0;transition:opacity .2s linear}.leaflet-fade-anim .leaflet-map-pane .leaflet-popup{opacity:1}.leaflet-zoom-animated{transform-origin:0 0}svg.leaflet-zoom-animated{will-change:transform}.leaflet-zoom-anim .leaflet-zoom-animated{transition:transform .25s cubic-bezier(0,0,.25,1)}.leaflet-zoom-anim .leaflet-tile,.leaflet-pan-anim .leaflet-tile{transition:none}.leaflet-zoom-anim .leaflet-zoom-hide{visibility:hidden}.leaflet-interactive{cursor:pointer}.leaflet-grab{cursor:grab}.leaflet-crosshair,.leaflet-crosshair .leaflet-interactive{cursor:crosshair}.leaflet-popup-pane,.leaflet-control{cursor:auto}.leaflet-dragging .leaflet-grab,.leaflet-dragging .leaflet-grab .leaflet-interactive,.leaflet-dragging .leaflet-marker-draggable{cursor:move;cursor:grabbing}.leaflet-marker-icon,.leaflet-marker-shadow,.leaflet-image-layer,.leaflet-pane>svg path,.leaflet-tile-container{pointer-events:none}.leaflet-marker-icon.leaflet-interactive,.leaflet-image-layer.leaflet-interactive,.leaflet-pane>svg path.leaflet-interactive,svg.leaflet-image-layer.leaflet-interactive path{pointer-events:visiblePainted;pointer-events:auto}.leaflet-container{background:#ddd;outline-offset:1px}.leaflet-container a{color:#0078a8}.leaflet-zoom-box{border:2px dotted #38f;background:#ffffff80}.leaflet-container{font-family:Helvetica Neue,Arial,Helvetica,sans-serif;font-size:12px;font-size:.75rem;line-height:1.5}.leaflet-bar{box-shadow:0 1px 5px #000000a6;border-radius:4px}.leaflet-bar a{background-color:#fff;border-bottom:1px solid #ccc;width:26px;height:26px;line-height:26px;display:block;text-align:center;text-decoration:none;color:#000}.leaflet-bar a,.leaflet-control-layers-toggle{background-position:50% 50%;background-repeat:no-repeat;display:block}.leaflet-bar a:hover,.leaflet-bar a:focus{background-color:#f4f4f4}.leaflet-bar a:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.leaflet-bar a:last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-bottom:none}.leaflet-bar a.leaflet-disabled{cursor:default;background-color:#f4f4f4;color:#bbb}.leaflet-touch .leaflet-bar a{width:30px;height:30px;line-height:30px}.leaflet-touch .leaflet-bar a:first-child{border-top-left-radius:2px;border-top-right-radius:2px}.leaflet-touch .leaflet-bar a:last-child{border-bottLine truncated
-542
View File
@@ -1,542 +0,0 @@
var Pv=Object.defineProperty;var Tv=(r,a,o)=>a in r?Pv(r,a,{enumerable:!0,configurable:!0,writable:!0,value:o}):r[a]=o;var Oo=(r,a,o)=>Tv(r,typeof a!="symbol"?a+"":a,o);function Dv(r,a){for(var o=0;o<a.length;o++){const l=a[o];if(typeof l!="string"&&!Array.isArray(l)){for(const d in l)if(d!=="default"&&!(d in r)){const f=Object.getOwnPropertyDescriptor(l,d);f&&Object.defineProperty(r,d,f.get?f:{enumerable:!0,get:()=>l[d]})}}}return Object.freeze(Object.defineProperty(r,Symbol.toStringTag,{value:"Module"}))}(function(){const a=document.createElement("link").relList;if(a&&a.supports&&a.supports("modulepreload"))return;for(const d of document.querySelectorAll('link[rel="modulepreload"]'))l(d);new MutationObserver(d=>{for(const f of d)if(f.type==="childList")for(const m of f.addedNodes)m.tagName==="LINK"&&m.rel==="modulepreload"&&l(m)}).observe(document,{childList:!0,subtree:!0});function o(d){const f={};return d.integrity&&(f.integrity=d.integrity),d.referrerPolicy&&(f.referrerPolicy=d.referrerPolicy),d.crossOrigin==="use-credentials"?f.credentials="include":d.crossOrigin==="anonymous"?f.credentials="omit":f.credentials="same-origin",f}function l(d){if(d.ep)return;d.ep=!0;const f=o(d);fetch(d.href,f)}})();var Tf=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function $s(r){return r&&r.__esModule&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}function NA(r){if(Object.prototype.hasOwnProperty.call(r,"__esModule"))return r;var a=r.default;if(typeof a=="function"){var o=function l(){return this instanceof l?Reflect.construct(a,arguments,this.constructor):a.apply(this,arguments)};o.prototype=a.prototype}else o={};return Object.defineProperty(o,"__esModule",{value:!0}),Object.keys(r).forEach(function(l){var d=Object.getOwnPropertyDescriptor(r,l);Object.defineProperty(o,l,d.get?d:{enumerable:!0,get:function(){return r[l]}})}),o}var Df={exports:{}},Ua={},Rf={exports:{}},ut={};/**
* @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 Ep;function Rv(){if(Ep)return ut;Ep=1;var r=Symbol.for("react.element"),a=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),l=Symbol.for("react.strict_mode"),d=Symbol.for("react.profiler"),f=Symbol.for("react.provider"),m=Symbol.for("react.context"),h=Symbol.for("react.forward_ref"),x=Symbol.for("react.suspense"),p=Symbol.for("react.memo"),v=Symbol.for("react.lazy"),y=Symbol.iterator;function w(R){return R===null||typeof R!="object"?null:(R=y&&R[y]||R["@@iterator"],typeof R=="function"?R:null)}var B={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},D=Object.assign,C={};function k(R,U,Q){this.props=R,this.context=U,this.refs=C,this.updater=Q||B}k.prototype.isReactComponent={},k.prototype.setState=function(R,U){if(typeof R!="object"&&typeof R!="function"&&R!=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,R,U,"setState")},k.prototype.forceUpdate=function(R){this.updater.enqueueForceUpdate(this,R,"forceUpdate")};function P(){}P.prototype=k.prototype;function T(R,U,Q){this.props=R,this.context=U,this.refs=C,this.updater=Q||B}var S=T.prototype=new P;S.constructor=T,D(S,k.prototype),S.isPureReactComponent=!0;var N=Array.isArray,I=Object.prototype.hasOwnProperty,j={current:null},H={key:!0,ref:!0,__self:!0,__source:!0};function z(R,U,Q){var $,de={},fe=null,ke=null;if(U!=null)for($ in U.ref!==void 0&&(ke=U.ref),U.key!==void 0&&(fe=""+U.key),U)I.call(U,$)&&!H.hasOwnProperty($)&&(de[$]=U[$]);var ge=arguments.length-2;if(ge===1)de.children=Q;else if(1<ge){for(var Ze=Array(ge),$e=0;$e<ge;$e++)Ze[$e]=arguments[$e+2];de.children=Ze}if(R&&R.defaultProps)for($ in ge=R.defaultProps,ge)de[$]===void 0&&(de[$]=ge[$]);return{$$typeof:r,type:R,key:fe,ref:ke,props:de,_owner:j.current}}function ee(R,U){return{$$typeof:r,type:R.type,key:U,ref:R.ref,props:R.props,_owner:R._owner}}function Z(R){return typeof R=="object"&&R!==null&&R.$$typeof===r}function V(R){var U={"=":"=0",":":"=2"};return"$"+R.replace(/[=:]/g,function(Q){return U[Q]})}var ne=/\/+/g;function J(R,U){return typeof R=="object"&&R!==null&&R.key!=null?V(""+R.key):U.toString(36)}function re(R,U,Q,$,de){var fe=typeof R;(fe==="undefined"||fe==="boolean")&&(R=null);var ke=!1;if(R===null)ke=!0;else switch(fe){case"string":case"number":ke=!0;break;case"object":switch(R.$$typeof){case r:case a:ke=!0}}if(ke)return ke=R,de=de(ke),R=$===""?"."+J(ke,0):$,N(de)?(Q="",R!=null&&(Q=R.replace(ne,"$&/")+"/"),re(de,U,Q,"",function($e){return $e})):de!=null&&(Z(de)&&(de=ee(de,Q+(!de.key||ke&&ke.key===de.key?"":(""+de.key).replace(ne,"$&/")+"/")+R)),U.push(de)),1;if(ke=0,$=$===""?".":$+":",N(R))for(var ge=0;ge<R.length;ge++){fe=R[ge];var Ze=$+J(fe,ge);ke+=re(fe,U,Q,Ze,de)}else if(Ze=w(R),typeof Ze=="function")for(R=Ze.call(R),ge=0;!(fe=R.next()).done;)fe=fe.value,Ze=$+J(fe,ge++),ke+=re(fe,U,Q,Ze,de);else if(fe==="object")throw U=String(R),Error("Objects are not valid as a React child (found: "+(U==="[object Object]"?"object with keys {"+Object.keys(R).join(", ")+"}":U)+"). If you meant to render a collection of children, use an array instead.");return ke}function he(R,U,Q){if(R==null)return R;var $=[],de=0;return re(R,$,"","",function(fe){return U.call(Q,fe,de++)}),$}function ae(R){if(R._status===-1){var U=R._result;U=U(),U.then(function(Q){(R._status===0||R._status===-1)&&(R._status=1,R._result=Q)},function(Q){(R._status===0||R._status===-1)&&(R._status=2,R._result=Q)}),R._status===-1&&(R._status=0,R._result=U)}if(R._status===1)return R._result.default;throw R._result}var pe={current:null},G={transition:null},Y={ReactCurrentDispatcher:pe,ReactCurrentBatchConfig:G,ReactCurrentOwner:j};function q(){throw Error("act(...) is not supported in production builds of React.")}return ut.Children={map:he,forEach:function(R,U,Q){he(R,function(){U.apply(this,arguments)},Q)},count:function(R){var U=0;return he(R,function(){U++}),U},toArray:function(R){return he(R,function(U){return U})||[]},only:function(R){if(!Z(R))throw Error("React.Children.only expected to receive a single React element child.");return R}},ut.Component=k,ut.Fragment=o,ut.Profiler=d,ut.PureComponent=T,ut.StrictMode=l,ut.Suspense=x,ut.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=Y,ut.act=q,ut.cloneElement=function(R,U,Q){if(R==null)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+R+".");var $=D({},R.props),de=R.key,fe=R.ref,ke=R._owner;if(U!=null){if(U.ref!==void 0&&(fe=U.ref,ke=j.current),U.key!==void 0&&(de=""+U.key),R.type&&R.type.defaultProps)var ge=R.type.defaultProps;for(Ze in U)I.call(U,Ze)&&!H.hasOwnProperty(Ze)&&($[Ze]=U[Ze]===void 0&&ge!==void 0?ge[Ze]:U[Ze])}var Ze=arguments.length-2;if(Ze===1)$.children=Q;else if(1<Ze){ge=Array(Ze);for(var $e=0;$e<Ze;$e++)ge[$e]=arguments[$e+2];$.children=ge}return{$$typeof:r,type:R.type,key:de,ref:fe,props:$,_owner:ke}},ut.creLine 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 Sp;function Fv(){if(Sp)return Ua;Sp=1;var r=m0(),a=Symbol.for("react.element"),o=Symbol.for("react.fragment"),l=Object.prototype.hasOwnProperty,d=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,f={key:!0,ref:!0,__self:!0,__source:!0};function m(h,x,p){var v,y={},w=null,B=null;p!==void 0&&(w=""+p),x.key!==void 0&&(w=""+x.key),x.ref!==void 0&&(B=x.ref);for(v in x)l.call(x,v)&&!f.hasOwnProperty(v)&&(y[v]=x[v]);if(h&&h.defaultProps)for(v in x=h.defaultProps,x)y[v]===void 0&&(y[v]=x[v]);return{$$typeof:a,type:h,key:w,ref:B,props:y,_owner:d.current}}return Ua.Fragment=o,Ua.jsx=m,Ua.jsxs=m,Ua}var Bp;function Nv(){return Bp||(Bp=1,Df.exports=Fv()),Df.exports}var E=Nv(),F=m0();const Ce=$s(F),A0=Dv({__proto__:null,default:Ce},[F]);var Bu={},Ff={exports:{}},Zn={},Nf={exports:{}},Lf={};/**
* @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 Pp;function Lv(){return Pp||(Pp=1,(function(r){function a(G,Y){var q=G.length;G.push(Y);e:for(;0<q;){var R=q-1>>>1,U=G[R];if(0<d(U,Y))G[R]=Y,G[q]=U,q=R;else break e}}function o(G){return G.length===0?null:G[0]}function l(G){if(G.length===0)return null;var Y=G[0],q=G.pop();if(q!==Y){G[0]=q;e:for(var R=0,U=G.length,Q=U>>>1;R<Q;){var $=2*(R+1)-1,de=G[$],fe=$+1,ke=G[fe];if(0>d(de,q))fe<U&&0>d(ke,de)?(G[R]=ke,G[fe]=q,R=fe):(G[R]=de,G[$]=q,R=$);else if(fe<U&&0>d(ke,q))G[R]=ke,G[fe]=q,R=fe;else break e}}return Y}function d(G,Y){var q=G.sortIndex-Y.sortIndex;return q!==0?q:G.id-Y.id}if(typeof performance=="object"&&typeof performance.now=="function"){var f=performance;r.unstable_now=function(){return f.now()}}else{var m=Date,h=m.now();r.unstable_now=function(){return m.now()-h}}var x=[],p=[],v=1,y=null,w=3,B=!1,D=!1,C=!1,k=typeof setTimeout=="function"?setTimeout:null,P=typeof clearTimeout=="function"?clearTimeout:null,T=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function S(G){for(var Y=o(p);Y!==null;){if(Y.callback===null)l(p);else if(Y.startTime<=G)l(p),Y.sortIndex=Y.expirationTime,a(x,Y);else break;Y=o(p)}}function N(G){if(C=!1,S(G),!D)if(o(x)!==null)D=!0,ae(I);else{var Y=o(p);Y!==null&&pe(N,Y.startTime-G)}}function I(G,Y){D=!1,C&&(C=!1,P(z),z=-1),B=!0;var q=w;try{for(S(Y),y=o(x);y!==null&&(!(y.expirationTime>Y)||G&&!V());){var R=y.callback;if(typeof R=="function"){y.callback=null,w=y.priorityLevel;var U=R(y.expirationTime<=Y);Y=r.unstable_now(),typeof U=="function"?y.callback=U:y===o(x)&&l(x),S(Y)}else l(x);y=o(x)}if(y!==null)var Q=!0;else{var $=o(p);$!==null&&pe(N,$.startTime-Y),Q=!1}return Q}finally{y=null,w=q,B=!1}}var j=!1,H=null,z=-1,ee=5,Z=-1;function V(){return!(r.unstable_now()-Z<ee)}function ne(){if(H!==null){var G=r.unstable_now();Z=G;var Y=!0;try{Y=H(!0,G)}finally{Y?J():(j=!1,H=null)}}else j=!1}var J;if(typeof T=="function")J=function(){T(ne)};else if(typeof MessageChannel<"u"){var re=new MessageChannel,he=re.port2;re.port1.onmessage=ne,J=function(){he.postMessage(null)}}else J=function(){k(ne,0)};function ae(G){H=G,j||(j=!0,J())}function pe(G,Y){z=k(function(){G(r.unstable_now())},Y)}r.unstable_IdlePriority=5,r.unstable_ImmediatePriority=1,r.unstable_LowPriority=4,r.unstable_NormalPriority=3,r.unstable_Profiling=null,r.unstable_UserBlockingPriority=2,r.unstable_cancelCallback=function(G){G.callback=null},r.unstable_continueExecution=function(){D||B||(D=!0,ae(I))},r.unstable_forceFrameRate=function(G){0>G||125<G?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):ee=0<G?Math.floor(1e3/G):5},r.unstable_getCurrentPriorityLevel=function(){return w},r.unstable_getFirstCallbackNode=function(){return o(x)},r.unstable_next=function(G){switch(w){case 1:case 2:case 3:var Y=3;break;default:Y=w}var q=w;w=Y;try{return G()}finally{w=q}},r.unstable_pauseExecution=function(){},r.unstable_requestPaint=function(){},r.unstable_runWithPriority=function(G,Y){switch(G){case 1:case 2:case 3:case 4:case 5:break;default:G=3}var q=w;w=G;try{return Y()}finally{w=q}},r.unstable_scheduleCallback=function(G,Y,q){var R=r.unstable_now();switch(typeof q=="object"&&q!==null?(q=q.delay,q=typeof q=="number"&&0<q?R+q:R):q=R,G){case 1:var U=-1;break;case 2:U=250;break;case 5:U=1073741823;break;case 4:U=1e4;break;default:U=5e3}return U=q+U,G={id:v++,callback:Y,priorityLevel:G,startTime:q,expirationTime:U,sortIndex:-1},q>R?(G.sortIndex=q,a(p,G),o(x)===null&&G===o(p)&&(C?(P(z),z=-1):C=!0,pe(N,q-R))):(G.sortIndex=U,a(x,G),D||B||(D=!0,ae(I))),G},r.unstable_shouldYield=V,r.unstable_wrapCallback=function(G){var Y=w;return function(){var q=w;w=Y;try{return G.apply(this,arguments)}finally{w=q}}}})(Lf)),Lf}var Tp;function Mv(){return Tp||(Tp=1,Nf.exports=Lv()),Nf.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 Dp;function Iv(){if(Dp)return Zn;Dp=1;var r=m0(),a=Mv();function o(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,s=1;s<arguments.length;s++)n+="&args[]="+encodeURIComponent(arguments[s]);return"Minified React error #"+e+"; visit "+n+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var l=new Set,d={};function f(e,n){m(e,n),m(e+"Capture",n)}function m(e,n){for(d[e]=n,e=0;e<n.length;e++)l.add(n[e])}var h=!(typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),x=Object.prototype.hasOwnProperty,p=/^[: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]*$/,v={},y={};function w(e){return x.call(y,e)?!0:x.call(v,e)?!1:p.test(e)?y[e]=!0:(v[e]=!0,!1)}function B(e,n,s,c){if(s!==null&&s.type===0)return!1;switch(typeof n){case"function":case"symbol":return!0;case"boolean":return c?!1:s!==null?!s.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function D(e,n,s,c){if(n===null||typeof n>"u"||B(e,n,s,c))return!0;if(c)return!1;if(s!==null)switch(s.type){case 3:return!n;case 4:return n===!1;case 5:return isNaN(n);case 6:return isNaN(n)||1>n}return!1}function C(e,n,s,c,g,_,M){this.acceptsBooleans=n===2||n===3||n===4,this.attributeName=c,this.attributeNamespace=g,this.mustUseProperty=s,this.propertyName=e,this.type=n,this.sanitizeURL=_,this.removeEmptyString=M}var k={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){k[e]=new C(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var n=e[0];k[n]=new C(n,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){k[e]=new C(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){k[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){k[e]=new C(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){k[e]=new C(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){k[e]=new C(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){k[e]=new C(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){k[e]=new C(e,5,!1,e.toLowerCase(),null,!1,!1)});var P=/[\-:]([a-z])/g;function T(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 n=e.replace(P,T);k[n]=new C(n,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var n=e.replace(P,T);k[n]=new C(n,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var n=e.replace(P,T);k[n]=new C(n,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){k[e]=new C(e,1,!1,e.toLowerCase(),null,!1,!1)}),k.xlinkHref=new C("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){k[e]=new C(e,1,!1,e.toLowerCase(),null,!0,!0)});function S(e,n,s,c){var g=k.hasOwnProperty(n)?k[n]:null;(g!==null?g.type!==0:c||!(2<n.length)||n[0]!=="o"&&n[0]!=="O"||n[1]!=="n"&&n[1]!= Line truncated
`+R+e}var Q=!1;function $(e,n){if(!e||Q)return"";Q=!0;var s=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(n)if(n=function(){throw Error()},Object.defineProperty(n.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(n,[])}catch(ce){var c=ce}Reflect.construct(e,[],n)}else{try{n.call()}catch(ce){c=ce}e.call(n.prototype)}else{try{throw Error()}catch(ce){c=ce}e()}}catch(ce){if(ce&&c&&typeof ce.stack=="string"){for(var g=ce.stack.split(`
`),_=c.stack.split(`
`),M=g.length-1,W=_.length-1;1<=M&&0<=W&&g[M]!==_[W];)W--;for(;1<=M&&0<=W;M--,W--)if(g[M]!==_[W]){if(M!==1||W!==1)do if(M--,W--,0>W||g[M]!==_[W]){var X=`
`+g[M].replace(" at new "," at ");return e.displayName&&X.includes("<anonymous>")&&(X=X.replace("<anonymous>",e.displayName)),X}while(1<=M&&0<=W);break}}}finally{Q=!1,Error.prepareStackTrace=s}return(e=e?e.displayName||e.name:"")?U(e):""}function de(e){switch(e.tag){case 5:return U(e.type);case 16:return U("Lazy");case 13:return U("Suspense");case 19:return U("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 fe(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 H:return"Fragment";case j:return"Portal";case ee:return"Profiler";case z:return"StrictMode";case J:return"Suspense";case re:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case V:return(e.displayName||"Context")+".Consumer";case Z:return(e._context.displayName||"Context")+".Provider";case ne:var n=e.render;return e=e.displayName,e||(e=n.displayName||n.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case he:return n=e.displayName||null,n!==null?n:fe(e.type)||"Memo";case ae:n=e._payload,e=e._init;try{return fe(e(n))}catch{}}return null}function ke(e){var n=e.type;switch(e.tag){case 24:return"Cache";case 9:return(n.displayName||"Context")+".Consumer";case 10:return(n._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=n.render,e=e.displayName||e.name||"",n.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return n;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return fe(n);case 8:return n===z?"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 n=="function")return n.displayName||n.name||null;if(typeof n=="string")return n}return null}function ge(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function Ze(e){var n=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(n==="checkbox"||n==="radio")}function $e(e){var n=Ze(e)?"checked":"value",s=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),c=""+e[n];if(!e.hasOwnProperty(n)&&typeof s<"u"&&typeof s.get=="function"&&typeof s.set=="function"){var g=s.get,_=s.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return g.call(this)},set:function(M){c=""+M,_.call(this,M)}}),Object.defineProperty(e,n,{enumerable:s.enumerable}),{getValue:function(){return c},setValue:function(M){c=""+M},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}function wt(e){e._valueTracker||(e._valueTracker=$e(e))}function ft(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var s=n.getValue(),c="";return e&&(c=Ze(e)?e.checked?"true":"false":e.value),e=c,e!==s?(n.setValue(e),!0):!1}function Se(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,n){var s=n.checked;return q({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:s??e._wrapperState.initialChecked})}function lt(e,n){var s=n.defaultValue==null?"":n.defaultValue,c=n.checked!=null?n.checked:n.defaultChecked;s=ge(n.value!=null?n.value:s),e._wrapperState={initialChecked:c,initialValue:s,controlled:n.type==="checkbox"||n.type==="radio"?n.checked!=null:n.value!=null}}function Dt(e,n){n=n.checked,n!=null&&S(e,"checked",n,!1)}function xt(e,n){Dt(e,n);var s=ge(n.value),c=n.type;if(s!=null)c==="number"?(s===0&&e.value===""||e.value!=s)&&(e.value=""+s):e.value!==""+s&&(e.value=""+s);else if(c==="submit"||c==="reset"){e.removeAttribute("value");return}n.hasOwnProperty("value")?Ke(e,n.type,s):n.hasOwnProperty("defaultValue")&&Ke(e,n.type,ge(n.defaultValue)),n.checked==null&&n.defaultChecked!=null&&(e.defaultChecked=!!n.defaultChecked)}function it(e,n,s){if(n.hasOwnProperty("value")||n.hasOwnProperty("defaultValue")){var c=n.type;if(!(c!=="submit"&&c!=="reset"||n.value!==void 0&&n.value!==null))return;n=""+e._wrapperState.initialValue,s||n===e.value||(e.value=n),e.defaultValue=n}s=e.name,s!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,s!==""&&(e.name=s)}function Ke(e,n,s){(n!=="number"||Se(e.ownerDocument)!==e)&&(s==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+s&&(e.defaultValue=""+s))}var Xe=Array.isArray;function xe(e,n,s,c){if(e=e.options,n){n={};for(var g=0;g<s.length;g++)n["$"+s[g]]=!0;for(s=0;s<e.length;s++)g=n.hasOwnProperty("$"+e[s].value),e[s].selected!==g&&(e[s].selected=g),g&&c&&(e[s].defaultSelected=!0)}else{for(s=""+ge(s),n=null,g=0;g<e.length;g++){if(e[g].value===s){e[g].selected=!0,c&&(e[g].defaultSelected=!0);return}n!==null||e[g].disabled||(n=e[g])}n!==null&&(n.selected=!0)}}function Te(e,n){if(n.dangerouslySetInnerHT Line truncated
`).replace(K,"")}function ue(e,n,s){if(n=ie(n),ie(e)!==n&&s)throw Error(o(425))}function ve(){}var Pe=null,qe=null;function nt(e,n){return e==="textarea"||e==="noscript"||typeof n.children=="string"||typeof n.children=="number"||typeof n.dangerouslySetInnerHTML=="object"&&n.dangerouslySetInnerHTML!==null&&n.dangerouslySetInnerHTML.__html!=null}var rn=typeof setTimeout=="function"?setTimeout:void 0,Xt=typeof clearTimeout=="function"?clearTimeout:void 0,Fn=typeof Promise=="function"?Promise:void 0,bn=typeof queueMicrotask=="function"?queueMicrotask:typeof Fn<"u"?function(e){return Fn.resolve(null).then(e).catch(Wi)}:rn;function Wi(e){setTimeout(function(){throw e})}function Ba(e,n){var s=n,c=0;do{var g=s.nextSibling;if(e.removeChild(s),g&&g.nodeType===8)if(s=g.data,s==="/$"){if(c===0){e.removeChild(g),Yn(n);return}c--}else s!=="$"&&s!=="$?"&&s!=="$!"||c++;s=g}while(s);Yn(n)}function Ur(e){for(;e!=null;e=e.nextSibling){var n=e.nodeType;if(n===1||n===3)break;if(n===8){if(n=e.data,n==="$"||n==="$!"||n==="$?")break;if(n==="/$")return null}}return e}function Ul(e){e=e.previousSibling;for(var n=0;e;){if(e.nodeType===8){var s=e.data;if(s==="$"||s==="$!"||s==="$?"){if(n===0)return e;n--}else s==="/$"&&n++}e=e.previousSibling}return null}var ui=Math.random().toString(36).slice(2),fr="__reactFiber$"+ui,qi="__reactProps$"+ui,_t="__reactContainer$"+ui,Gi="__reactEvents$"+ui,Cd="__reactListeners$"+ui,Ed="__reactHandles$"+ui;function ci(e){var n=e[fr];if(n)return n;for(var s=e.parentNode;s;){if(n=s[_t]||s[fr]){if(s=n.alternate,n.child!==null||s!==null&&s.child!==null)for(e=Ul(e);e!==null;){if(s=e[fr])return s;e=Ul(e)}return n}e=s,s=e.parentNode}return null}function di(e){return e=e[fr]||e[_t],!e||e.tag!==5&&e.tag!==6&&e.tag!==13&&e.tag!==3?null:e}function fi(e){if(e.tag===5||e.tag===6)return e.stateNode;throw Error(o(33))}function ws(e){return e[qi]||null}var kd=[],bs=-1;function Qi(e){return{current:e}}function Ft(e){0>bs||(e.current=kd[bs],kd[bs]=null,bs--)}function Tt(e,n){bs++,kd[bs]=e.current,e.current=n}var Ki={},Cn=Qi(Ki),zn=Qi(!1),So=Ki;function Cs(e,n){var s=e.type.contextTypes;if(!s)return Ki;var c=e.stateNode;if(c&&c.__reactInternalMemoizedUnmaskedChildContext===n)return c.__reactInternalMemoizedMaskedChildContext;var g={},_;for(_ in s)g[_]=n[_];return c&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=g),g}function jn(e){return e=e.childContextTypes,e!=null}function Zl(){Ft(zn),Ft(Cn)}function G0(e,n,s){if(Cn.current!==Ki)throw Error(o(168));Tt(Cn,n),Tt(zn,s)}function Q0(e,n,s){var c=e.stateNode;if(n=n.childContextTypes,typeof c.getChildContext!="function")return s;c=c.getChildContext();for(var g in c)if(!(g in n))throw Error(o(108,ke(e)||"Unknown",g));return q({},s,c)}function Wl(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Ki,So=Cn.current,Tt(Cn,e),Tt(zn,zn.current),!0}function K0(e,n,s){var c=e.stateNode;if(!c)throw Error(o(169));s?(e=Q0(e,n,So),c.__reactInternalMemoizedMergedChildContext=e,Ft(zn),Ft(Cn),Tt(Cn,e)):Ft(zn),Tt(zn,s)}var hi=null,ql=!1,Sd=!1;function $0(e){hi===null?hi=[e]:hi.push(e)}function Qx(e){ql=!0,$0(e)}function $i(){if(!Sd&&hi!==null){Sd=!0;var e=0,n=ht;try{var s=hi;for(ht=1;e<s.length;e++){var c=s[e];do c=c(!0);while(c!==null)}hi=null,ql=!1}catch(g){throw hi!==null&&(hi=hi.slice(e+1)),vl(ra,$i),g}finally{ht=n,Sd=!1}}return null}var Es=[],ks=0,Gl=null,Ql=0,hr=[],pr=0,Bo=null,pi=1,mi="";function Po(e,n){Es[ks++]=Ql,Es[ks++]=Gl,Gl=e,Ql=n}function Y0(e,n,s){hr[pr++]=pi,hr[pr++]=mi,hr[pr++]=Bo,Bo=e;var c=pi;e=mi;var g=32-tt(c)-1;c&=~(1<<g),s+=1;var _=32-tt(n)+g;if(30<_){var M=g-g%5;_=(c&(1<<M)-1).toString(32),c>>=M,g-=M,pi=1<<32-tt(n)+g|s<<g|c,mi=_+e}else pi=1<<_|s<<g|c,mi=e}function Bd(e){e.return!==null&&(Po(e,1),Y0(e,1,0))}function Pd(e){for(;e===Gl;)Gl=Es[--ks],Es[ks]=null,Ql=Es[--ks],Es[ks]=null;for(;e===Bo;)Bo=hr[--pr],hr[pr]=null,mi=hr[--pr],hr[pr]=null,pi=hr[--pr],hr[pr]=null}var nr=null,rr=null,Mt=!1,kr=null;function X0(e,n){var s=xr(5,null,null,0);s.elementType="DELETED",s.stateNode=n,s.return=e,n=e.deletions,n===null?(e.deletions=[s],e.flags|=16):n.push(s)}function J0(e,n){switch(e.tag){case 5:var s=e.type;return n=n.nodeType!==1||s.toLowerCase()!==n.nodeName.toLowerCase()?null:n,n!==null?(e.stateNode=n,nr=e,rr=Ur(n.firstChild),!0):!1;case 6:return n=e.pendingProps===""||n.nodeType!==3?null:n,n!==null?(e.stateNode=n,nr=e,rr=null,!0):!1;case 13:return n=n.nodeType!==8?null:n,n!==null?(s=Bo!==null?{id:pi,overflow:mi}:null,e.memoizedState={dehydrated:n,treeContext:s,retryLane:1073741824},s=xr(18,null,null,0),s.stateNode=n,s.return=e,e.child=s,nr=e,rr=null,!0):!1;default:return!1}}function Td(e){return(e.mode&1)!==0&&(e.flags&128)===0}function Dd(e){if(Mt){var n=rr;if(n){var s=n;if(!J0(e,n)){if(Td(e))throw Error(o(418));n=Ur(s.nextSibling);var c=nr;n&&J0(e,n)?X0(c,s):(e.flags=e.flags&-4097|2,Mt=!1,nr=e)}}else{if(Td(e))throw Error(o(418));e.flags=e.flags&-4097|2,Mt=!1,nr=e}}}function eh(e){for(e=e.r Line truncated
Error generating stack: `+_.message+`
`+_.stack}return{value:e,source:n,stack:g,digest:null}}function Jd(e,n,s){return{value:e,source:null,stack:s??null,digest:n??null}}function ef(e,n){try{console.error(n.value)}catch(s){setTimeout(function(){throw s})}}var rv=typeof WeakMap=="function"?WeakMap:Map;function Nh(e,n,s){s=gi(-1,s),s.tag=3,s.payload={element:null};var c=n.value;return s.callback=function(){pu||(pu=!0,Af=c),ef(e,n)},s}function Lh(e,n,s){s=gi(-1,s),s.tag=3;var c=e.type.getDerivedStateFromError;if(typeof c=="function"){var g=n.value;s.payload=function(){return c(g)},s.callback=function(){ef(e,n)}}var _=e.stateNode;return _!==null&&typeof _.componentDidCatch=="function"&&(s.callback=function(){ef(e,n),typeof c!="function"&&(eo===null?eo=new Set([this]):eo.add(this));var M=n.stack;this.componentDidCatch(n.value,{componentStack:M!==null?M:""})}),s}function Mh(e,n,s){var c=e.pingCache;if(c===null){c=e.pingCache=new rv;var g=new Set;c.set(n,g)}else g=c.get(n),g===void 0&&(g=new Set,c.set(n,g));g.has(s)||(g.add(s),e=gv.bind(null,e,n,s),n.then(e,e))}function Ih(e){do{var n;if((n=e.tag===13)&&(n=e.memoizedState,n=n!==null?n.dehydrated!==null:!0),n)return e;e=e.return}while(e!==null);return null}function Oh(e,n,s,c,g){return(e.mode&1)===0?(e===n?e.flags|=65536:(e.flags|=128,s.flags|=131072,s.flags&=-52805,s.tag===1&&(s.alternate===null?s.tag=17:(n=gi(-1,1),n.tag=2,Xi(s,n,1))),s.lanes|=1),e):(e.flags|=65536,e.lanes=g,e)}var iv=N.ReactCurrentOwner,Hn=!1;function Nn(e,n,s,c){n.child=e===null?ih(n,null,s,c):Bs(n,e.child,s,c)}function zh(e,n,s,c,g){s=s.render;var _=n.ref;return Ts(n,g),c=Wd(e,n,s,c,_,g),s=qd(),e!==null&&!Hn?(n.updateQueue=e.updateQueue,n.flags&=-2053,e.lanes&=~g,xi(e,n,g)):(Mt&&s&&Bd(n),n.flags|=1,Nn(e,n,c,g),n.child)}function jh(e,n,s,c,g){if(e===null){var _=s.type;return typeof _=="function"&&!bf(_)&&_.defaultProps===void 0&&s.compare===null&&s.defaultProps===void 0?(n.tag=15,n.type=_,Hh(e,n,_,c,g)):(e=yu(s.type,null,c,n,n.mode,g),e.ref=n.ref,e.return=n,n.child=e)}if(_=e.child,(e.lanes&g)===0){var M=_.memoizedProps;if(s=s.compare,s=s!==null?s:jr,s(M,c)&&e.ref===n.ref)return xi(e,n,g)}return n.flags|=1,e=io(_,c),e.ref=n.ref,e.return=n,n.child=e}function Hh(e,n,s,c,g){if(e!==null){var _=e.memoizedProps;if(jr(_,c)&&e.ref===n.ref)if(Hn=!1,n.pendingProps=c=_,(e.lanes&g)!==0)(e.flags&131072)!==0&&(Hn=!0);else return n.lanes=e.lanes,xi(e,n,g)}return tf(e,n,s,c,g)}function Vh(e,n,s){var c=n.pendingProps,g=c.children,_=e!==null?e.memoizedState:null;if(c.mode==="hidden")if((n.mode&1)===0)n.memoizedState={baseLanes:0,cachePool:null,transitions:null},Tt(Ns,ir),ir|=s;else{if((s&1073741824)===0)return e=_!==null?_.baseLanes|s:s,n.lanes=n.childLanes=1073741824,n.memoizedState={baseLanes:e,cachePool:null,transitions:null},n.updateQueue=null,Tt(Ns,ir),ir|=e,null;n.memoizedState={baseLanes:0,cachePool:null,transitions:null},c=_!==null?_.baseLanes:s,Tt(Ns,ir),ir|=c}else _!==null?(c=_.baseLanes|s,n.memoizedState=null):c=s,Tt(Ns,ir),ir|=c;return Nn(e,n,g,s),n.child}function Uh(e,n){var s=n.ref;(e===null&&s!==null||e!==null&&e.ref!==s)&&(n.flags|=512,n.flags|=2097152)}function tf(e,n,s,c,g){var _=jn(s)?So:Cn.current;return _=Cs(n,_),Ts(n,g),s=Wd(e,n,s,c,_,g),c=qd(),e!==null&&!Hn?(n.updateQueue=e.updateQueue,n.flags&=-2053,e.lanes&=~g,xi(e,n,g)):(Mt&&c&&Bd(n),n.flags|=1,Nn(e,n,s,g),n.child)}function Zh(e,n,s,c,g){if(jn(s)){var _=!0;Wl(n)}else _=!1;if(Ts(n,g),n.stateNode===null)uu(e,n),Rh(n,s,c),Xd(n,s,c,g),c=!0;else if(e===null){var M=n.stateNode,W=n.memoizedProps;M.props=W;var X=M.context,ce=s.contextType;typeof ce=="object"&&ce!==null?ce=mr(ce):(ce=jn(s)?So:Cn.current,ce=Cs(n,ce));var _e=s.getDerivedStateFromProps,we=typeof _e=="function"||typeof M.getSnapshotBeforeUpdate=="function";we||typeof M.UNSAFE_componentWillReceiveProps!="function"&&typeof M.componentWillReceiveProps!="function"||(W!==c||X!==ce)&&Fh(n,M,c,ce),Yi=!1;var ye=n.memoizedState;M.state=ye,eu(n,c,M,g),X=n.memoizedState,W!==c||ye!==X||zn.current||Yi?(typeof _e=="function"&&(Yd(n,s,_e,c),X=n.memoizedState),(W=Yi||Dh(n,s,W,c,ye,X,ce))?(we||typeof M.UNSAFE_componentWillMount!="function"&&typeof M.componentWillMount!="function"||(typeof M.componentWillMount=="function"&&M.componentWillMount(),typeof M.UNSAFE_componentWillMount=="function"&&M.UNSAFE_componentWillMount()),typeof M.componentDidMount=="function"&&(n.flags|=4194308)):(typeof M.componentDidMount=="function"&&(n.flags|=4194308),n.memoizedProps=c,n.memoizedState=X),M.props=c,M.state=X,M.context=ce,c=W):(typeof M.componentDidMount=="function"&&(n.flags|=4194308),c=!1)}else{M=n.stateNode,sh(e,n),W=n.memoizedProps,ce=n.type===n.elementType?W:Sr(n.type,W),M.props=ce,we=n.pendingProps,ye=M.context,X=s.contextType,typeof X=="object"&&X!==null?X=mr(X):(X=jn(s)?So:Cn.current,X=Cs(n,X));var Fe=s.getDerivedStateFromProps;(_e=typeof Fe=="function"||typeof M.getSnapshotBeforeUpdate=="function")||typeof M.UNSAFE_componentWillReceiveProps!="function"&&typeof M.componentWillReceiveProps!="function"||(W!==we||ye!==X)&&Fh(n,M,c,X),Yi=!1,ye=n.m Line truncated
`)}function Is(r,a,o){const l=Math.floor(Date.now()/1e3);return{id:-Date.now(),type:"PRIV",conversation_key:r,text:a,sender_timestamp:l,received_at:l,path:null,txt_type:0,signature:null,outgoing:o,acked:1}}function Wv(r){const a=F.useRef(null),o=F.useRef(null),l=F.useCallback(()=>{o.current!==null&&(clearInterval(o.current),o.current=null),a.current=null},[]),d=F.useCallback(async()=>{const m=a.current;if(!m)return;let h=null,x=null;for(let p=0;p<2;p++)try{h=await st.requestTelemetry(m.conversationId,"");break}catch(v){x=v instanceof Error?v:new Error("Unknown error"),p===0&&await new Promise(y=>setTimeout(y,2e3))}if(h){const p=Is(m.conversationId,Zv(m,h),!1);r(v=>[...v,p])}else{const p=Is(m.conversationId,`Duty cycle poll failed after retry: ${(x==null?void 0:x.message)??"Unknown error"}`,!1);r(v=>[...v,p])}},[r]),f=F.useCallback(async(m,h)=>{const x=m.trim().toLowerCase();if(x==="dutycycle_start"){l();let p=null,v=null;for(let B=0;B<2;B++)try{p=await st.requestTelemetry(h,"");break}catch(D){v=D instanceof Error?D:new Error("Unknown error"),B===0&&await new Promise(C=>setTimeout(C,2e3))}if(!p){const B=Is(h,`Failed to start duty cycle tracking after retry: ${(v==null?void 0:v.message)??"Unknown error"}`,!1);return r(D=>[...D,B]),!0}const y=Math.floor(Date.now()/1e3);a.current={startTime:y,uptime:p.uptime_seconds,txAirtime:p.airtime_seconds,rxAirtime:p.rx_airtime_seconds,sentFlood:p.sent_flood,sentDirect:p.sent_direct,recvFlood:p.recv_flood,recvDirect:p.recv_direct,conversationId:h};const w=Is(h,`Airtime/duty cycle statistics gathering begins at ${y}. Logs will follow every 5 minutes. To stop, run dutycycle_stop or navigate away from this conversation.`,!1);return r(B=>[...B,w]),o.current=window.setInterval(d,Vv),!0}if(x==="dutycycle_stop"){if(a.current&&a.current.conversationId===h){await d(),l();const p=Is(h,"Airtime/duty cycle statistics gathering stopped.",!1);r(v=>[...v,p])}else{const p=Is(h,"Duty cycle tracking is not active.",!1);r(v=>[...v,p])}return!0}return!1},[r,l,d]);return F.useEffect(()=>()=>{o.current!==null&&clearInterval(o.current)},[]),{handleAirtimeCommand:f,stopTracking:l}}function Hu(r){if(r<60)return`${r}s`;const a=Math.floor(r/86400),o=Math.floor(r%86400/3600),l=Math.floor(r%3600/60);return a>0?o>0&&l>0?`${a}d${o}h${l}m`:o>0?`${a}d${o}h`:l>0?`${a}d${l}m`:`${a}d`:o>0?l>0?`${o}h${l}m`:`${o}h`:`${l}m`}function qv(r){return["Telemetry",`Battery Voltage: ${r.battery_volts.toFixed(3)}V`,`Uptime: ${Hu(r.uptime_seconds)}`,`TX Airtime: ${Hu(r.airtime_seconds)}`,`RX Airtime: ${Hu(r.rx_airtime_seconds)}`,"",`Noise Floor: ${r.noise_floor_dbm} dBm`,`Last RSSI: ${r.last_rssi_dbm} dBm`,`Last SNR: ${r.last_snr_db.toFixed(1)} dB`,"",`Packets: ${r.packets_received.toLocaleString()} rx / ${r.packets_sent.toLocaleString()} tx`,`Flood: ${r.recv_flood.toLocaleString()} rx / ${r.sent_flood.toLocaleString()} tx`,`Direct: ${r.recv_direct.toLocaleString()} rx / ${r.sent_direct.toLocaleString()} tx`,`Duplicates: ${r.flood_dups.toLocaleString()} flood / ${r.direct_dups.toLocaleString()} direct`,"",`TX Queue: ${r.tx_queue_len}`,`Debug Flags: ${r.full_events}`].join(`
`)}function Gv(r){if(r.length===0)return`Neighbors
No neighbors reported`;const a=[...r].sort((l,d)=>d.snr-l.snr),o=[`Neighbors (${a.length})`];for(const l of a){const d=l.name||l.pubkey_prefix,f=l.snr>=0?`+${l.snr.toFixed(1)}`:l.snr.toFixed(1);o.push(`${d}, ${f} dB [${Hu(l.last_heard_seconds)} ago]`)}return o.join(`
`)}function Qv(r){if(r.length===0)return`ACL
No ACL entries`;const a=[`ACL (${r.length})`];for(const o of r){const l=o.name||o.pubkey_prefix;a.push(`${l}: ${o.permission_name}`)}return a.join(`
`)}function zo(r,a,o,l=0){const d=Math.floor(Date.now()/1e3);return{id:-Date.now()-l,type:"PRIV",conversation_key:r,text:a,sender_timestamp:d,received_at:d,path:null,txt_type:0,signature:null,outgoing:o,acked:1}}function Kv(r,a,o){const[l,d]=F.useState(!1),{handleAirtimeCommand:f,stopTracking:m}=Wv(o);F.useEffect(()=>{d(!1),m()},[r==null?void 0:r.id,m]);const h=F.useMemo(()=>{if(!r||r.type!=="contact")return!1;const v=a.find(y=>y.public_key===r.id);return(v==null?void 0:v.type)===zc},[r,a]),x=F.useCallback(async v=>{if(!(!r||r.type!=="contact")&&h)try{const y=await st.requestTelemetry(r.id,v),w=zo(r.id,qv(y),!1,0),B=zo(r.id,Gv(y.neighbors),!1,1),D=zo(r.id,Qv(y.acl),!1,2);o(C=>[...C,w,B,D]),d(!0)}catch(y){const w=zo(r.id,`Telemetry request failed: ${y instanceof Error?y.message:"Unknown error"}`,!1,0);o(B=>[...B,w])}},[r,h,o]),p=F.useCallback(async v=>{if(!r||r.type!=="contact"||!h||!l||await f(v,r.id))return;const w=zo(r.id,`> ${v}`,!0,0);o(B=>[...B,w]);try{const B=await st.sendRepeaterCommand(r.id,v),D=zo(r.id,B.response,!1,1);B.sender_timestamp&&(D.sender_timestamp=B.sender_timestamp),o(C=>[...C,D])}catch(B){const D=zo(r.id,`Command failed: ${B instanceof Error?B.message:"Unknown error"}`,!1,1);o(C=>[...C,D])}},[r,h,l,o,f]);return{repeaterLoggedIn:l,activeContactIsRepeater:h,handleTelemetryRequest:x,handleRepeaterCommand:p}}const $v=12;function Gs(r){return r.slice(0,$v)}function MA(r,a){return!r||!a?!1:Gs(r)===Gs(a)}function Ci(r,a){return r||Gs(a)}const Jf="remoteterm-lastMessageTime";function IA(r){try{const a=localStorage.getItem(r);return a?JSON.parse(a):{}}catch{return{}}}function Yv(r,a){try{localStorage.setItem(r,JSON.stringify(a))}catch{}}function Lp(){return IA(Jf)}function Mf(r,a){const o=IA(Jf);return(!o[r]||a>o[r])&&(o[r]=a,Yv(Jf,o)),o}function Rr(r,a){return r==="channel"?`channel-${a}`:`contact-${Gs(a)}`}function Mp(r,a){if(!a)return!1;const o=a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`@\\[${o}\\]`,"i").test(r)}function Xv(r,a,o,l=null){const[d,f]=F.useState({}),[m,h]=F.useState({}),[x,p]=F.useState(Lp),v=F.useRef(l);F.useEffect(()=>{v.current=l},[l]);const y=F.useRef(new Set),w=F.useRef(new Set);F.useEffect(()=>{const P=r.filter(N=>!y.current.has(N.key)),T=a.filter(N=>N.public_key&&!w.current.has(N.public_key));if(P.length===0&&T.length===0)return;P.forEach(N=>y.current.add(N.key)),T.forEach(N=>w.current.add(N.public_key)),(async()=>{const N=[...P.map(I=>({type:"CHAN",conversation_key:I.key})),...T.map(I=>({type:"PRIV",conversation_key:I.public_key}))];if(N.length!==0)try{const I=await st.getMessagesBulk(N,g0),j={},H={},z={};for(const ee of P){const Z=I[`CHAN:${ee.key}`]||[];if(Z.length>0){const V=Rr("channel",ee.key),ne=ee.last_read_at||0,J=Z.filter(he=>!he.outgoing&&he.received_at>ne);J.length>0&&(j[V]=J.length,J.some(he=>Mp(he.text,v.current))&&(H[V]=!0));const re=Math.max(...Z.map(he=>he.received_at));z[V]=re,Mf(V,re)}}for(const ee of T){const Z=I[`PRIV:${ee.public_key}`]||[];if(Z.length>0){const V=Rr("contact",ee.public_key),ne=ee.last_read_at||0,J=Z.filter(he=>!he.outgoing&&he.received_at>ne);J.length>0&&(j[V]=J.length,J.some(he=>Mp(he.text,v.current))&&(H[V]=!0));const re=Math.max(...Z.map(he=>he.received_at));z[V]=re,Mf(V,re)}}Object.keys(j).length>0&&f(ee=>({...ee,...j})),Object.keys(H).length>0&&h(ee=>({...ee,...H})),p(Lp())}catch(I){console.error("Failed to fetch messages bulk:",I)}})()},[r,a]),F.useEffect(()=>{if(o&&o.type!=="raw"&&o.type!=="map"){const P=Rr(o.type,o.id);f(T=>{if(T[P]){const S={...T};return delete S[P],S}return T}),h(T=>{if(T[P]){const S={...T};return delete S[P],S}return T}),o.type==="channel"?st.markChannelRead(o.id).catch(T=>{console.error("Failed to mark channel as read on server:",T)}):o.type==="contact"&&st.markContactRead(o.id).catch(T=>{console.error("Failed to mark contact as read on server:",T)})}},[o]);const B=F.useCallback((P,T)=>{f(S=>({...S,[P]:(S[P]||0)+1})),T&&h(S=>({...S,[P]:!0}))},[]),D=F.useCallback(()=>{f({}),h({}),st.markAllRead().catch(P=>{console.error("Failed to mark all as read on server:",P)})},[]),C=F.useCallback(P=>{if(P.type==="raw"||P.type==="map")return;const T=Rr(P.type,P.id);f(S=>{if(S[T]){const N={...S};return delete N[T],N}return S}),h(S=>{if(S[T]){const N={...S};return delete N[T],N}return S}),P.type==="channel"?st.markChannelRead(P.id).catch(S=>{console.error("Failed to mark channel as read on server:",S)}):P.type==="contact"&&st.markContactRead(P.id).catch(S=>{console.error("Failed to mark contact as read on server:",S)})},[]),k=F.useCallback(P=>{let T=null;if(P.type==="CHAN"&&P.conversation_key?T=Rr("channel",P.conversation_key):P.type==="PRIV"&&P.conversation_key&&(T=Rr("contact",P.conversation_key)),T){const S=P.received_at||Math.floor(Date.now()/1e3),N=Mf(T,S);p(N)}},[]);return{unreadCounts:d,mentions:m,lastMessageTimes:x,incrementUnread:B,markAllRead:D,markConversationRead:C,trackNewMessage:k}}var x0=LA();const OA=$s(x0);function Jv(r){if(typeof document>"u")return;let a=document.head||document.getElem 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 By=r=>r.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),Py=r=>r.replace(/^([A-Z])|[\s-_]+(\w)/g,(a,o,l)=>l?l.toUpperCase():o.toLowerCase()),zp=r=>{const a=Py(r);return a.charAt(0).toUpperCase()+a.slice(1)},zA=(...r)=>r.filter((a,o,l)=>!!a&&a.trim()!==""&&l.indexOf(a)===o).join(" ").trim(),Ty=r=>{for(const a in r)if(a.startsWith("aria-")||a==="role"||a==="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 Dy={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 Ry=F.forwardRef(({color:r="currentColor",size:a=24,strokeWidth:o=2,absoluteStrokeWidth:l,className:d="",children:f,iconNode:m,...h},x)=>F.createElement("svg",{ref:x,...Dy,width:a,height:a,stroke:r,strokeWidth:l?Number(o)*24/Number(a):o,className:zA("lucide",d),...!f&&!Ty(h)&&{"aria-hidden":"true"},...h},[...m.map(([p,v])=>F.createElement(p,v)),...Array.isArray(f)?f:[f]]));/**
* @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 v0=(r,a)=>{const o=F.forwardRef(({className:l,...d},f)=>F.createElement(Ry,{ref:f,iconNode:a,className:zA(`lucide-${By(zp(r))}`,`lucide-${r}`,l),...d}));return o.displayName=zp(r),o};/**
* @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 Fy=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],Ny=v0("check",Fy);/**
* @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 Ly=[["path",{d:"M4 5h16",key:"1tepv9"}],["path",{d:"M4 12h16",key:"1lakjw"}],["path",{d:"M4 19h16",key:"1djgab"}]],My=v0("menu",Ly);/**
* @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 Iy=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],jA=v0("x",Iy);function Oy({health:r,config:a,onSettingsClick:o,onMenuClick:l}){const d=(r==null?void 0:r.radio_connected)??!1,[f,m]=F.useState(!1),h=async()=>{m(!0);try{const x=await st.reconnectRadio();x.connected&&kt.success("Reconnected",{description:x.message})}catch(x){kt.error("Reconnection failed",{description:x instanceof Error?x.message:"Check radio connection and power"})}finally{m(!1)}};return E.jsxs("div",{className:"flex items-center gap-4 px-4 py-2 bg-[#252525] border-b border-[#333] text-xs",children:[l&&E.jsx("button",{onClick:l,className:"md:hidden p-1 bg-transparent border-none text-[#e0e0e0] cursor-pointer","aria-label":"Open menu",children:E.jsx(My,{className:"h-5 w-5"})}),E.jsx("h1",{className:"hidden lg:block text-base font-semibold mr-auto",children:"RemoteTerm"}),E.jsxs("div",{className:"flex items-center gap-1 text-[#888]",children:[E.jsx("div",{className:`w-2 h-2 rounded-full ${d?"bg-[#4caf50]":"bg-[#666]"}`}),E.jsx("span",{className:"hidden lg:inline text-[#e0e0e0]",children:d?"Connected":"Disconnected"})]}),a&&E.jsx("div",{className:"hidden lg:flex items-center gap-1 text-[#888]",children:E.jsx("span",{className:"text-[#e0e0e0]",children:a.name||"Unnamed"})}),E.jsx("div",{className:"flex-1 lg:hidden"}),!d&&E.jsx("button",{onClick:h,disabled:f,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:f?"Reconnecting...":"Reconnect"}),E.jsxs("button",{onClick:o,className:"px-3 py-1 bg-[#333] border border-[#444] text-[#e0e0e0] rounded text-xs cursor-pointer hover:bg-[#444]",children:[E.jsx("span",{role:"img","aria-label":"Settings",children:"🔧"})," ","Radio & Config"]})]})}const t0=2,zy={text:"🛜",background:"#444444",textColor:"#ffffff"};function jy(r){let a=0;for(let o=0;o<r.length;o++){const l=r.charCodeAt(o);a=(a<<5)-a+l,a=a&a}return Math.abs(a)}const Hy=/[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]|[\u{1F600}-\u{1F64F}]|[\u{1F680}-\u{1F6FF}]|[\u{1F1E0}-\u{1F1FF}]/u;function Vy(r,a){if(!r)return a.slice(0,2).toUpperCase();const o=r.match(Hy);if(o)return o[0];const l=r.match(/[a-zA-Z]/g);if(!l||l.length===0)return a.slice(0,2).toUpperCase();const d=r.indexOf(" ");if(d!==-1){const f=l[0],m=r.slice(d+1).match(/[a-zA-Z]/);if(m)return(f+m[0]).toUpperCase()}return l[0].toUpperCase()}function Uy(r){const a=jy(r),o=a%360,l=50+(a>>8)%30,d=35+(a>>16)%20,f=`hsl(${o}, ${l}%, ${d}%)`,m=d<45?"#ffffff":"#000000";return{background:f,text:m}}function Zy(r,a,o){if(o===t0)return zy;const l=Vy(r,a),d=Uy(a);return{text:l,background:d.background,textColor:d.text}}function n0({name:r,publicKey:a,size:o=28,contactType:l}){const d=Zy(r,a,l);return E.jsx("div",{className:"flex items-center justify-center rounded-full font-semibold flex-shrink-0 select-none",style:{backgroundColor:d.background,color:d.textColor,width:o,height:o,fontSize:o*.45},children:d.text})}const HA="remoteterm-favorites";function jc(){try{const r=localStorage.getItem(HA);return r?JSON.parse(r):[]}catch{return[]}}function VA(r){try{localStorage.setItem(HA,JSON.stringify(r))}catch{}}function Wy(r,a){const o=jc();if(o.some(d=>d.type===r&&d.id===a))return o;const l=[...o,{type:r,id:a}];return VA(l),l}function qy(r,a){const l=jc().filter(d=>!(d.type===r&&d.id===a));return VA(l),l}function Us(r,a,o){return r.some(l=>l.type===a&&l.id===o)}function Gy(r,a){return jc().some(l=>l.type===r&&l.id===a)?qy(r,a):Wy(r,a)}function UA(r){var a,o,l="";if(typeof r=="string"||typeof r=="number")l+=r;else if(typeof r=="object")if(Array.isArray(r)){var d=r.length;for(a=0;a<d;a++)r[a]&&(o=UA(r[a]))&&(l&&(l+=" "),l+=o)}else for(o in r)r[o]&&(l&&(l+=" "),l+=o);return l}function ZA(){for(var r,a,o=0,l="",d=arguments.length;o<d;o++)(r=arguments[o])&&(a=UA(r))&&(l&&(l+=" "),l+=a);return l}const Qy=(r,a)=>{const o=new Array(r.length+a.length);for(let l=0;l<r.length;l++)o[l]=r[l];for(let l=0;l<a.length;l++)o[r.length+l]=a[l];return o},Ky=(r,a)=>({classGroupId:r,validator:a}),WA=(r=new Map,a=null,o)=>({nextPart:r,validators:a,classGroupId:o}),Dc="-",jp=[],$y="arbitrary..",Yy=r=>{const a=Jy(r),{conflictingClassGroups:o,conflictingClassGroupModifiers:l}=r;return{getClassGroupId:m=>{if(m.startsWith("[")&&m.endsWith("]"))return Xy(m);const h=m.split(Dc),x=h[0]===""&&h.length>1?1:0;return qA(h,x,a)},getConflictingClassGroupIds:(m,h)=>{if(h){const x=l[m],p=o[m];return x?p?Qy(p,x):x:p||jp}return o[m]||jp}}},qA=(r,a,o)=>{if(r.length-a===0)return o.classGroupId;const d=r[a],f=o.nextPart.get(d);if(f){const p=qA(r,a+1,f);if(p)return p}const m=o.validators;if(m===null)return;const h=a===0?r.join(Dc):r.slice(a).join(Dc),x=m.length;for(let p=0;p<x;p++){const v=m[p];if(v.validator(h))return v.classGroupId}},Xy=r=>r.slice(1,-1).indexOf(":")===-1?void 0:(()=>{const a=r.slice(1,-1),o=a.indexOf(":"),l=a.slice(0,o);return l?$y+l:void 0})(),Jy=r=>{conLine truncated
.`.concat(L1,` {
overflow: hidden `).concat(l,`;
padding-right: `).concat(h,"px ").concat(l,`;
}
body[`).concat(Ws,`] {
overflow: hidden `).concat(l,`;
overscroll-behavior: contain;
`).concat([a&&"position: relative ".concat(l,";"),o==="margin"&&`
padding-left: `.concat(d,`px;
padding-top: `).concat(f,`px;
padding-right: `).concat(m,`px;
margin-left:0;
margin-top:0;
margin-right: `).concat(h,"px ").concat(l,`;
`),o==="padding"&&"padding-right: ".concat(h,"px ").concat(l,";")].filter(Boolean).join(""),`
}
.`).concat(Uu,` {
right: `).concat(h,"px ").concat(l,`;
}
.`).concat(Zu,` {
margin-right: `).concat(h,"px ").concat(l,`;
}
.`).concat(Uu," .").concat(Uu,` {
right: 0 `).concat(l,`;
}
.`).concat(Zu," .").concat(Zu,` {
margin-right: 0 `).concat(l,`;
}
body[`).concat(Ws,`] {
`).concat(M1,": ").concat(h,`px;
}
`)},rm=function(){var r=parseInt(document.body.getAttribute(Ws)||"0",10);return isFinite(r)?r:0},tw=function(){F.useEffect(function(){return document.body.setAttribute(Ws,(rm()+1).toString()),function(){var r=rm()-1;r<=0?document.body.removeAttribute(Ws):document.body.setAttribute(Ws,r.toString())}},[])},nw=function(r){var a=r.noRelative,o=r.noImportant,l=r.gapMode,d=l===void 0?"margin":l;tw();var f=F.useMemo(function(){return X1(d)},[d]);return F.createElement(J1,{styles:ew(f,!a,d,o?"":"!important")})},o0=!1;if(typeof window<"u")try{var Iu=Object.defineProperty({},"passive",{get:function(){return o0=!0,!0}});window.addEventListener("test",Iu,Iu),window.removeEventListener("test",Iu,Iu)}catch{o0=!1}var zs=o0?{passive:!1}:!1,rw=function(r){return r.tagName==="TEXTAREA"},pg=function(r,a){if(!(r instanceof Element))return!1;var o=window.getComputedStyle(r);return o[a]!=="hidden"&&!(o.overflowY===o.overflowX&&!rw(r)&&o[a]==="visible")},iw=function(r){return pg(r,"overflowY")},ow=function(r){return pg(r,"overflowX")},im=function(r,a){var o=a.ownerDocument,l=a;do{typeof ShadowRoot<"u"&&l instanceof ShadowRoot&&(l=l.host);var d=mg(r,l);if(d){var f=Ag(r,l),m=f[1],h=f[2];if(m>h)return!0}l=l.parentNode}while(l&&l!==o.body);return!1},sw=function(r){var a=r.scrollTop,o=r.scrollHeight,l=r.clientHeight;return[a,o,l]},aw=function(r){var a=r.scrollLeft,o=r.scrollWidth,l=r.clientWidth;return[a,o,l]},mg=function(r,a){return r==="v"?iw(a):ow(a)},Ag=function(r,a){return r==="v"?sw(a):aw(a)},lw=function(r,a){return r==="h"&&a==="rtl"?-1:1},uw=function(r,a,o,l,d){var f=lw(r,window.getComputedStyle(a).direction),m=f*l,h=o.target,x=a.contains(h),p=!1,v=m>0,y=0,w=0;do{if(!h)break;var B=Ag(r,h),D=B[0],C=B[1],k=B[2],P=C-k-f*D;(D||P)&&mg(r,h)&&(y+=P,w+=D);var T=h.parentNode;h=T&&T.nodeType===Node.DOCUMENT_FRAGMENT_NODE?T.host:T}while(!x&&h!==document.body||x&&(a.contains(h)||a===h));return(v&&Math.abs(y)<1||!v&&Math.abs(w)<1)&&(p=!0),p},Ou=function(r){return"changedTouches"in r?[r.changedTouches[0].clientX,r.changedTouches[0].clientY]:[0,0]},om=function(r){return[r.deltaX,r.deltaY]},sm=function(r){return r&&"current"in r?r.current:r},cw=function(r,a){return r[0]===a[0]&&r[1]===a[1]},dw=function(r){return`
.block-interactivity-`.concat(r,` {pointer-events: none;}
.allow-interactivity-`).concat(r,` {pointer-events: all;}
`)},fw=0,js=[];function hw(r){var a=F.useRef([]),o=F.useRef([0,0]),l=F.useRef(),d=F.useState(fw++)[0],f=F.useState(hg)[0],m=F.useRef(r);F.useEffect(function(){m.current=r},[r]),F.useEffect(function(){if(r.inert){document.body.classList.add("block-interactivity-".concat(d));var C=N1([r.lockRef.current],(r.shards||[]).map(sm),!0).filter(Boolean);return C.forEach(function(k){return k.classList.add("allow-interactivity-".concat(d))}),function(){document.body.classList.remove("block-interactivity-".concat(d)),C.forEach(function(k){return k.classList.remove("allow-interactivity-".concat(d))})}}},[r.inert,r.lockRef.current,r.shards]);var h=F.useCallback(function(C,k){if("touches"in C&&C.touches.length===2||C.type==="wheel"&&C.ctrlKey)return!m.current.allowPinchZoom;var P=Ou(C),T=o.current,S="deltaX"in C?C.deltaX:T[0]-P[0],N="deltaY"in C?C.deltaY:T[1]-P[1],I,j=C.target,H=Math.abs(S)>Math.abs(N)?"h":"v";if("touches"in C&&H==="h"&&j.type==="range")return!1;var z=window.getSelection(),ee=z&&z.anchorNode,Z=ee?ee===j||ee.contains(j):!1;if(Z)return!1;var V=im(H,j);if(!V)return!0;if(V?I=H:(I=H==="v"?"h":"v",V=im(H,j)),!V)return!1;if(!l.current&&"changedTouches"in C&&(S||N)&&(l.current=I),!I)return!0;var ne=l.current||I;return uw(ne,k,C,ne==="h"?S:N)},[]),x=F.useCallback(function(C){var k=C;if(!(!js.length||js[js.length-1]!==f)){var P="deltaY"in k?om(k):Ou(k),T=a.current.filter(function(I){return I.name===k.type&&(I.target===k.target||k.target===I.shadowParent)&&cw(I.delta,P)})[0];if(T&&T.should){k.cancelable&&k.preventDefault();return}if(!T){var S=(m.current.shards||[]).map(sm).filter(Boolean).filter(function(I){return I.contains(k.target)}),N=S.length>0?h(k,S[0]):!m.current.noIsolation;N&&k.cancelable&&k.preventDefault()}}},[]),p=F.useCallback(function(C,k,P,T){var S={name:C,delta:k,target:P,should:T,shadowParent:pw(P)};a.current.push(S),setTimeout(function(){a.current=a.current.filter(function(N){return N!==S})},1)},[]),v=F.useCallback(function(C){o.current=Ou(C),l.current=void 0},[]),y=F.useCallback(function(C){p(C.type,om(C),C.target,h(C,r.lockRef.current))},[]),w=F.useCallback(function(C){p(C.type,Ou(C),C.target,h(C,r.lockRef.current))},[]);F.useEffect(function(){return js.push(f),r.setCallbacks({onScrollCapture:y,onWheelCapture:y,onTouchMoveCapture:w}),document.addEventListener("wheel",x,zs),document.addEventListener("touchmove",x,zs),document.addEventListener("touchstart",v,zs),function(){js=js.filter(function(C){return C!==f}),document.removeEventListener("wheel",x,zs),document.removeEventListener("touchmove",x,zs),document.removeEventListener("touchstart",v,zs)}},[]);var B=r.removeScrollBar,D=r.inert;return F.createElement(F.Fragment,null,D?F.createElement(f,{styles:dw(d)}):null,B?F.createElement(nw,{noRelative:r.noRelative,gapMode:r.gapMode}):null)}function pw(r){for(var a=null;r!==null;)r instanceof ShadowRoot&&(a=r.host,r=r.host),r=r.parentNode;return a}const mw=U1(fg,hw);var gg=F.forwardRef(function(r,a){return F.createElement(Vc,$r({},r,{ref:a,sideCar:mw}))});gg.classNames=Vc.classNames;var Aw=function(r){if(typeof document>"u")return null;var a=Array.isArray(r)?r[0]:r;return a.ownerDocument.body},Hs=new WeakMap,zu=new WeakMap,ju={},Wf=0,xg=function(r){return r&&(r.host||xg(r.parentNode))},gw=function(r,a){return a.map(function(o){if(r.contains(o))return o;var l=xg(o);return l&&r.contains(l)?l:(console.error("aria-hidden",o,"in not contained inside",r,". Doing nothing"),null)}).filter(function(o){return!!o})},xw=function(r,a,o,l){var d=gw(a,Array.isArray(r)?r:[r]);ju[o]||(ju[o]=new WeakMap);var f=ju[o],m=[],h=new Set,x=new Set(d),p=function(y){!y||h.has(y)||(h.add(y),p(y.parentNode))};d.forEach(p);var v=function(y){!y||x.has(y)||Array.prototype.forEach.call(y.children,function(w){if(h.has(w))v(w);else try{var B=w.getAttribute(l),D=B!==null&&B!=="false",C=(Hs.get(w)||0)+1,k=(f.get(w)||0)+1;Hs.set(w,C),f.set(w,k),m.push(w),C===1&&D&&zu.set(w,!0),k===1&&w.setAttribute(o,"true"),D||w.setAttribute(l,"true")}catch(P){console.error("aria-hidden: cannot operate on ",w,P)}})};return v(a),h.clear(),Wf++,function(){m.forEach(function(y){var w=Hs.get(y)-1,B=f.get(y)-1;Hs.set(y,w),f.set(y,B),w||(zu.has(y)||y.removeAttribute(l),zu.delete(y)),B||y.removeAttribute(o)}),Wf--,Wf||(Hs=new WeakMap,Hs=new WeakMap,zu=new WeakMap,ju={})}},vw=function(r,a,o){o===void 0&&(o="data-aria-hidden");var l=Array.from(Array.isArray(r)?r:[r]),d=Aw(r);return d?(l.push.apply(l,Array.from(d.querySelectorAll("[aria-live], script"))),xw(l,d,o,"aria-hidden")):function(){return null}};function yw(r){const a=_w(r),o=F.forwardRef((l,d)=>{const{children:f,...m}=l,h=F.Children.toArray(f),x=h.find(bw);if(x){const p=x.props.children,v=h.map(y=>y===x?F.Children.count(p)>1?F.Children.only(null):F.isValidElement(p)?p.props.children:null:y);return E.jsx(a,{...m,ref:d,children:F.isValidElement(p)?F.cloneElement(p,void 0,v):null})}return E.jsx(a,{...m,ref:d,children:f})});return o.displayName=`${r}.Slot`,o}function _w(r){const a=F.forwardRef((o,l)=>{const{chi Line truncated
If you want to hide the \`${a.titleName}\`, you can wrap it with our VisuallyHidden component.
For more information, see https://radix-ui.com/primitives/docs/components/${a.docsSlug}`;return F.useEffect(()=>{r&&(document.getElementById(r)||console.error(o))},[o,r]),null},Nw="DialogDescriptionWarning",Lw=({contentRef:r,descriptionId:a})=>{const l=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${Fg(Nw).contentName}}.`;return F.useEffect(()=>{var f;const d=(f=r.current)==null?void 0:f.getAttribute("aria-describedby");a&&d&&(document.getElementById(a)||console.warn(l))},[l,r,a]),null},Ng=yg,Lg=bg,Zc=Cg,Wc=Eg,qc=Sg,Gc=Pg,Mg=Dg;const k0=Ng,Mw=Lg,Ig=F.forwardRef(({className:r,...a},o)=>E.jsx(Zc,{ref:o,className:at("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",r),...a}));Ig.displayName=Zc.displayName;const Qc=F.forwardRef(({className:r,children:a,...o},l)=>E.jsxs(Mw,{children:[E.jsx(Ig,{}),E.jsxs(Wc,{ref:l,className:at("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",r),...o,children:[a,E.jsxs(Mg,{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:[E.jsx(jA,{className:"h-4 w-4"}),E.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));Qc.displayName=Wc.displayName;const Kc=({className:r,...a})=>E.jsx("div",{className:at("flex flex-col space-y-1.5 text-center sm:text-left",r),...a});Kc.displayName="DialogHeader";const S0=({className:r,...a})=>E.jsx("div",{className:at("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",r),...a});S0.displayName="DialogFooter";const $c=F.forwardRef(({className:r,...a},o)=>E.jsx(qc,{ref:o,className:at("text-lg font-semibold leading-none tracking-tight",r),...a}));$c.displayName=qc.displayName;const Yc=F.forwardRef(({className:r,...a},o)=>E.jsx(Gc,{ref:o,className:at("text-sm text-muted-foreground",r),...a}));Yc.displayName=Gc.displayName;function Iw({open:r,onClose:a,path:o,senderInfo:l,contacts:d,config:f}){const m=Y_(o,l,d,f);return E.jsx(k0,{open:r,onOpenChange:h=>!h&&a(),children:E.jsxs(Qc,{className:"max-w-md max-h-[80vh] flex flex-col",children:[E.jsxs(Kc,{children:[E.jsx($c,{children:"Message Path"}),E.jsxs(Yc,{children:["This shows ",E.jsx("em",{children:"one route"})," that this message traveled through the mesh network. Flood messages may arrive via multiple paths, and routers may be incorrectly identified due to prefix collisions between heard and non-heard router advertisements."]})]}),E.jsx("div",{className:"flex-1 overflow-y-auto py-2",children:E.jsx(Ow,{resolved:m})}),E.jsx(S0,{children:E.jsx(Pn,{onClick:a,children:"Close"})})]})})}function Ow({resolved:r}){const a=o=>{if(o===0)return xn(r.sender.lat,r.sender.lon)?{lat:r.sender.lat,lon:r.sender.lon}:null;const l=r.hops[o-1];return l.matches.length>1||l.matches.length===0?null:xn(l.matches[0].lat,l.matches[0].lon)?{lat:l.matches[0].lat,lon:l.matches[0].lon}:null};return E.jsxs("div",{className:"space-y-0",children:[E.jsx(am,{label:"Sender",name:r.sender.name,prefix:r.sender.prefix,distance:null,isFirst:!0}),r.hops.map((o,l)=>E.jsx(zw,{hop:o,hopNumber:l+1,prevLocation:a(l)},l)),E.jsx(am,{label:"Receiver (me)",name:r.receiver.name,prefix:r.receiver.prefix,distance:jw(r),isLast:!0}),r.totalDistances&&r.totalDistances.length>0&&E.jsxs("div",{className:"pt-3 mt-3 border-t border-border",children:[E.jsxs("span",{className:"text-sm text-muted-foreground",children:["Presumed unambiguous distance covered:"," "]}),E.jsx("span",{className:"text-sm font-medium",children:Nc(r.totalDistances[0])})]})]})}function am({label:r,name:a,prefix:o,distance:l,isFirst:d,isLast:f}){return E.jsxs("div",{className:"flex gap-3",children:[E.jsxs("div",{className:"flex flex-col items-center w-4 flex-shrink-0",children:[!d&&E.jsx("div",{className:"w-0.5 h-3 bg-border"}),E.jsx("div",{className:"w-3 h-3 rounded-full bg-primary flex-shrink-0"}),!f&&E.jsx("div",{className:"w-0.5 flex-1 bg-border"})]}),E.jsxs("div",{className:"pb-3 flex-1 min-w-0",children:[E.jsx("div",{className:"text-xs text-muted-foreground font-medium",children:r}),E.jsxs("div",{className:"font-medium truncate",children:[a," ",E.jsxs("span",{className:"text-muted-foreground font-mono text-sm",children:["(",o,")"]})]}),l!==null&&E.jsx("div",{className:"text-xs text-muted-foreground",children:Nc(l)})]})]})}function zw({hop:r,hopNumber:a,prevL Line truncated
`).map(($,de,fe)=>E.jsxs("span",{children:[Hw($,h),de<fe.length-1&&E.jsx("br",{})]},de)),!Y&&E.jsxs(E.Fragment,{children:[E.jsx("span",{className:"text-[10px] text-muted-foreground/50 ml-2",children:al(z.sender_timestamp||z.received_at)}),!z.outgoing&&z.path&&E.jsxs("span",{className:"text-[10px] text-muted-foreground/50 ml-1 cursor-pointer hover:text-primary hover:underline",onClick:$=>{$.stopPropagation(),C({path:z.path,senderInfo:I(z,Z,ne)})},title:"View message path",children:["(",Lu(z.path)," hop",Lu(z.path)!==1?"s":"",")"]})]}),z.outgoing&&(z.acked>0?` ✓${z.acked>1?z.acked:""}`:" ?")]})]})]},z.id)})]}),w&&E.jsx("button",{onClick:T,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:E.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:E.jsx("polyline",{points:"6 9 12 15 18 9"})})}),D&&E.jsx(Iw,{open:!0,onClose:()=>C(null),path:D.path,senderInfo:D.senderInfo,contacts:a,config:x??null})]})}const lm=156,Uw=140,Zw=156,Ww=120,qw=8,Gw=F.forwardRef(function({onSend:a,disabled:o,placeholder:l,isRepeaterMode:d,conversationType:f,senderName:m},h){const[x,p]=F.useState(""),[v,y]=F.useState(!1),w=F.useRef(null);F.useImperativeHandle(h,()=>({appendText:I=>{var j;p(H=>H+I),(j=w.current)==null||j.focus()}}));const B=F.useMemo(()=>{if(f==="contact")return{warningAt:Uw,dangerAt:lm,hardLimit:lm};if(f==="channel"){const I=(m==null?void 0:m.length)??10,j=Math.max(1,Zw-I-2);return{warningAt:Ww,dangerAt:Math.max(1,j-qw),hardLimit:j}}return null},[f,m]),{limitState:D,warningMessage:C}=F.useMemo(()=>{if(!B)return{limitState:"normal",warningMessage:null};const I=x.length;return I>=B.hardLimit?{limitState:"error",warningMessage:"likely truncated by radio"}:I>=B.dangerAt?{limitState:"danger",warningMessage:"may impact multi-repeater hop delivery"}:I>=B.warningAt?{limitState:"warning",warningMessage:"may impact multi-repeater hop delivery"}:{limitState:"normal",warningMessage:null}},[x.length,B]),k=B?B.hardLimit-x.length:0,P=F.useCallback(async I=>{I.preventDefault();const j=x.trim();if(d){if(v||o)return;y(!0);try{await a(j),p("")}catch(H){console.error("Failed to request telemetry:",H),kt.error("Failed to request telemetry",{description:H instanceof Error?H.message:"Check radio connection"});return}finally{y(!1)}setTimeout(()=>{var H;return(H=w.current)==null?void 0:H.focus()},0)}else{if(!j||v||o)return;y(!0);try{await a(j),p("")}catch(H){console.error("Failed to send message:",H),kt.error("Failed to send message",{description:H instanceof Error?H.message:"Check radio connection"});return}finally{y(!1)}setTimeout(()=>{var H;return(H=w.current)==null?void 0:H.focus()},0)}},[x,v,o,a,d]),T=F.useCallback(I=>{I.key==="Enter"&&!I.shiftKey&&(I.preventDefault(),P(I))},[P]),S=d?!0:x.trim().length>0,N=!d&&B!==null;return E.jsxs("form",{className:"px-4 py-3 border-t border-border flex flex-col gap-1",onSubmit:P,children:[E.jsxs("div",{className:"flex gap-2",children:[E.jsx(Yt,{ref:w,type:d?"password":"text",autoComplete:d?"off":void 0,value:x,onChange:I=>p(I.target.value),onKeyDown:T,placeholder:l||(d?"Enter password for admin login...":"Type a message..."),disabled:o||v,className:"flex-1 min-w-0"}),E.jsx(Pn,{type:"submit",disabled:o||v||!S,className:"flex-shrink-0",children:v?d?"Logging in...":"Sending...":d?x.trim()?"Log in with password":"Log in as guest/use repeater ACLs":"Send"})]}),N&&E.jsxs("div",{className:"flex items-center justify-end gap-2 text-xs",children:[E.jsxs("span",{className:at("tabular-nums",D==="error"||D==="danger"?"text-red-500 font-medium":D==="warning"?"text-yellow-500":"text-muted-foreground"),children:[x.length,"/",B.hardLimit,k<0&&` (${k})`]}),C&&E.jsxs("span",{className:at(D==="error"?"text-red-500":"text-yellow-500"),children:["— ",C]})]})]})});function um(r){const a=Qw(r),o=F.forwardRef((l,d)=>{const{children:f,...m}=l,h=F.Children.toArray(f),x=h.find($w);if(x){const p=x.props.children,v=h.map(y=>y===x?F.Children.count(p)>1?F.Children.only(null):F.isValidElement(p)?p.props.children:null:y);return E.jsx(a,{...m,ref:d,children:F.isValidElement(p)?F.cloneElement(p,void 0,v):null})}return E.jsx(a,{...m,ref:d,children:f})});return o.displayName=`${r}.Slot`,o}function Qw(r){const a=F.forwardRef((o,l)=>{const{children:d,...f}=o;if(F.isValidElement(d)){const m=Xw(d),h=Yw(f,d.props);return d.type!==F.Fragment&&(h.ref=l?dl(l,m):m),F.cloneElement(d,h)}return F.Children.count(d)>1?F.Children.only(null):null});return a.displayName=`${r}.SlotClone`,a}var Kw=Symbol("radix.slottable");function $w(r){return F.isValidElement(r)&&typeof r.type=="function"&&"__radixId"in r.type&&r.type.__radixId===Kw}function Yw(r,a){const o={...a};for(const l in a){const d=r[l],f=a[l];/^on[A-Z]/.test(l)?d&&f?o[l]=(...h 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 W2=il.exports,fm;function q2(){return fm||(fm=1,(function(r,a){(function(o,l){l(a)})(W2,(function(o){var l="1.9.4";function d(t){var i,u,A,b;for(u=1,A=arguments.length;u<A;u++){b=arguments[u];for(i in b)t[i]=b[i]}return t}var f=Object.create||(function(){function t(){}return function(i){return t.prototype=i,new t}})();function m(t,i){var u=Array.prototype.slice;if(t.bind)return t.bind.apply(t,u.call(arguments,1));var A=u.call(arguments,2);return function(){return t.apply(i,A.length?A.concat(u.call(arguments)):arguments)}}var h=0;function x(t){return"_leaflet_id"in t||(t._leaflet_id=++h),t._leaflet_id}function p(t,i,u){var A,b,O,K;return K=function(){A=!1,b&&(O.apply(u,b),b=!1)},O=function(){A?b=arguments:(t.apply(u,arguments),setTimeout(K,i),A=!0)},O}function v(t,i,u){var A=i[1],b=i[0],O=A-b;return t===A&&u?t:((t-b)%O+O)%O+b}function y(){return!1}function w(t,i){if(i===!1)return t;var u=Math.pow(10,i===void 0?6:i);return Math.round(t*u)/u}function B(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}function D(t){return B(t).split(/\s+/)}function C(t,i){Object.prototype.hasOwnProperty.call(t,"options")||(t.options=t.options?f(t.options):{});for(var u in i)t.options[u]=i[u];return t.options}function k(t,i,u){var A=[];for(var b in t)A.push(encodeURIComponent(u?b.toUpperCase():b)+"="+encodeURIComponent(t[b]));return(!i||i.indexOf("?")===-1?"?":"&")+A.join("&")}var P=/\{ *([\w_ -]+) *\}/g;function T(t,i){return t.replace(P,function(u,A){var b=i[A];if(b===void 0)throw new Error("No value provided for variable "+u);return typeof b=="function"&&(b=b(i)),b})}var S=Array.isArray||function(t){return Object.prototype.toString.call(t)==="[object Array]"};function N(t,i){for(var u=0;u<t.length;u++)if(t[u]===i)return u;return-1}var I="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";function j(t){return window["webkit"+t]||window["moz"+t]||window["ms"+t]}var H=0;function z(t){var i=+new Date,u=Math.max(0,16-(i-H));return H=i+u,window.setTimeout(t,u)}var ee=window.requestAnimationFrame||j("RequestAnimationFrame")||z,Z=window.cancelAnimationFrame||j("CancelAnimationFrame")||j("CancelRequestAnimationFrame")||function(t){window.clearTimeout(t)};function V(t,i,u){if(u&&ee===z)t.call(i);else return ee.call(window,m(t,i))}function ne(t){t&&Z.call(window,t)}var J={__proto__:null,extend:d,create:f,bind:m,get lastId(){return h},stamp:x,throttle:p,wrapNum:v,falseFn:y,formatNum:w,trim:B,splitWords:D,setOptions:C,getParamString:k,template:T,isArray:S,indexOf:N,emptyImageUrl:I,requestFn:ee,cancelFn:Z,requestAnimFrame:V,cancelAnimFrame:ne};function re(){}re.extend=function(t){var i=function(){C(this),this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()},u=i.__super__=this.prototype,A=f(u);A.constructor=i,i.prototype=A;for(var b in this)Object.prototype.hasOwnProperty.call(this,b)&&b!=="prototype"&&b!=="__super__"&&(i[b]=this[b]);return t.statics&&d(i,t.statics),t.includes&&(he(t.includes),d.apply(null,[A].concat(t.includes))),d(A,t),delete A.statics,delete A.includes,A.options&&(A.options=u.options?f(u.options):{},d(A.options,t.options)),A._initHooks=[],A.callInitHooks=function(){if(!this._initHooksCalled){u.callInitHooks&&u.callInitHooks.call(this),this._initHooksCalled=!0;for(var O=0,K=A._initHooks.length;O<K;O++)A._initHooks[O].call(this)}},i},re.include=function(t){var i=this.prototype.options;return d(this.prototype,t),t.options&&(this.prototype.options=i,this.mergeOptions(t.options)),this},re.mergeOptions=function(t){return d(this.prototype.options,t),this},re.addInitHook=function(t){var i=Array.prototype.slice.call(arguments,1),u=typeof t=="function"?t:function(){this[t].apply(this,i)};return this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(u),this};function he(t){if(!(typeof L>"u"||!L||!L.Mixin)){t=S(t)?t:[t];for(var i=0;i<t.length;i++)t[i]===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 ae={on:function(t,i,u){if(typeof t=="object")for(var A in t)this._on(A,t[A],i);else{t=D(t);for(var b=0,O=t.length;b<O;b++)this._on(t[b],i,u)}return this},off:function(t,i,u){if(!arguments.length)delete this._events;else if(typeof t=="object")for(var A in t)this._off(A,t[A],i);else{t=D(t);for(var b=arguments.length===1,O=0,K=t.length;O<K;O++)b?this._off(t[O]):this._off(t[O],i,u)}return this},_on:function(t,i,u,A){if(typeof i!="function"){console.warn("wrong listener type: "+typeof i);return}if(this._listens(t,i,u)===!1){u===this&&(u=void 0);var b={fn:i,ctx:u};A&&(b.once=!0),this._events=this._events||{},this._events[t]=this._events[t]||[],this._events[t].push(b)}},_off:function(t,i,u){var A,b,O;if(this._events&&(A=this._events[t],!!A)){if(arguments.length===1){if(this._firingCount)for(b=0,O=A.length;b<O;b++)A[b].fn=y;delete this._events[t];return}if(typeof i!="function"){console.warn("wrong listener type: "+typeof i);return}var K=tLine 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 d=o,f=d.lib,m=f.WordArray,h=f.Hasher,x=d.algo,p=m.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]),v=m.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]),y=m.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=m.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]),B=m.create([0,1518500249,1859775393,2400959708,2840853838]),D=m.create([1352829926,1548603684,1836072691,2053994217,0]),C=x.RIPEMD160=h.extend({_doReset:function(){this._hash=m.create([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(j,H){for(var z=0;z<16;z++){var ee=H+z,Z=j[ee];j[ee]=(Z<<8|Z>>>24)&16711935|(Z<<24|Z>>>8)&4278255360}var V=this._hash.words,ne=B.words,J=D.words,re=p.words,he=v.words,ae=y.words,pe=w.words,G,Y,q,R,U,Q,$,de,fe,ke;Q=G=V[0],$=Y=V[1],de=q=V[2],fe=R=V[3],ke=U=V[4];for(var ge,z=0;z<80;z+=1)ge=G+j[H+re[z]]|0,z<16?ge+=k(Y,q,R)+ne[0]:z<32?ge+=P(Y,q,R)+ne[1]:z<48?ge+=T(Y,q,R)+ne[2]:z<64?ge+=S(Y,q,R)+ne[3]:ge+=N(Y,q,R)+ne[4],ge=ge|0,ge=I(ge,ae[z]),ge=ge+U|0,G=U,U=R,R=I(q,10),q=Y,Y=ge,ge=Q+j[H+he[z]]|0,z<16?ge+=N($,de,fe)+J[0]:z<32?ge+=S($,de,fe)+J[1]:z<48?ge+=T($,de,fe)+J[2]:z<64?ge+=P($,de,fe)+J[3]:ge+=k($,de,fe)+J[4],ge=ge|0,ge=I(ge,pe[z]),ge=ge+ke|0,Q=ke,ke=fe,fe=I(de,10),de=$,$=ge;ge=V[1]+q+fe|0,V[1]=V[2]+R+ke|0,V[2]=V[3]+U+Q|0,V[3]=V[4]+G+$|0,V[4]=V[0]+Y+de|0,V[0]=ge},_doFinalize:function(){var j=this._data,H=j.words,z=this._nDataBytes*8,ee=j.sigBytes*8;H[ee>>>5]|=128<<24-ee%32,H[(ee+64>>>9<<4)+14]=(z<<8|z>>>24)&16711935|(z<<24|z>>>8)&4278255360,j.sigBytes=(H.length+1)*4,this._process();for(var Z=this._hash,V=Z.words,ne=0;ne<5;ne++){var J=V[ne];V[ne]=(J<<8|J>>>24)&16711935|(J<<24|J>>>8)&4278255360}return Z},clone:function(){var j=h.clone.call(this);return j._hash=this._hash.clone(),j}});function k(j,H,z){return j^H^z}function P(j,H,z){return j&H|~j&z}function T(j,H,z){return(j|~H)^z}function S(j,H,z){return j&z|H&~z}function N(j,H,z){return j^(H|~z)}function I(j,H){return j<<H|j>>>32-H}d.RIPEMD160=h._createHelper(C),d.HmacRIPEMD160=h._createHmacHelper(C)})(),o.RIPEMD160})})(oc)),oc.exports}var sc={exports:{}},Lb=sc.exports,Dm;function id(){return Dm||(Dm=1,(function(r,a){(function(o,l){r.exports=l(dt())})(Lb,function(o){(function(){var l=o,d=l.lib,f=d.Base,m=l.enc,h=m.Utf8,x=l.algo;x.HMAC=f.extend({init:function(p,v){p=this._hasher=new p.init,typeof v=="string"&&(v=h.parse(v));var y=p.blockSize,w=y*4;v.sigBytes>w&&(v=p.finalize(v)),v.clamp();for(var B=this._oKey=v.clone(),D=this._iKey=v.clone(),C=B.words,k=D.words,P=0;P<y;P++)C[P]^=1549556828,k[P]^=909522486;B.sigBytes=D.sigBytes=w,this.reset()},reset:function(){var p=this._hasher;p.reset(),p.update(this._iKey)},update:function(p){return this._hasher.update(p),this},finalize:function(p){var v=this._hasher,y=v.finalize(p);v.reset();var w=v.finalize(this._oKey.clone().concat(y));return w}})})()})})(sc)),sc.exports}var ac={exports:{}},Mb=ac.exports,Rm;function Ib(){return Rm||(Rm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),pl(),id())})(Mb,function(o){return(function(){var l=o,d=l.lib,f=d.Base,m=d.WordArray,h=l.algo,x=h.SHA256,p=h.HMAC,v=h.PBKDF2=f.extend({cfg:f.extend({keySize:128/32,hasher:x,iterations:25e4}),init:function(y){this.cfg=this.cfg.extend(y)},compute:function(y,w){for(var B=this.cfg,D=p.create(B.hasher,y),C=m.create(),k=m.create([1]),P=C.words,T=k.words,S=B.keySize,N=B.iterations;P.length<S;){var I=D.update(w).finalize(k);D.reset();for(var j=I.words,H=j.length,z=I,ee=1;ee<N;ee++){z=D.finalize(z),D.reset();for(var Z=z.words,V=0;V<H;V++)j[V]^=Z[V]}C.concat(I),T[0]++}return C.sigBytes=S*4,C}});l.PBKDF2=function(y,w,B){return v.create(B).compute(y,w)}})(),o.PBKDF2})})(ac)),ac.exports}var lc={exports:{}},Ob=lc.exports,Fm;function fo(){return Fm||(Fm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),_x(),id())})(Ob,function(o){return(function(){var l=o,d=l.lib,f=d.Base,m=d.WordArray,h=l.algo,x=h.MD5,p=h.EvpKDF=f.extend({cfg:f.extend({keySize:128/32,hasher:x,iterations:1}),init:function(v){this.cfg=this.cfg.extend(v)},compute:function(v,y){for(var w,B=this.cfg,D=B.hasher.create(),C=m.create(),k=C.words,P=B.keySize,T=B.iterations;k.length<P;){w&&D.update(w),w=D.update(v).finalize(y),D.reset();for(var S=1;S<T;S++)w=D.finalize(w),D.reset();C.concat(w)}return C.sigBytes=P*4,C}});l.EvpKDF=function(v,y,w){return p.create(w).compute(v,y)}})(),o.EvpKDF})})(lc)),lc.exports}var uc={exports:{}},zb=uc.exports,Line truncated
* Counter block mode compatible with Dr Brian Gladman fileenc.c
* derived from CryptoJS.mode.CTR
* Jan Hruby jhruby.web@gmail.com
*/return o.mode.CTRGladman=(function(){var l=o.lib.BlockCipherMode.extend();function d(h){if((h>>24&255)===255){var x=h>>16&255,p=h>>8&255,v=h&255;x===255?(x=0,p===255?(p=0,v===255?v=0:++v):++p):++x,h=0,h+=x<<16,h+=p<<8,h+=v}else h+=1<<24;return h}function f(h){return(h[0]=d(h[0]))===0&&(h[1]=d(h[1])),h}var m=l.Encryptor=l.extend({processBlock:function(h,x){var p=this._cipher,v=p.blockSize,y=this._iv,w=this._counter;y&&(w=this._counter=y.slice(0),this._iv=void 0),f(w);var B=w.slice(0);p.encryptBlock(B,0);for(var D=0;D<v;D++)h[x+D]^=B[D]}});return l.Decryptor=m,l})(),o.mode.CTRGladman})})(fc)),fc.exports}var hc={exports:{}},qb=hc.exports,Om;function Gb(){return Om||(Om=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),hn())})(qb,function(o){return o.mode.OFB=(function(){var l=o.lib.BlockCipherMode.extend(),d=l.Encryptor=l.extend({processBlock:function(f,m){var h=this._cipher,x=h.blockSize,p=this._iv,v=this._keystream;p&&(v=this._keystream=p.slice(0),this._iv=void 0),h.encryptBlock(v,0);for(var y=0;y<x;y++)f[m+y]^=v[y]}});return l.Decryptor=d,l})(),o.mode.OFB})})(hc)),hc.exports}var pc={exports:{}},Qb=pc.exports,zm;function Kb(){return zm||(zm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),hn())})(Qb,function(o){return o.mode.ECB=(function(){var l=o.lib.BlockCipherMode.extend();return l.Encryptor=l.extend({processBlock:function(d,f){this._cipher.encryptBlock(d,f)}}),l.Decryptor=l.extend({processBlock:function(d,f){this._cipher.decryptBlock(d,f)}}),l})(),o.mode.ECB})})(pc)),pc.exports}var mc={exports:{}},$b=mc.exports,jm;function Yb(){return jm||(jm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),hn())})($b,function(o){return o.pad.AnsiX923={pad:function(l,d){var f=l.sigBytes,m=d*4,h=m-f%m,x=f+h-1;l.clamp(),l.words[x>>>2]|=h<<24-x%4*8,l.sigBytes+=h},unpad:function(l){var d=l.words[l.sigBytes-1>>>2]&255;l.sigBytes-=d}},o.pad.Ansix923})})(mc)),mc.exports}var Ac={exports:{}},Xb=Ac.exports,Hm;function Jb(){return Hm||(Hm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),hn())})(Xb,function(o){return o.pad.Iso10126={pad:function(l,d){var f=d*4,m=f-l.sigBytes%f;l.concat(o.lib.WordArray.random(m-1)).concat(o.lib.WordArray.create([m<<24],1))},unpad:function(l){var d=l.words[l.sigBytes-1>>>2]&255;l.sigBytes-=d}},o.pad.Iso10126})})(Ac)),Ac.exports}var gc={exports:{}},eC=gc.exports,Vm;function tC(){return Vm||(Vm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),hn())})(eC,function(o){return o.pad.Iso97971={pad:function(l,d){l.concat(o.lib.WordArray.create([2147483648],1)),o.pad.ZeroPadding.pad(l,d)},unpad:function(l){o.pad.ZeroPadding.unpad(l),l.sigBytes--}},o.pad.Iso97971})})(gc)),gc.exports}var xc={exports:{}},nC=xc.exports,Um;function rC(){return Um||(Um=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),hn())})(nC,function(o){return o.pad.ZeroPadding={pad:function(l,d){var f=d*4;l.clamp(),l.sigBytes+=f-(l.sigBytes%f||f)},unpad:function(l){for(var d=l.words,f=l.sigBytes-1,f=l.sigBytes-1;f>=0;f--)if(d[f>>>2]>>>24-f%4*8&255){l.sigBytes=f+1;break}}},o.pad.ZeroPadding})})(xc)),xc.exports}var vc={exports:{}},iC=vc.exports,Zm;function oC(){return Zm||(Zm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),hn())})(iC,function(o){return o.pad.NoPadding={pad:function(){},unpad:function(){}},o.pad.NoPadding})})(vc)),vc.exports}var yc={exports:{}},sC=yc.exports,Wm;function aC(){return Wm||(Wm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),hn())})(sC,function(o){return(function(l){var d=o,f=d.lib,m=f.CipherParams,h=d.enc,x=h.Hex,p=d.format;p.Hex={stringify:function(v){return v.ciphertext.toString(x)},parse:function(v){var y=x.parse(v);return m.create({ciphertext:y})}}})(),o.format.Hex})})(yc)),yc.exports}var _c={exports:{}},lC=_c.exports,qm;function uC(){return qm||(qm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),Ko(),$o(),fo(),hn())})(lC,function(o){return(function(){var l=o,d=l.lib,f=d.BlockCipher,m=l.algo,h=[],x=[],p=[],v=[],y=[],w=[],B=[],D=[],C=[],k=[];(function(){for(var S=[],N=0;N<256;N++)N<128?S[N]=N<<1:S[N]=N<<1^283;for(var I=0,j=0,N=0;N<256;N++){var H=j^j<<1^j<<2^j<<3^j<<4;H=H>>>8^H&255^99,h[I]=H,x[H]=I;var z=S[I],ee=S[z],Z=S[ee],V=S[H]*257^H*16843008;p[I]=V<<24|V>>>8,v[I]=V<<16|V>>>16,y[I]=V<<8|V>>>24,w[I]=V;var V=Z*16843009^ee*65537^z*257^I*16843008;B[H]=V<<24|V>>>8,D[H]=V<<16|V>>>16,C[H]=V<<8|V>>>24,k[H]=V,I?(I=z^S[S[S[Z^z]]],j^=S[S[j]]):I=j=1}})();var P=[0,1,2,4,8,16,32,64,128,27,54],T=m.AES=f.extend({_doReset:function(){var S;if(!(this._nRounds&&this._keyPriorReset===this._key)){for(var N=this._keyPriorReset=this._key,I=N.words,j=N.sigBytes/4,H=this._nRounds=j+6,z=(H+1)*4,ee=this._keySchedule=[],Z=0;Z<z;Z++)Z<j?ee[Z]=I[Z]:(S=ee[Z-1],Z%j?j>6&&Z%j==4&&(S=h[S>>>24]<<24|h[S>>>16&255]<<16|h[S>>>8&255]<<8|h[S&255]):(S=S<<8|S>>>24,S=h[S>>>24]<<24|h[S>>>16&255]<<16|h[S>>>8&255]<<8|h[S&255],S^=P[Z/j|0]<<24),ee[Z]=ee[Z-j]^S);for(var V=this._invKeySchedule=[],ne=0;ne<z;ne++){var Z=z-ne;if(ne%4)var S=ee[Z];else var S=ee[Z-4];ne<4||Z<=4?V[ne]=S:V[ne]=B[h[S>>>24]]^D[h[S>>>16&255]]^C[h[S>>>8&255]]^k[h[S&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:h+x,endByte:h+d.length-1,value:w});const B={type:r.PayloadType.Request,version:r.PayloadVersion.Version1,isValid:!0,timestamp:0,requestType:r.RequestType.GetStats,requestData:"",destinationHash:p,sourceHash:v,cipherMac:y,ciphertext:w};return f!=null&&f.includeSegments&&(B.segments=m),B}catch(m){return{type:r.PayloadType.Request,version:r.PayloadVersion.Version1,isValid:!1,errors:[m instanceof Error?m.message:"Failed to decode request payload"],timestamp:0,requestType:r.RequestType.GetStats,requestData:"",destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:""}}}}return Ya.RequestPayloadDecoder=o,Ya}var Xa={},mA;function WC(){if(mA)return Xa;mA=1,Object.defineProperty(Xa,"__esModule",{value:!0}),Xa.ResponsePayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<4){const D={type:r.PayloadType.Response,version:r.PayloadVersion.Version1,isValid:!1,errors:["Response payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return f!=null&&f.includeSegments&&(D.segments=[{name:"Invalid Response Data",description:"Response payload too short (minimum 4 bytes required)",startByte:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),D}const m=[],h=(f==null?void 0:f.segmentOffset)||0;let x=0;const p=(0,a.byteToHex)(d[x]);f!=null&&f.includeSegments&&m.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:h+x,endByte:h+x,value:p}),x+=1;const v=(0,a.byteToHex)(d[x]);f!=null&&f.includeSegments&&m.push({name:"Source Hash",description:"First byte of source node public key",startByte:h+x,endByte:h+x,value:v}),x+=1;const y=(0,a.bytesToHex)(d.subarray(x,x+2));f!=null&&f.includeSegments&&m.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:h+x,endByte:h+x+1,value:y}),x+=2;const w=(0,a.bytesToHex)(d.subarray(x));f!=null&&f.includeSegments&&d.length>x&&m.push({name:"Ciphertext",description:"Encrypted response data (tag + content)",startByte:h+x,endByte:h+d.length-1,value:w});const B={type:r.PayloadType.Response,version:r.PayloadVersion.Version1,isValid:!0,destinationHash:p,sourceHash:v,cipherMac:y,ciphertext:w,ciphertextLength:d.length-4};return f!=null&&f.includeSegments&&(B.segments=m),B}catch(m){return{type:r.PayloadType.Response,version:r.PayloadVersion.Version1,isValid:!1,errors:[m instanceof Error?m.message:"Failed to decode response payload"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return Xa.ResponsePayloadDecoder=o,Xa}var Ja={},AA;function qC(){if(AA)return Ja;AA=1,Object.defineProperty(Ja,"__esModule",{value:!0}),Ja.AnonRequestPayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<35){const D={type:r.PayloadType.AnonRequest,version:r.PayloadVersion.Version1,isValid:!1,errors:["AnonRequest payload too short (minimum 35 bytes: dest + public key + MAC)"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return f!=null&&f.includeSegments&&(D.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:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),D}const m=[],h=(f==null?void 0:f.segmentOffset)||0;let x=0;const p=(0,a.byteToHex)(d[0]);f!=null&&f.includeSegments&&m.push({name:"Destination Hash",description:`First byte of destination node public key: 0x${p}`,startByte:h+x,endByte:h+x,value:p}),x+=1;const v=(0,a.bytesToHex)(d.subarray(1,33));f!=null&&f.includeSegments&&m.push({name:"Sender Public Key",description:"Ed25519 public key of the sender (32 bytes)",startByte:h+x,endByte:h+x+31,value:v}),x+=32;const y=(0,a.bytesToHex)(d.subarray(33,35));f!=null&&f.includeSegments&&m.push({name:"Cipher MAC",description:"MAC for encrypted data verification (2 bytes)",startByte:h+x,endByte:h+x+1,value:y}),x+=2;const w=(0,a.bytesToHex)(d.subarray(35));f!=null&&f.includeSegments&&d.length>35&&m.push({name:"Ciphertext",description:`Encrypted message data (${d.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:h+x,endByte:h+d.length-1,value:w});const B={type:r.PayloadType.AnonRequest,version:r.PayloadVersion.Version1,isValid:!0,destinationHash:p,senderPublicKey:v,cipherMac:y,ciphertext:w,ciphertextLength:d.length-35};return f!=null&&f.includeSegments&&(B.segments=m),B}catch(m){return{type:r.PayloadType.AnonRequest,version:r.PayloadVersion.Version1,isValid:!1,errors:[m instanceof Error?m.message:"Failed to decode AnonRequest payload"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return Ja.AnonRequestPayloadDecoder=o,Ja}var el={},gA;function GC(){if(gA)return el;gA=1,Object.defineProperty(el,"__esModule",{value:!0}),el.AckPayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<4){const v={type:r.PayloadType.Ack,version:r.PayloadVersion.Version1,isValid:!1,errors:["Ack payload too short (minimum 4 bytes for checksum)"],checksum:""};return f!=null&&f.includeSegments&&(v.segments=[{name:"Invalid Ack Data",description:"Ack payload too short (minimum 4 bytes required for checksum)",startByte:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),v}const m=[],h=(f==null?void 0:f.segmentOffset)||0,x=(0,a.bytesToHex)(d.subarray(0,4));f!=null&&f.includeSegments&&m.push({name:"Checksum",description:`CRC checksum of message timestamp, text, and sender pubkey: 0x${x}`,startByte:h,endByte:h+3,value:x}),f!=null&&f.includeSegments&&d.length>4&&m.push({name:"Additional Data",description:"Extra data in Ack payload",startByte:h+4,endByte:h+d.length-1,value:(0,a.bytesToHex)(d.subarray(4))});const p={type:r.PayloadType.Ack,version:r.PayloadVersion.Version1,isValid:!0,checksum:x};return f!=null&&f.includeSegments&&(p.segments=m),p}catch(m){return{type:r.PayloadType.Ack,version:r.PayloadVersion.Version1,isValid:!1,errors:[m instanceof Error?m.message:"Failed to decode Ack payload"],checksum:""}}}}return el.AckPayloadDecoder=o,el}var tl={},xA;function QC(){if(xA)return tl;xA=1,Object.defineProperty(tl,"__esModule",{value:!0}),tl.PathPayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d){try{if(d.length<2)return{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!1,errors:["Path payload too short (minimum 2 bytes: path length + extra type)"],pathLength:0,pathHashes:[],extraType:0,extraData:""};const f=d[0];if(d.length<1+f+1)return{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!1,errors:[`Path payload too short (need ${1+f+1} bytes for path length + path + extra type)`],pathLength:f,pathHashes:[],extraType:0,extraData:""};const m=[];for(let p=0;p<f;p++)m.push((0,a.byteToHex)(d[1+p]));const h=d[1+f];let x="";return d.length>1+f+1&&(x=(0,a.bytesToHex)(d.subarray(1+f+1))),{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!0,pathLength:f,pathHashes:m,extraType:h,extraData:x}}catch(f){return{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!1,errors:[f instanceof Error?f.message:"Failed to decode Path payload"],pathLength:0,pathHashes:[],extraType:0,extraData:""}}}}return tl.PathPayloadDecoder=o,tl}var nl={},vA;function KC(){if(vA)return nl;vA=1,Object.defineProperty(nl,"__esModule",{value:!0}),nl.TextMessagePayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<4){const D={type:r.PayloadType.TextMessage,version:r.PayloadVersion.Version1,isValid:!1,errors:["TextMessage payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return f!=null&&f.includeSegments&&(D.segments=[{name:"Invalid TextMessage Data",description:"TextMessage payload too short (minimum 4 bytes required)",startByte:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),D}const m=[],h=(f==null?void 0:f.segmentOffset)||0;let x=0;const p=(0,a.byteToHex)(d[x]);f!=null&&f.includeSegments&&m.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:h+x,endByte:h+x,value:p}),x+=1;const v=(0,a.byteToHex)(d[x]);f!=null&&f.includeSegments&&m.push({name:"Source Hash",description:"First byte of source node public key",startByte:h+x,endByte:h+x,value:v}),x+=1;const y=(0,a.bytesToHex)(d.subarray(x,x+2));f!=null&&f.includeSegments&&m.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:h+x,endByte:h+x+1,value:y}),x+=2;const w=(0,a.bytesToHex)(d.subarray(x));f!=null&&f.includeSegments&&d.length>x&&m.push({name:"Ciphertext",description:"Encrypted message data (timestamp + message text)",startByte:h+x,endByte:h+d.length-1,value:w});const B={type:r.PayloadType.TextMessage,version:r.PayloadVersion.Version1,isValid:!0,destinationHash:p,sourceHash:v,cipherMac:y,ciphertext:w,ciphertextLength:d.length-4};return f!=null&&f.includeSegments&&(B.segments=m),B}catch(m){return{type:r.PayloadType.TextMessage,version:r.PayloadVersion.Version1,i Line 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 a=await navigator.gpu.requestAdapter();if(!a)return console.warn("No GPU adapter found"),!1;this.device=await a.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 d=0;d<2;d++)this.matchCountReadBuffers[d]=this.device.createBuffer({size:4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),this.matchIndicesReadBuffers[d]=this.device.createBuffer({size:1024*4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST});const o=this.device.createShaderModule({code:this.shaderCode}),l=this.device.createPipelineLayout({bindGroupLayouts:[this.bindGroupLayout]});return this.pipeline=this.device.createComputePipeline({layout:l,compute:{module:o,entryPoint:"main"}}),!0}catch(a){return console.error("WebGPU initialization failed:",a),!1}}isAvailable(){return this.device!==null&&this.pipeline!==null}indexToRoomName(a,o){return qo(o,a)}countNamesForLength(a){return ol(a)}async runBatch(a,o,l,d,f,m){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 h=this.currentReadBufferIndex;this.currentReadBufferIndex=1-this.currentReadBufferIndex;const x=this.matchCountReadBuffers[h],p=this.matchIndicesReadBuffers[h],v=f&&m?1:0;let y,w=0,B=0;if(v){const I=new Uint8Array(f.length/2);for(let Z=0;Z<I.length;Z++)I[Z]=parseInt(f.substr(Z*2,2),16);w=I.length*8;const j=Math.ceil(I.length/4)*4,H=new Uint8Array(j);H.set(I),y=new Uint32Array(j/4);for(let Z=0;Z<y.length;Z++)y[Z]=H[Z*4]<<24|H[Z*4+1]<<16|H[Z*4+2]<<8|H[Z*4+3];const z=parseInt(m.substr(0,2),16),ee=parseInt(m.substr(2,2),16);B=z<<24|ee<<16}else y=new Uint32Array([0]);const D=Math.max(y.length*4,4);(!this.ciphertextBuffer||this.ciphertextBufferSize<D)&&(this.ciphertextBuffer&&this.ciphertextBuffer.destroy(),this.ciphertextBuffer=this.device.createBuffer({size:D,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.ciphertextBufferSize=D,this.bindGroupDirty=!0);const C=new Uint32Array([a,l,o,d,B,y.length,w,v]);this.device.queue.writeBuffer(this.paramsBuffer,0,C),this.device.queue.writeBuffer(this.ciphertextBuffer,0,y),this.device.queue.writeBuffer(this.matchCountBuffer,0,sd.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 k=this.device.createCommandEncoder(),P=k.beginComputePass();P.setPipeline(this.pipeline),P.setBindGroup(0,this.bindGroup),P.dispatchWorkgroups(Math.ceil(d/(256*32))),P.end(),k.copyBufferToBuffer(this.matchCountBuffer,0,x,0,4),k.copyBufferToBuffer(this.matchIndicesBuffer,0,p,0,1024*4),this.device.queue.submit([k.finish()]),await x.mapAsync(GPUMapMode.READ);const S=new Uint32Array(x.getMappedRange())[0];x.unmap();const N=[];if(S>0){await p.mapAsync(GPUMapMode.READ);const I=new Uint32Array(p.getMappedRange());for(let j=0;j<Math.min(S,1024);j++)N.push(I[j]);p.unmap()}return N}destroy(){var a,o,l,d,f,m,h,x;(a=this.paramsBuffer)==null||a.destroy(),(o=this.matchCountBuffer)==null||o.destroy(),(l=this.matchIndicesBuffer)==null||l.destroy(),(d=this.ciphertextBuffer)==null||d.destroy(),(f=this.matchCountReadBuffers[0])==null||f.destroy(),(m=this.matchCountReadBuffers[1])==null||m.destroy(),(h=this.matchIndicesReadBuffers[0])==null||h.destroy(),(x=this.matchIndicesReadBuffers[1])==null||x.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}}sd.ZERO_DATA=new Uint32Array([0]);function uE(){return typeof navigator<"u"&&"gpu"in navigator}class PA{runBatch(a,o,l,d,f,m){const h=[],x=a.toString(16).padStart(2,"0 Line truncated
`).map(f=>f.trim().toLowerCase()).filter(f=>f.length>0);this.wordlist=d.filter(TA)}setWordlist(a){this.wordlist=a.map(o=>o.trim().toLowerCase()).filter(TA)}abort(){this.abortFlag=!0}isGpuAvailable(){return uE()}async decodePacket(a){var l;const o=a.trim().replace(/\s+/g,"").replace(/^0x/i,"");if(!o||!/^[0-9a-fA-F]+$/.test(o))return null;try{const f=(l=(await kA.MeshCorePacketDecoder.decodeWithVerification(o,{})).payload)==null?void 0:l.decoded;return!(f!=null&&f.channelHash)||!(f!=null&&f.ciphertext)||!(f!=null&&f.cipherMac)?null:{channelHash:f.channelHash,ciphertext:f.ciphertext,cipherMac:f.cipherMac,isGroupText:!0}}catch{return null}}async crack(a,o,l){this.abortFlag=!1,this.useTimestampFilter=(o==null?void 0:o.useTimestampFilter)??!0,this.useUtf8Filter=(o==null?void 0:o.useUtf8Filter)??!0,this.useSenderFilter=(o==null?void 0:o.useSenderFilter)??!0,this.validSeconds=(o==null?void 0:o.validSeconds)??f0,this.useCpu=(o==null?void 0:o.forceCpu)??!1;const d=(o==null?void 0:o.maxLength)??8,f=(o==null?void 0:o.startingLength)??1,m=(o==null?void 0:o.useDictionary)??!0,h=(o==null?void 0:o.startFromType)??"bruteforce",x=a.toLowerCase(),p=await this.decodePacket(x);if(!p)return{found:!1,error:"Invalid packet or not a GroupText packet"};const{channelHash:v,ciphertext:y,cipherMac:w}=p,B=parseInt(v,16);this.useCpu?this.cpuInstance||(this.cpuInstance=new PA):this.gpuInstance||(this.gpuInstance=new sd,await this.gpuInstance.init()||(this.useCpu=!0,this.cpuInstance=new PA));const D=performance.now();let C=0,k=performance.now(),P=f,T=0,S=0,N=!1;if(o!=null&&o.startFrom){const J=o.startFrom.toLowerCase();if(h==="dictionary"){const re=this.wordlist.indexOf(J);re>=0&&(S=re+1)}else{N=!0;const re=sE(J);re&&(P=Math.max(f,re.length),T=re.index+1,T>=ol(P)&&(P++,T=0))}}let I=0;m&&!N&&this.wordlist.length>0&&(I+=this.wordlist.length-S);for(let J=P;J<=d;J++)I+=ol(J);I-=T;const j=(J,re,he)=>{if(!l)return;const pe=(performance.now()-D)/1e3,G=pe>0?Math.round(C/pe):0,Y=I-C,q=G>0?Y/G:0;l({checked:C,total:I,percent:I>0?Math.min(100,C/I*100):0,rateKeysPerSec:G,etaSeconds:q,elapsedSeconds:pe,currentLength:re,currentPosition:he,phase:J})},H=J=>{if(!Ux(y,w,J))return{valid:!1};const re=kA.ChannelCrypto.decryptGroupTextMessage(y,w,J);return!re.success||!re.data?{valid:!1}:this.useTimestampFilter&&!aE(re.data.timestamp,this.validSeconds)?{valid:!1}:this.useUtf8Filter&&!lE(re.data.message)?{valid:!1}:this.useSenderFilter&&!re.data.sender?{valid:!1}:{valid:!0,message:re.data.sender?`${re.data.sender}: ${re.data.message}`:re.data.message}};if(!N&&S===0&&P===f&&T===0){j("public-key",0,d0);const J=p0(Tc);if(v===J){const re=H(Tc);if(re.valid)return{found:!0,roomName:d0,key:Tc,decryptedMessage:re.message}}}if(m&&!N&&this.wordlist.length>0)for(let J=S;J<this.wordlist.length;J++){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:this.wordlist[J],resumeType:"dictionary"};const re=this.wordlist[J],he=h0("#"+re),ae=p0(he);if(parseInt(ae,16)===B){const G=H(he);if(G.valid)return{found:!0,roomName:re,key:he,decryptedMessage:G.message,resumeFrom:re,resumeType:"dictionary"}}C++;const pe=performance.now();pe-k>=200&&(j("wordlist",re.length,re),k=pe,await new Promise(G=>setTimeout(G,0)))}const z=this.useCpu?1024:32768,ee=(o==null?void 0:o.gpuDispatchMs)??1e3;let Z=z,V=!1;for(let J=P;J<=d;J++){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:qo(J,0)||void 0,resumeType:"bruteforce"};const re=ol(J);let he=J===P?T:0;for(;he<re;){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:qo(J,he)||void 0,resumeType:"bruteforce"};const ae=Math.min(Z,re-he),pe=performance.now();let G;this.useCpu?G=this.cpuInstance.runBatch(B,J,he,ae,y,w):G=await this.gpuInstance.runBatch(B,J,he,ae,y,w);const Y=performance.now()-pe;if(C+=ae,!this.useCpu&&!V&&ae>=z&&Y>0){const R=ee/Y,U=Math.round(ae*R),Q=Math.pow(2,Math.round(Math.log2(Math.max(z,U))));Z=Math.max(z,Q),V=!0}for(const R of G){const U=qo(J,R);if(!U)continue;const Q=h0("#"+U),$=H(Q);if($.valid)return{found:!0,roomName:U,key:Q,decryptedMessage:$.message,resumeFrom:U,resumeType:"bruteforce"}}he+=ae;const q=performance.now();if(q-k>=200){const R=qo(J,Math.min(he,re-1))||"";j("bruteforce",J,R),k=q,await new Promise(U=>setTimeout(U,0))}}}return{found:!1,resumeFrom:qo(d,ol(d)-1)||void 0,resumeType:"bruteforce"}}destroy(){this.gpuInstance&&(this.gpuInstance.destroy(),this.gpuInstance=null),this.cpuInstance&&(this.cpuInstance.destroy(),this.cpuInstance=null)}}var Yf,DA;function pE(){return DA||(DA=1,Yf={webm:"data:video/webm;base64,GkXfowEAAAAAAAAfQoaBAUL3gQFC8oEEQvOBCEKChHdlYm1Ch4EEQoWBAhhTgGcBAAAAAAAVkhFNm3RALE27i1OrhBVJqWZTrIHfTbuMU6uEFlSua1OsggEwTbuMU6uEHFO7a1OsghV17AEAAAAAAACkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmAQAAAAAAAEUq17GDD0JATYCNTGF2ZjU1LjMzLjEwMFdBjUxhdmY1NS4zMy4xMDBzpJBlrrXf3DCDVB8KcgbMpcr+RImIQJBgAAAAAAAWVK5rAQAAAAAAD++uAQAAAAA 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(h=>(this.enabled=!0,h)).catch(h=>{throw this.enabled=!1,h})}disable(){l()?(this._wakeLock&&this._wakeLock.release(),this._wakeLock=null):o()?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 Xf=d,Xf}var AE=mE();const gE=$s(AE);function xE(r){if(r.length<4)return null;try{const o=parseInt(r.slice(0,2),16)&3;let l=2;if(o===0||o===3){if(r.length<l+8)return null;l+=8}if(r.length<l+2)return null;const d=parseInt(r.slice(l,l+2),16);l+=2;const f=d*2;return r.length<l+f?null:(l+=f,r.slice(l))}catch{return null}}function vE({packets:r,channels:a,onChannelCreate:o,onRunningChange:l,visible:d=!1}){const[f,m]=F.useState(!1),[h,x]=F.useState(6),[p,v]=F.useState(!1),[y,w]=F.useState(!0),[B,D]=F.useState(!1),[C,k]=F.useState(null),[P,T]=F.useState(new Map),[S,N]=F.useState([]),[I,j]=F.useState(!1),[H,z]=F.useState(null),[ee,Z]=F.useState(null),[V,ne]=F.useState(0),J=F.useRef(null),re=F.useRef(null),he=F.useRef(!1),ae=F.useRef(!1),pe=F.useRef(!1),G=F.useRef(new Map),Y=F.useRef(!1),q=F.useRef(6),R=F.useRef(!0),U=F.useRef(!1),Q=F.useRef(new Set),$=F.useRef(new Set);F.useEffect(()=>{const Se=new hE;J.current=Se,z(Se.isGpuAvailable());const Ue=new gE;return re.current=Ue,()=>{Se.destroy(),J.current=null,Ue.disable(),re.current=null}},[]),F.useEffect(()=>{!d||I||db(async()=>{const{ENGLISH_WORDLIST:Se}=await import("./wordlist-BtmChKSf.js");return{ENGLISH_WORDLIST:Se}},[]).then(({ENGLISH_WORDLIST:Se})=>{J.current&&(J.current.setWordlist(Se),j(!0))}).catch(Se=>{console.error("Failed to load wordlist:",Se),kt.error("Failed to load wordlist",{description:"Cracking will not be available"})})},[d,I]),F.useEffect(()=>{const Se=()=>{st.getUndecryptedPacketCount().then(({count:lt})=>Z(lt)).catch(()=>Z(null))};Se();const Ue=setInterval(Se,3e4);return()=>clearInterval(Ue)},[]);const de=F.useMemo(()=>new Set(a.map(Se=>Se.key.toUpperCase())),[a]),fe=r.filter(Se=>Se.payload_type==="GROUP_TEXT"&&!Se.decrypted);F.useEffect(()=>{let Se=0;T(Ue=>{const lt=new Map(Ue);let Dt=!1;for(const xt of fe)if(!lt.has(xt.id)){const it=xE(xt.data);if(it&&$.current.has(it)){Se++;continue}it&&$.current.add(it),lt.set(xt.id,{packet:xt,attempts:0,lastAttemptLength:0,status:"pending"}),Dt=!0}return Dt?(G.current=lt,lt):Ue}),Se>0&&ne(Ue=>Ue+Se)},[fe.length]),F.useEffect(()=>{G.current=P},[P]),F.useEffect(()=>{Y.current=p},[p]),F.useEffect(()=>{q.current=h},[h]),F.useEffect(()=>{R.current=y},[y]),F.useEffect(()=>{U.current=B},[B]),F.useEffect(()=>{Q.current=new Set(fe.map(Se=>Se.id))},[fe]),F.useEffect(()=>{l==null||l(f)},[f,l]);const ke=Array.from(P.values()).filter(Se=>Se.status==="pending").length,ge=Array.from(P.values()).filter(Se=>Se.status==="cracked").length,Ze=Array.from(P.values()).filter(Se=>Se.status==="failed").length,$e=F.useCallback(async()=>{if(pe.current||!J.current||!he.current)return;const Se=G.current;let Ue=null,lt=null;for(const[Ke,Xe]of Se.entries())if(Xe.status==="pending"){Ue=Xe,lt=Ke;break}if(!Ue&&Y.current){const Ke=Array.from(Se.entries()).filter(([,Xe])=>Xe.status==="failed"&&Xe.lastAttemptLength<10);Ke.length>0&&(Ke.sort((Xe,xe)=>Xe[1].lastAttemptLength-xe[1].lastAttemptLength),[lt,Ue]=Ke[0])}if(!Ue||lt===null){he.current&&setTimeout(()=>$e(),1e3);return}if(!Q.current.has(lt)){T(Ke=>{const Xe=new Map(Ke);return Xe.delete(lt),Xe}),he.current&&setTimeout(()=>$e(),10);return}pe.current=!0;const Dt=q.current,xt=Ue.lastAttemptLength>0,it=xt?Ue.lastAttemptLength+1:Dt;try{const Ke=await J.current.crack(Ue.packet.data,{maxLength:it,useSenderFilter:!0,useTimestampFilter:!0,useUtf8Filter:!0,...U.current&&{gpuDispatchMs:1e4},...xt&&{useDictionary:!1,startingLength:it}},Xe=>{k(Xe)});if(ae.current){ae.current=!1,pe.current=!1,k(null);return}if(Ke.found&&Ke.roomName&&Ke.key){T(Te=>{const pt=new Map(Te),Ut=pt.get(lt);return Ut&&pt.set(lt,{...Ut,status:"cracked",attempts:Ut.attempts+1,lastAttemptLength:it}),pt});const Xe={roomName:Ke.roomName,key:Ke.key,packetId:lt,message:Ke.decryptedMessage||"",crackedAt:Date.now()};N(Te=>[...Te,Xe]);const xe=Ke.key.toUpperCase();if(!de.has(xe))try{const Te="#"+Ke.roomName;await o(Te,Ke.key),R.current&&await st.decryptHistoricalPackets({key_type:"channel",channel_name:Te})}catch(Te){console.error("Failed to create channel or decrypt historical:",Te),kt.error("Failed to save cracked channel",{description:Te instanceof Error?Te.message:"Channel discovered but could not be saved"})}}else T(Xe=>{const xe=new Map(Xe),Te=xe.get(lt);return Te&&xe.set(lt,{...Te,status:"failed",attempts:Te.attempts+1,lastAttemptLength:it}),xe})}catch(Ke){console.error("Cracking error:",Ke),T(Xe=>{const xe=new Map(Xe),Te=xe.get(lt);return Te&&xe.set(lt,{...Te,status:"failed",attempts:Te.attempts+1,lastAttemptLength:it}),xe})}pe.current=!1,k(null),he.current&&setTimeout(()=>$e(),100)},[de,o]),wt=()=>{var Se;if(!H){kt.error("WebGPU not available",{description:"Cracking requires Chrome 113+ or Edge 113+ with WebGPU support."});return}m(!0),he.current=!0,ae.current=!1,(Se=re.current)==null||Se.enable(),$e()},ft=()=>{var Se,Ue;m(!1),he.current=!1,ae.current=!0,(Se=J.current)==null||Se.abort(),(Ue=re.current)==nu Line truncated
//# sourceMappingURL=index-DlEnSqQ7.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,IAAI,EAAE,CAAC,UAAU,UAAU,CAAC,MAAM,EAAE,EAAE,mBAAmB,UAAU,GAAG,oBAAoB,UAAU,GAAG,gBAAgB,UAAU,EAAE,EAAEC,EAAE,OAAO,OAAOC,EAAE,GAAG,SAASC,EAAEH,EAAEI,EAAEC,EAAE,CAAC,KAAK,MAAML,EAAE,KAAK,QAAQI,EAAE,KAAK,KAAKF,EAAE,KAAK,QAAQG,GAAG,CAAC,CAACF,EAAE,UAAU,iBAAiB,GACnQA,EAAE,UAAU,SAAS,SAASH,EAAEI,EAAE,CAAC,GAAc,OAAOJ,GAAlB,UAAkC,OAAOA,GAApB,YAA6BA,GAAN,KAAQ,MAAM,MAAM,uHAAuH,EAAE,KAAK,QAAQ,gBAAgB,KAAKA,EAAEI,EAAE,UAAU,CAAC,EAAED,EAAE,UAAU,YAAY,SAASH,EAAE,CAAC,KAAK,QAAQ,mBAAmB,KAAKA,EAAE,aAAa,CAAC,EAAE,SAASM,GAAG,EAAEA,EAAE,UAAUH,EAAE,UAAU,SAASI,EAAEP,EAAEI,EAAEC,EAAE,CAAC,KAAK,MAAML,EAAE,KAAK,QAAQI,EAAE,KAAK,KAAKF,EAAE,KAAK,QAAQG,GAAG,CAAC,CAAC,IAAIG,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,EAAEb,EAAEI,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,GAAGnB,GAAGA,EAAE,aAAa,IAAIc,KAAKI,GAAElB,EAAE,aAAakB,GAAWH,GAAED,CAAC,IAAZ,SAAgBC,GAAED,CAAC,EAAEI,GAAEJ,CAAC,GAAG,MAAM,CAAC,SAAS3B,EAAE,KAAKa,EAAE,IAAIgB,GAAE,IAAIC,GAAE,MAAMF,GAAE,OAAOJ,EAAE,OAAO,CAAC,CAC7a,SAASU,GAAErB,EAAEI,EAAE,CAAC,MAAM,CAAC,SAASjB,EAAE,KAAKa,EAAE,KAAK,IAAII,EAAE,IAAIJ,EAAE,IAAI,MAAMA,EAAE,MAAM,OAAOA,EAAE,MAAM,CAAC,CAAC,SAASsB,EAAEtB,EAAE,CAAC,OAAiB,OAAOA,GAAlB,UAA4BA,IAAP,MAAUA,EAAE,WAAWb,CAAC,CAAC,SAASoC,EAAOvB,EAAE,CAAC,IAAII,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,EAAE,MAAM,IAAIJ,EAAE,QAAQ,QAAQ,SAASA,EAAE,CAAC,OAAOI,EAAEJ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAIwB,GAAE,OAAO,SAASC,EAAEzB,EAAEI,EAAE,CAAC,OAAiB,OAAOJ,GAAlB,UAA4BA,IAAP,MAAgBA,EAAE,KAAR,KAAYuB,EAAO,GAAGvB,EAAE,GAAG,EAAEI,EAAE,SAAS,EAAE,CAAC,CAC/W,SAASsB,GAAE1B,EAAEI,EAAEC,EAAES,EAAEC,GAAE,CAAC,IAAIC,GAAE,OAAOhB,GAAmBgB,KAAd,aAA6BA,KAAZ,aAAchB,EAAE,MAAK,IAAIiB,GAAE,GAAG,GAAUjB,IAAP,KAASiB,GAAE,OAAQ,QAAOD,GAAC,CAAE,IAAK,SAAS,IAAK,SAASC,GAAE,GAAG,MAAM,IAAK,SAAS,OAAOjB,EAAE,SAAQ,CAAE,KAAKb,EAAE,KAAKC,EAAE6B,GAAE,EAAE,CAAC,CAAC,GAAGA,GAAE,OAAOA,GAAEjB,EAAEe,GAAEA,GAAEE,EAAC,EAAEjB,EAAOc,IAAL,GAAO,IAAIW,EAAER,GAAE,CAAC,EAAEH,EAAEL,EAAEM,EAAC,GAAGV,EAAE,GAASL,GAAN,OAAUK,EAAEL,EAAE,QAAQwB,GAAE,KAAK,EAAE,KAAKE,GAAEX,GAAEX,EAAEC,EAAE,GAAG,SAASL,GAAE,CAAC,OAAOA,EAAC,CAAC,GAASe,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,KAAKxB,CAAC,GAAGI,EAAE,KAAKW,EAAC,GAAG,EAAyB,GAAvBE,GAAE,EAAEH,EAAOA,IAAL,GAAO,IAAIA,EAAE,IAAOL,EAAET,CAAC,EAAE,QAAQkB,GAAE,EAAEA,GAAElB,EAAE,OAAOkB,KAAI,CAACF,GACrfhB,EAAEkB,EAAC,EAAE,IAAIC,GAAEL,EAAEW,EAAET,GAAEE,EAAC,EAAED,IAAGS,GAAEV,GAAEZ,EAAEC,EAAEc,GAAEJ,EAAC,CAAC,SAASI,GAAEpB,EAAEC,CAAC,EAAe,OAAOmB,IAApB,WAAsB,IAAInB,EAAEmB,GAAE,KAAKnB,CAAC,EAAEkB,GAAE,EAAE,EAAEF,GAAEhB,EAAE,KAAI,GAAI,MAAMgB,GAAEA,GAAE,MAAMG,GAAEL,EAAEW,EAAET,GAAEE,IAAG,EAAED,IAAGS,GAAEV,GAAEZ,EAAEC,EAAEc,GAAEJ,EAAC,UAAqBC,KAAX,SAAa,MAAMZ,EAAE,OAAOJ,CAAC,EAAE,MAAM,mDAAuEI,IAApB,kBAAsB,qBAAqB,OAAO,KAAKJ,CAAC,EAAE,KAAK,IAAI,EAAE,IAAII,GAAG,2EAA2E,EAAE,OAAOa,EAAC,CACzZ,SAASU,GAAE3B,EAAEI,EAAEC,EAAE,CAAC,GAASL,GAAN,KAAQ,OAAOA,EAAE,IAAIc,EAAE,GAAGC,GAAE,EAAE,OAAAW,GAAE1B,EAAEc,EAAE,GAAG,GAAG,SAASd,GAAE,CAAC,OAAOI,EAAE,KAAKC,EAAEL,GAAEe,IAAG,CAAC,CAAC,EAASD,CAAC,CAAC,SAASc,GAAE5B,EAAE,CAAC,GAAQA,EAAE,UAAP,GAAe,CAAC,IAAII,EAAEJ,EAAE,QAAQI,EAAEA,EAAC,EAAGA,EAAE,KAAK,SAASA,EAAE,EAAQJ,EAAE,UAAN,GAAoBA,EAAE,UAAP,MAAeA,EAAE,QAAQ,EAAEA,EAAE,QAAQI,EAAC,EAAE,SAASA,EAAE,EAAQJ,EAAE,UAAN,GAAoBA,EAAE,UAAP,MAAeA,EAAE,QAAQ,EAAEA,EAAE,QAAQI,EAAC,CAAC,EAAOJ,EAAE,UAAP,KAAiBA,EAAE,QAAQ,EAAEA,EAAE,QAAQI,EAAE,CAAC,GAAOJ,EAAE,UAAN,EAAc,OAAOA,EAAE,QAAQ,QAAQ,MAAMA,EAAE,OAAQ,CAC5Z,IAAI6B,GAAE,CAAC,QAAQ,IAAI,EAAEC,EAAE,CAAC,WAAW,IAAI,EAAEC,EAAE,CAAC,uBAAuBF,GAAE,wBAAwBC,EAAE,kBAAkBnB,CAAC,EAAE,SAASqB,GAAG,CAAC,MAAM,MAAM,0DAA0D,CAAE,CACzM,OAAAC,GAAA,SAAiB,CAAC,IAAIN,GAAE,QAAQ,SAAS3B,EAAEI,EAAEC,EAAE,CAACsB,GAAE3B,EAAE,UAAU,CAACI,EAAE,MAAM,KAAK,SAAS,CAAC,EAAEC,CAAC,CAAC,EAAE,MAAM,SAASL,EAAE,CAAC,IAAII,EAAE,EAAE,OAAAuB,GAAE3B,EAAE,UAAU,CAACI,GAAG,CAAC,EAASA,CAAC,EAAE,QAAQ,SAASJ,EAAE,CAAC,OAAO2B,GAAE3B,EAAE,SAASA,EAAE,CAAC,OAAOA,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,SAASA,EAAE,CAAC,GAAG,CAACsB,EAAEtB,CAAC,EAAE,MAAM,MLine truncated
+542
View File
@@ -0,0 +1,542 @@
var Dv=Object.defineProperty;var Rv=(r,a,o)=>a in r?Dv(r,a,{enumerable:!0,configurable:!0,writable:!0,value:o}):r[a]=o;var Oo=(r,a,o)=>Rv(r,typeof a!="symbol"?a+"":a,o);function Fv(r,a){for(var o=0;o<a.length;o++){const l=a[o];if(typeof l!="string"&&!Array.isArray(l)){for(const d in l)if(d!=="default"&&!(d in r)){const f=Object.getOwnPropertyDescriptor(l,d);f&&Object.defineProperty(r,d,f.get?f:{enumerable:!0,get:()=>l[d]})}}}return Object.freeze(Object.defineProperty(r,Symbol.toStringTag,{value:"Module"}))}(function(){const a=document.createElement("link").relList;if(a&&a.supports&&a.supports("modulepreload"))return;for(const d of document.querySelectorAll('link[rel="modulepreload"]'))l(d);new MutationObserver(d=>{for(const f of d)if(f.type==="childList")for(const p of f.addedNodes)p.tagName==="LINK"&&p.rel==="modulepreload"&&l(p)}).observe(document,{childList:!0,subtree:!0});function o(d){const f={};return d.integrity&&(f.integrity=d.integrity),d.referrerPolicy&&(f.referrerPolicy=d.referrerPolicy),d.crossOrigin==="use-credentials"?f.credentials="include":d.crossOrigin==="anonymous"?f.credentials="omit":f.credentials="same-origin",f}function l(d){if(d.ep)return;d.ep=!0;const f=o(d);fetch(d.href,f)}})();var Tf=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Ys(r){return r&&r.__esModule&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}function Mg(r){if(Object.prototype.hasOwnProperty.call(r,"__esModule"))return r;var a=r.default;if(typeof a=="function"){var o=function l(){return this instanceof l?Reflect.construct(a,arguments,this.constructor):a.apply(this,arguments)};o.prototype=a.prototype}else o={};return Object.defineProperty(o,"__esModule",{value:!0}),Object.keys(r).forEach(function(l){var d=Object.getOwnPropertyDescriptor(r,l);Object.defineProperty(o,l,d.get?d:{enumerable:!0,get:function(){return r[l]}})}),o}var Df={exports:{}},Za={},Rf={exports:{}},ut={};/**
* @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 Sp;function Nv(){if(Sp)return ut;Sp=1;var r=Symbol.for("react.element"),a=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),l=Symbol.for("react.strict_mode"),d=Symbol.for("react.profiler"),f=Symbol.for("react.provider"),p=Symbol.for("react.context"),h=Symbol.for("react.forward_ref"),g=Symbol.for("react.suspense"),m=Symbol.for("react.memo"),v=Symbol.for("react.lazy"),y=Symbol.iterator;function w(R){return R===null||typeof R!="object"?null:(R=y&&R[y]||R["@@iterator"],typeof R=="function"?R:null)}var B={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},T=Object.assign,b={};function k(R,U,K){this.props=R,this.context=U,this.refs=b,this.updater=K||B}k.prototype.isReactComponent={},k.prototype.setState=function(R,U){if(typeof R!="object"&&typeof R!="function"&&R!=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,R,U,"setState")},k.prototype.forceUpdate=function(R){this.updater.enqueueForceUpdate(this,R,"forceUpdate")};function D(){}D.prototype=k.prototype;function P(R,U,K){this.props=R,this.context=U,this.refs=b,this.updater=K||B}var S=P.prototype=new D;S.constructor=P,T(S,k.prototype),S.isPureReactComponent=!0;var N=Array.isArray,I=Object.prototype.hasOwnProperty,z={current:null},H={key:!0,ref:!0,__self:!0,__source:!0};function j(R,U,K){var $,de={},fe=null,ke=null;if(U!=null)for($ in U.ref!==void 0&&(ke=U.ref),U.key!==void 0&&(fe=""+U.key),U)I.call(U,$)&&!H.hasOwnProperty($)&&(de[$]=U[$]);var Ae=arguments.length-2;if(Ae===1)de.children=K;else if(1<Ae){for(var We=Array(Ae),$e=0;$e<Ae;$e++)We[$e]=arguments[$e+2];de.children=We}if(R&&R.defaultProps)for($ in Ae=R.defaultProps,Ae)de[$]===void 0&&(de[$]=Ae[$]);return{$$typeof:r,type:R,key:fe,ref:ke,props:de,_owner:z.current}}function ee(R,U){return{$$typeof:r,type:R.type,key:U,ref:R.ref,props:R.props,_owner:R._owner}}function Z(R){return typeof R=="object"&&R!==null&&R.$$typeof===r}function V(R){var U={"=":"=0",":":"=2"};return"$"+R.replace(/[=:]/g,function(K){return U[K]})}var ne=/\/+/g;function J(R,U){return typeof R=="object"&&R!==null&&R.key!=null?V(""+R.key):U.toString(36)}function ie(R,U,K,$,de){var fe=typeof R;(fe==="undefined"||fe==="boolean")&&(R=null);var ke=!1;if(R===null)ke=!0;else switch(fe){case"string":case"number":ke=!0;break;case"object":switch(R.$$typeof){case r:case a:ke=!0}}if(ke)return ke=R,de=de(ke),R=$===""?"."+J(ke,0):$,N(de)?(K="",R!=null&&(K=R.replace(ne,"$&/")+"/"),ie(de,U,K,"",function($e){return $e})):de!=null&&(Z(de)&&(de=ee(de,K+(!de.key||ke&&ke.key===de.key?"":(""+de.key).replace(ne,"$&/")+"/")+R)),U.push(de)),1;if(ke=0,$=$===""?".":$+":",N(R))for(var Ae=0;Ae<R.length;Ae++){fe=R[Ae];var We=$+J(fe,Ae);ke+=ie(fe,U,K,We,de)}else if(We=w(R),typeof We=="function")for(R=We.call(R),Ae=0;!(fe=R.next()).done;)fe=fe.value,We=$+J(fe,Ae++),ke+=ie(fe,U,K,We,de);else if(fe==="object")throw U=String(R),Error("Objects are not valid as a React child (found: "+(U==="[object Object]"?"object with keys {"+Object.keys(R).join(", ")+"}":U)+"). If you meant to render a collection of children, use an array instead.");return ke}function he(R,U,K){if(R==null)return R;var $=[],de=0;return ie(R,$,"","",function(fe){return U.call(K,fe,de++)}),$}function ae(R){if(R._status===-1){var U=R._result;U=U(),U.then(function(K){(R._status===0||R._status===-1)&&(R._status=1,R._result=K)},function(K){(R._status===0||R._status===-1)&&(R._status=2,R._result=K)}),R._status===-1&&(R._status=0,R._result=U)}if(R._status===1)return R._result.default;throw R._result}var pe={current:null},G={transition:null},Y={ReactCurrentDispatcher:pe,ReactCurrentBatchConfig:G,ReactCurrentOwner:z};function q(){throw Error("act(...) is not supported in production builds of React.")}return ut.Children={map:he,forEach:function(R,U,K){he(R,function(){U.apply(this,arguments)},K)},count:function(R){var U=0;return he(R,function(){U++}),U},toArray:function(R){return he(R,function(U){return U})||[]},only:function(R){if(!Z(R))throw Error("React.Children.only expected to receive a single React element child.");return R}},ut.Component=k,ut.Fragment=o,ut.Profiler=d,ut.PureComponent=P,ut.StrictMode=l,ut.Suspense=g,ut.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=Y,ut.act=q,ut.cloneElement=function(R,U,K){if(R==null)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+R+".");var $=T({},R.props),de=R.key,fe=R.ref,ke=R._owner;if(U!=null){if(U.ref!==void 0&&(fe=U.ref,ke=z.current),U.key!==void 0&&(de=""+U.key),R.type&&R.type.defaultProps)var Ae=R.type.defaultProps;for(We in U)I.call(U,We)&&!H.hasOwnProperty(We)&&($[We]=U[We]===void 0&&Ae!==void 0?Ae[We]:U[We])}var We=arguments.length-2;if(We===1)$.children=K;else if(1<We){Ae=Array(We);for(var $e=0;$e<We;$e++)Ae[$e]=arguments[$e+2];$.children=Ae}return{$$typeof:r,type:R.type,key:de,ref:fe,props:$,_owner:ke}},ut.creLine 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 Pp;function Lv(){if(Pp)return Za;Pp=1;var r=g0(),a=Symbol.for("react.element"),o=Symbol.for("react.fragment"),l=Object.prototype.hasOwnProperty,d=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,f={key:!0,ref:!0,__self:!0,__source:!0};function p(h,g,m){var v,y={},w=null,B=null;m!==void 0&&(w=""+m),g.key!==void 0&&(w=""+g.key),g.ref!==void 0&&(B=g.ref);for(v in g)l.call(g,v)&&!f.hasOwnProperty(v)&&(y[v]=g[v]);if(h&&h.defaultProps)for(v in g=h.defaultProps,g)y[v]===void 0&&(y[v]=g[v]);return{$$typeof:a,type:h,key:w,ref:B,props:y,_owner:d.current}}return Za.Fragment=o,Za.jsx=p,Za.jsxs=p,Za}var Tp;function Mv(){return Tp||(Tp=1,Df.exports=Lv()),Df.exports}var E=Mv(),F=g0();const Ce=Ys(F),A0=Fv({__proto__:null,default:Ce},[F]);var Pu={},Ff={exports:{}},Zn={},Nf={exports:{}},Lf={};/**
* @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 Dp;function Iv(){return Dp||(Dp=1,(function(r){function a(G,Y){var q=G.length;G.push(Y);e:for(;0<q;){var R=q-1>>>1,U=G[R];if(0<d(U,Y))G[R]=Y,G[q]=U,q=R;else break e}}function o(G){return G.length===0?null:G[0]}function l(G){if(G.length===0)return null;var Y=G[0],q=G.pop();if(q!==Y){G[0]=q;e:for(var R=0,U=G.length,K=U>>>1;R<K;){var $=2*(R+1)-1,de=G[$],fe=$+1,ke=G[fe];if(0>d(de,q))fe<U&&0>d(ke,de)?(G[R]=ke,G[fe]=q,R=fe):(G[R]=de,G[$]=q,R=$);else if(fe<U&&0>d(ke,q))G[R]=ke,G[fe]=q,R=fe;else break e}}return Y}function d(G,Y){var q=G.sortIndex-Y.sortIndex;return q!==0?q:G.id-Y.id}if(typeof performance=="object"&&typeof performance.now=="function"){var f=performance;r.unstable_now=function(){return f.now()}}else{var p=Date,h=p.now();r.unstable_now=function(){return p.now()-h}}var g=[],m=[],v=1,y=null,w=3,B=!1,T=!1,b=!1,k=typeof setTimeout=="function"?setTimeout:null,D=typeof clearTimeout=="function"?clearTimeout:null,P=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function S(G){for(var Y=o(m);Y!==null;){if(Y.callback===null)l(m);else if(Y.startTime<=G)l(m),Y.sortIndex=Y.expirationTime,a(g,Y);else break;Y=o(m)}}function N(G){if(b=!1,S(G),!T)if(o(g)!==null)T=!0,ae(I);else{var Y=o(m);Y!==null&&pe(N,Y.startTime-G)}}function I(G,Y){T=!1,b&&(b=!1,D(j),j=-1),B=!0;var q=w;try{for(S(Y),y=o(g);y!==null&&(!(y.expirationTime>Y)||G&&!V());){var R=y.callback;if(typeof R=="function"){y.callback=null,w=y.priorityLevel;var U=R(y.expirationTime<=Y);Y=r.unstable_now(),typeof U=="function"?y.callback=U:y===o(g)&&l(g),S(Y)}else l(g);y=o(g)}if(y!==null)var K=!0;else{var $=o(m);$!==null&&pe(N,$.startTime-Y),K=!1}return K}finally{y=null,w=q,B=!1}}var z=!1,H=null,j=-1,ee=5,Z=-1;function V(){return!(r.unstable_now()-Z<ee)}function ne(){if(H!==null){var G=r.unstable_now();Z=G;var Y=!0;try{Y=H(!0,G)}finally{Y?J():(z=!1,H=null)}}else z=!1}var J;if(typeof P=="function")J=function(){P(ne)};else if(typeof MessageChannel<"u"){var ie=new MessageChannel,he=ie.port2;ie.port1.onmessage=ne,J=function(){he.postMessage(null)}}else J=function(){k(ne,0)};function ae(G){H=G,z||(z=!0,J())}function pe(G,Y){j=k(function(){G(r.unstable_now())},Y)}r.unstable_IdlePriority=5,r.unstable_ImmediatePriority=1,r.unstable_LowPriority=4,r.unstable_NormalPriority=3,r.unstable_Profiling=null,r.unstable_UserBlockingPriority=2,r.unstable_cancelCallback=function(G){G.callback=null},r.unstable_continueExecution=function(){T||B||(T=!0,ae(I))},r.unstable_forceFrameRate=function(G){0>G||125<G?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):ee=0<G?Math.floor(1e3/G):5},r.unstable_getCurrentPriorityLevel=function(){return w},r.unstable_getFirstCallbackNode=function(){return o(g)},r.unstable_next=function(G){switch(w){case 1:case 2:case 3:var Y=3;break;default:Y=w}var q=w;w=Y;try{return G()}finally{w=q}},r.unstable_pauseExecution=function(){},r.unstable_requestPaint=function(){},r.unstable_runWithPriority=function(G,Y){switch(G){case 1:case 2:case 3:case 4:case 5:break;default:G=3}var q=w;w=G;try{return Y()}finally{w=q}},r.unstable_scheduleCallback=function(G,Y,q){var R=r.unstable_now();switch(typeof q=="object"&&q!==null?(q=q.delay,q=typeof q=="number"&&0<q?R+q:R):q=R,G){case 1:var U=-1;break;case 2:U=250;break;case 5:U=1073741823;break;case 4:U=1e4;break;default:U=5e3}return U=q+U,G={id:v++,callback:Y,priorityLevel:G,startTime:q,expirationTime:U,sortIndex:-1},q>R?(G.sortIndex=q,a(m,G),o(g)===null&&G===o(m)&&(b?(D(j),j=-1):b=!0,pe(N,q-R))):(G.sortIndex=U,a(g,G),T||B||(T=!0,ae(I))),G},r.unstable_shouldYield=V,r.unstable_wrapCallback=function(G){var Y=w;return function(){var q=w;w=Y;try{return G.apply(this,arguments)}finally{w=q}}}})(Lf)),Lf}var Rp;function Ov(){return Rp||(Rp=1,Nf.exports=Iv()),Nf.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 Fp;function jv(){if(Fp)return Zn;Fp=1;var r=g0(),a=Ov();function o(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,s=1;s<arguments.length;s++)n+="&args[]="+encodeURIComponent(arguments[s]);return"Minified React error #"+e+"; visit "+n+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var l=new Set,d={};function f(e,n){p(e,n),p(e+"Capture",n)}function p(e,n){for(d[e]=n,e=0;e<n.length;e++)l.add(n[e])}var h=!(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]*$/,v={},y={};function w(e){return g.call(y,e)?!0:g.call(v,e)?!1:m.test(e)?y[e]=!0:(v[e]=!0,!1)}function B(e,n,s,c){if(s!==null&&s.type===0)return!1;switch(typeof n){case"function":case"symbol":return!0;case"boolean":return c?!1:s!==null?!s.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function T(e,n,s,c){if(n===null||typeof n>"u"||B(e,n,s,c))return!0;if(c)return!1;if(s!==null)switch(s.type){case 3:return!n;case 4:return n===!1;case 5:return isNaN(n);case 6:return isNaN(n)||1>n}return!1}function b(e,n,s,c,x,_,M){this.acceptsBooleans=n===2||n===3||n===4,this.attributeName=c,this.attributeNamespace=x,this.mustUseProperty=s,this.propertyName=e,this.type=n,this.sanitizeURL=_,this.removeEmptyString=M}var k={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){k[e]=new b(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var n=e[0];k[n]=new b(n,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){k[e]=new b(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){k[e]=new b(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){k[e]=new b(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){k[e]=new b(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){k[e]=new b(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){k[e]=new b(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){k[e]=new b(e,5,!1,e.toLowerCase(),null,!1,!1)});var D=/[\-:]([a-z])/g;function P(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 n=e.replace(D,P);k[n]=new b(n,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var n=e.replace(D,P);k[n]=new b(n,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var n=e.replace(D,P);k[n]=new b(n,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){k[e]=new b(e,1,!1,e.toLowerCase(),null,!1,!1)}),k.xlinkHref=new b("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){k[e]=new b(e,1,!1,e.toLowerCase(),null,!0,!0)});function S(e,n,s,c){var x=k.hasOwnProperty(n)?k[n]:null;(x!==null?x.type!==0:c||!(2<n.length)||n[0]!=="o"&&n[0]!=="O"||n[1]!=="n"&&n[1]!= Line truncated
`+R+e}var K=!1;function $(e,n){if(!e||K)return"";K=!0;var s=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(n)if(n=function(){throw Error()},Object.defineProperty(n.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(n,[])}catch(ce){var c=ce}Reflect.construct(e,[],n)}else{try{n.call()}catch(ce){c=ce}e.call(n.prototype)}else{try{throw Error()}catch(ce){c=ce}e()}}catch(ce){if(ce&&c&&typeof ce.stack=="string"){for(var x=ce.stack.split(`
`),_=c.stack.split(`
`),M=x.length-1,W=_.length-1;1<=M&&0<=W&&x[M]!==_[W];)W--;for(;1<=M&&0<=W;M--,W--)if(x[M]!==_[W]){if(M!==1||W!==1)do if(M--,W--,0>W||x[M]!==_[W]){var X=`
`+x[M].replace(" at new "," at ");return e.displayName&&X.includes("<anonymous>")&&(X=X.replace("<anonymous>",e.displayName)),X}while(1<=M&&0<=W);break}}}finally{K=!1,Error.prepareStackTrace=s}return(e=e?e.displayName||e.name:"")?U(e):""}function de(e){switch(e.tag){case 5:return U(e.type);case 16:return U("Lazy");case 13:return U("Suspense");case 19:return U("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 fe(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 H:return"Fragment";case z:return"Portal";case ee:return"Profiler";case j:return"StrictMode";case J:return"Suspense";case ie:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case V:return(e.displayName||"Context")+".Consumer";case Z:return(e._context.displayName||"Context")+".Provider";case ne:var n=e.render;return e=e.displayName,e||(e=n.displayName||n.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case he:return n=e.displayName||null,n!==null?n:fe(e.type)||"Memo";case ae:n=e._payload,e=e._init;try{return fe(e(n))}catch{}}return null}function ke(e){var n=e.type;switch(e.tag){case 24:return"Cache";case 9:return(n.displayName||"Context")+".Consumer";case 10:return(n._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=n.render,e=e.displayName||e.name||"",n.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return n;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return fe(n);case 8:return n===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 n=="function")return n.displayName||n.name||null;if(typeof n=="string")return n}return null}function Ae(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function We(e){var n=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(n==="checkbox"||n==="radio")}function $e(e){var n=We(e)?"checked":"value",s=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),c=""+e[n];if(!e.hasOwnProperty(n)&&typeof s<"u"&&typeof s.get=="function"&&typeof s.set=="function"){var x=s.get,_=s.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return x.call(this)},set:function(M){c=""+M,_.call(this,M)}}),Object.defineProperty(e,n,{enumerable:s.enumerable}),{getValue:function(){return c},setValue:function(M){c=""+M},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}function wt(e){e._valueTracker||(e._valueTracker=$e(e))}function ft(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var s=n.getValue(),c="";return e&&(c=We(e)?e.checked?"true":"false":e.value),e=c,e!==s?(n.setValue(e),!0):!1}function Se(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 Ze(e,n){var s=n.checked;return q({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:s??e._wrapperState.initialChecked})}function lt(e,n){var s=n.defaultValue==null?"":n.defaultValue,c=n.checked!=null?n.checked:n.defaultChecked;s=Ae(n.value!=null?n.value:s),e._wrapperState={initialChecked:c,initialValue:s,controlled:n.type==="checkbox"||n.type==="radio"?n.checked!=null:n.value!=null}}function Rt(e,n){n=n.checked,n!=null&&S(e,"checked",n,!1)}function xt(e,n){Rt(e,n);var s=Ae(n.value),c=n.type;if(s!=null)c==="number"?(s===0&&e.value===""||e.value!=s)&&(e.value=""+s):e.value!==""+s&&(e.value=""+s);else if(c==="submit"||c==="reset"){e.removeAttribute("value");return}n.hasOwnProperty("value")?Qe(e,n.type,s):n.hasOwnProperty("defaultValue")&&Qe(e,n.type,Ae(n.defaultValue)),n.checked==null&&n.defaultChecked!=null&&(e.defaultChecked=!!n.defaultChecked)}function it(e,n,s){if(n.hasOwnProperty("value")||n.hasOwnProperty("defaultValue")){var c=n.type;if(!(c!=="submit"&&c!=="reset"||n.value!==void 0&&n.value!==null))return;n=""+e._wrapperState.initialValue,s||n===e.value||(e.value=n),e.defaultValue=n}s=e.name,s!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,s!==""&&(e.name=s)}function Qe(e,n,s){(n!=="number"||Se(e.ownerDocument)!==e)&&(s==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+s&&(e.defaultValue=""+s))}var Xe=Array.isArray;function xe(e,n,s,c){if(e=e.options,n){n={};for(var x=0;x<s.length;x++)n["$"+s[x]]=!0;for(s=0;s<e.length;s++)x=n.hasOwnProperty("$"+e[s].value),e[s].selected!==x&&(e[s].selected=x),x&&c&&(e[s].defaultSelected=!0)}else{for(s=""+Ae(s),n=null,x=0;x<e.length;x++){if(e[x].value===s){e[x].selected=!0,c&&(e[x].defaultSelected=!0);return}n!==null||e[x].disabled||(n=e[x])}n!==null&&(n.selected=!0)}}function Te(e,n){if(n.dangerouslySetInnerHT Line truncated
`).replace(Q,"")}function ue(e,n,s){if(n=oe(n),oe(e)!==n&&s)throw Error(o(425))}function ve(){}var Pe=null,qe=null;function nt(e,n){return e==="textarea"||e==="noscript"||typeof n.children=="string"||typeof n.children=="number"||typeof n.dangerouslySetInnerHTML=="object"&&n.dangerouslySetInnerHTML!==null&&n.dangerouslySetInnerHTML.__html!=null}var on=typeof setTimeout=="function"?setTimeout:void 0,Jt=typeof clearTimeout=="function"?clearTimeout:void 0,Fn=typeof Promise=="function"?Promise:void 0,bn=typeof queueMicrotask=="function"?queueMicrotask:typeof Fn<"u"?function(e){return Fn.resolve(null).then(e).catch(qi)}:on;function qi(e){setTimeout(function(){throw e})}function Pa(e,n){var s=n,c=0;do{var x=s.nextSibling;if(e.removeChild(s),x&&x.nodeType===8)if(s=x.data,s==="/$"){if(c===0){e.removeChild(x),Yn(n);return}c--}else s!=="$"&&s!=="$?"&&s!=="$!"||c++;s=x}while(s);Yn(n)}function Ur(e){for(;e!=null;e=e.nextSibling){var n=e.nodeType;if(n===1||n===3)break;if(n===8){if(n=e.data,n==="$"||n==="$!"||n==="$?")break;if(n==="/$")return null}}return e}function Zl(e){e=e.previousSibling;for(var n=0;e;){if(e.nodeType===8){var s=e.data;if(s==="$"||s==="$!"||s==="$?"){if(n===0)return e;n--}else s==="/$"&&n++}e=e.previousSibling}return null}var ci=Math.random().toString(36).slice(2),fr="__reactFiber$"+ci,Gi="__reactProps$"+ci,_t="__reactContainer$"+ci,Ki="__reactEvents$"+ci,Cd="__reactListeners$"+ci,Ed="__reactHandles$"+ci;function di(e){var n=e[fr];if(n)return n;for(var s=e.parentNode;s;){if(n=s[_t]||s[fr]){if(s=n.alternate,n.child!==null||s!==null&&s.child!==null)for(e=Zl(e);e!==null;){if(s=e[fr])return s;e=Zl(e)}return n}e=s,s=e.parentNode}return null}function fi(e){return e=e[fr]||e[_t],!e||e.tag!==5&&e.tag!==6&&e.tag!==13&&e.tag!==3?null:e}function hi(e){if(e.tag===5||e.tag===6)return e.stateNode;throw Error(o(33))}function ws(e){return e[Gi]||null}var kd=[],bs=-1;function Qi(e){return{current:e}}function Nt(e){0>bs||(e.current=kd[bs],kd[bs]=null,bs--)}function Dt(e,n){bs++,kd[bs]=e.current,e.current=n}var $i={},Cn=Qi($i),jn=Qi(!1),So=$i;function Cs(e,n){var s=e.type.contextTypes;if(!s)return $i;var c=e.stateNode;if(c&&c.__reactInternalMemoizedUnmaskedChildContext===n)return c.__reactInternalMemoizedMaskedChildContext;var x={},_;for(_ in s)x[_]=n[_];return c&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=x),x}function zn(e){return e=e.childContextTypes,e!=null}function Wl(){Nt(jn),Nt(Cn)}function Q0(e,n,s){if(Cn.current!==$i)throw Error(o(168));Dt(Cn,n),Dt(jn,s)}function $0(e,n,s){var c=e.stateNode;if(n=n.childContextTypes,typeof c.getChildContext!="function")return s;c=c.getChildContext();for(var x in c)if(!(x in n))throw Error(o(108,ke(e)||"Unknown",x));return q({},s,c)}function ql(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||$i,So=Cn.current,Dt(Cn,e),Dt(jn,jn.current),!0}function Y0(e,n,s){var c=e.stateNode;if(!c)throw Error(o(169));s?(e=$0(e,n,So),c.__reactInternalMemoizedMergedChildContext=e,Nt(jn),Nt(Cn),Dt(Cn,e)):Nt(jn),Dt(jn,s)}var pi=null,Gl=!1,Sd=!1;function X0(e){pi===null?pi=[e]:pi.push(e)}function $x(e){Gl=!0,X0(e)}function Yi(){if(!Sd&&pi!==null){Sd=!0;var e=0,n=ht;try{var s=pi;for(ht=1;e<s.length;e++){var c=s[e];do c=c(!0);while(c!==null)}pi=null,Gl=!1}catch(x){throw pi!==null&&(pi=pi.slice(e+1)),yl(ia,Yi),x}finally{ht=n,Sd=!1}}return null}var Es=[],ks=0,Kl=null,Ql=0,hr=[],pr=0,Bo=null,mi=1,gi="";function Po(e,n){Es[ks++]=Ql,Es[ks++]=Kl,Kl=e,Ql=n}function J0(e,n,s){hr[pr++]=mi,hr[pr++]=gi,hr[pr++]=Bo,Bo=e;var c=mi;e=gi;var x=32-tt(c)-1;c&=~(1<<x),s+=1;var _=32-tt(n)+x;if(30<_){var M=x-x%5;_=(c&(1<<M)-1).toString(32),c>>=M,x-=M,mi=1<<32-tt(n)+x|s<<x|c,gi=_+e}else mi=1<<_|s<<x|c,gi=e}function Bd(e){e.return!==null&&(Po(e,1),J0(e,1,0))}function Pd(e){for(;e===Kl;)Kl=Es[--ks],Es[ks]=null,Ql=Es[--ks],Es[ks]=null;for(;e===Bo;)Bo=hr[--pr],hr[pr]=null,gi=hr[--pr],hr[pr]=null,mi=hr[--pr],hr[pr]=null}var nr=null,rr=null,It=!1,kr=null;function eh(e,n){var s=xr(5,null,null,0);s.elementType="DELETED",s.stateNode=n,s.return=e,n=e.deletions,n===null?(e.deletions=[s],e.flags|=16):n.push(s)}function th(e,n){switch(e.tag){case 5:var s=e.type;return n=n.nodeType!==1||s.toLowerCase()!==n.nodeName.toLowerCase()?null:n,n!==null?(e.stateNode=n,nr=e,rr=Ur(n.firstChild),!0):!1;case 6:return n=e.pendingProps===""||n.nodeType!==3?null:n,n!==null?(e.stateNode=n,nr=e,rr=null,!0):!1;case 13:return n=n.nodeType!==8?null:n,n!==null?(s=Bo!==null?{id:mi,overflow:gi}:null,e.memoizedState={dehydrated:n,treeContext:s,retryLane:1073741824},s=xr(18,null,null,0),s.stateNode=n,s.return=e,e.child=s,nr=e,rr=null,!0):!1;default:return!1}}function Td(e){return(e.mode&1)!==0&&(e.flags&128)===0}function Dd(e){if(It){var n=rr;if(n){var s=n;if(!th(e,n)){if(Td(e))throw Error(o(418));n=Ur(s.nextSibling);var c=nr;n&&th(e,n)?eh(c,s):(e.flags=e.flags&-4097|2,It=!1,nr=e)}}else{if(Td(e))throw Error(o(418));e.flags=e.flags&-4097|2,It=!1,nr=e}}}function nh(e){for(e=e.r Line truncated
Error generating stack: `+_.message+`
`+_.stack}return{value:e,source:n,stack:x,digest:null}}function Jd(e,n,s){return{value:e,source:null,stack:s??null,digest:n??null}}function ef(e,n){try{console.error(n.value)}catch(s){setTimeout(function(){throw s})}}var ov=typeof WeakMap=="function"?WeakMap:Map;function Mh(e,n,s){s=xi(-1,s),s.tag=3,s.payload={element:null};var c=n.value;return s.callback=function(){mu||(mu=!0,gf=c),ef(e,n)},s}function Ih(e,n,s){s=xi(-1,s),s.tag=3;var c=e.type.getDerivedStateFromError;if(typeof c=="function"){var x=n.value;s.payload=function(){return c(x)},s.callback=function(){ef(e,n)}}var _=e.stateNode;return _!==null&&typeof _.componentDidCatch=="function"&&(s.callback=function(){ef(e,n),typeof c!="function"&&(to===null?to=new Set([this]):to.add(this));var M=n.stack;this.componentDidCatch(n.value,{componentStack:M!==null?M:""})}),s}function Oh(e,n,s){var c=e.pingCache;if(c===null){c=e.pingCache=new ov;var x=new Set;c.set(n,x)}else x=c.get(n),x===void 0&&(x=new Set,c.set(n,x));x.has(s)||(x.add(s),e=vv.bind(null,e,n,s),n.then(e,e))}function jh(e){do{var n;if((n=e.tag===13)&&(n=e.memoizedState,n=n!==null?n.dehydrated!==null:!0),n)return e;e=e.return}while(e!==null);return null}function zh(e,n,s,c,x){return(e.mode&1)===0?(e===n?e.flags|=65536:(e.flags|=128,s.flags|=131072,s.flags&=-52805,s.tag===1&&(s.alternate===null?s.tag=17:(n=xi(-1,1),n.tag=2,Ji(s,n,1))),s.lanes|=1),e):(e.flags|=65536,e.lanes=x,e)}var sv=N.ReactCurrentOwner,Hn=!1;function Nn(e,n,s,c){n.child=e===null?sh(n,null,s,c):Bs(n,e.child,s,c)}function Hh(e,n,s,c,x){s=s.render;var _=n.ref;return Ts(n,x),c=Wd(e,n,s,c,_,x),s=qd(),e!==null&&!Hn?(n.updateQueue=e.updateQueue,n.flags&=-2053,e.lanes&=~x,vi(e,n,x)):(It&&s&&Bd(n),n.flags|=1,Nn(e,n,c,x),n.child)}function Vh(e,n,s,c,x){if(e===null){var _=s.type;return typeof _=="function"&&!bf(_)&&_.defaultProps===void 0&&s.compare===null&&s.defaultProps===void 0?(n.tag=15,n.type=_,Uh(e,n,_,c,x)):(e=_u(s.type,null,c,n,n.mode,x),e.ref=n.ref,e.return=n,n.child=e)}if(_=e.child,(e.lanes&x)===0){var M=_.memoizedProps;if(s=s.compare,s=s!==null?s:zr,s(M,c)&&e.ref===n.ref)return vi(e,n,x)}return n.flags|=1,e=oo(_,c),e.ref=n.ref,e.return=n,n.child=e}function Uh(e,n,s,c,x){if(e!==null){var _=e.memoizedProps;if(zr(_,c)&&e.ref===n.ref)if(Hn=!1,n.pendingProps=c=_,(e.lanes&x)!==0)(e.flags&131072)!==0&&(Hn=!0);else return n.lanes=e.lanes,vi(e,n,x)}return tf(e,n,s,c,x)}function Zh(e,n,s){var c=n.pendingProps,x=c.children,_=e!==null?e.memoizedState:null;if(c.mode==="hidden")if((n.mode&1)===0)n.memoizedState={baseLanes:0,cachePool:null,transitions:null},Dt(Ns,ir),ir|=s;else{if((s&1073741824)===0)return e=_!==null?_.baseLanes|s:s,n.lanes=n.childLanes=1073741824,n.memoizedState={baseLanes:e,cachePool:null,transitions:null},n.updateQueue=null,Dt(Ns,ir),ir|=e,null;n.memoizedState={baseLanes:0,cachePool:null,transitions:null},c=_!==null?_.baseLanes:s,Dt(Ns,ir),ir|=c}else _!==null?(c=_.baseLanes|s,n.memoizedState=null):c=s,Dt(Ns,ir),ir|=c;return Nn(e,n,x,s),n.child}function Wh(e,n){var s=n.ref;(e===null&&s!==null||e!==null&&e.ref!==s)&&(n.flags|=512,n.flags|=2097152)}function tf(e,n,s,c,x){var _=zn(s)?So:Cn.current;return _=Cs(n,_),Ts(n,x),s=Wd(e,n,s,c,_,x),c=qd(),e!==null&&!Hn?(n.updateQueue=e.updateQueue,n.flags&=-2053,e.lanes&=~x,vi(e,n,x)):(It&&c&&Bd(n),n.flags|=1,Nn(e,n,s,x),n.child)}function qh(e,n,s,c,x){if(zn(s)){var _=!0;ql(n)}else _=!1;if(Ts(n,x),n.stateNode===null)cu(e,n),Nh(n,s,c),Xd(n,s,c,x),c=!0;else if(e===null){var M=n.stateNode,W=n.memoizedProps;M.props=W;var X=M.context,ce=s.contextType;typeof ce=="object"&&ce!==null?ce=mr(ce):(ce=zn(s)?So:Cn.current,ce=Cs(n,ce));var _e=s.getDerivedStateFromProps,we=typeof _e=="function"||typeof M.getSnapshotBeforeUpdate=="function";we||typeof M.UNSAFE_componentWillReceiveProps!="function"&&typeof M.componentWillReceiveProps!="function"||(W!==c||X!==ce)&&Lh(n,M,c,ce),Xi=!1;var ye=n.memoizedState;M.state=ye,tu(n,c,M,x),X=n.memoizedState,W!==c||ye!==X||jn.current||Xi?(typeof _e=="function"&&(Yd(n,s,_e,c),X=n.memoizedState),(W=Xi||Fh(n,s,W,c,ye,X,ce))?(we||typeof M.UNSAFE_componentWillMount!="function"&&typeof M.componentWillMount!="function"||(typeof M.componentWillMount=="function"&&M.componentWillMount(),typeof M.UNSAFE_componentWillMount=="function"&&M.UNSAFE_componentWillMount()),typeof M.componentDidMount=="function"&&(n.flags|=4194308)):(typeof M.componentDidMount=="function"&&(n.flags|=4194308),n.memoizedProps=c,n.memoizedState=X),M.props=c,M.state=X,M.context=ce,c=W):(typeof M.componentDidMount=="function"&&(n.flags|=4194308),c=!1)}else{M=n.stateNode,lh(e,n),W=n.memoizedProps,ce=n.type===n.elementType?W:Sr(n.type,W),M.props=ce,we=n.pendingProps,ye=M.context,X=s.contextType,typeof X=="object"&&X!==null?X=mr(X):(X=zn(s)?So:Cn.current,X=Cs(n,X));var Fe=s.getDerivedStateFromProps;(_e=typeof Fe=="function"||typeof M.getSnapshotBeforeUpdate=="function")||typeof M.UNSAFE_componentWillReceiveProps!="function"&&typeof M.componentWillReceiveProps!="function"||(W!==we||ye!==X)&&Lh(n,M,c,X),Xi=!1,ye=n.m Line truncated
`)}function Is(r,a,o){const l=Math.floor(Date.now()/1e3);return{id:-Date.now(),type:"PRIV",conversation_key:r,text:a,sender_timestamp:l,received_at:l,path:null,txt_type:0,signature:null,outgoing:o,acked:1}}function Gv(r){const a=F.useRef(null),o=F.useRef(null),l=F.useCallback(()=>{o.current!==null&&(clearInterval(o.current),o.current=null),a.current=null},[]),d=F.useCallback(async()=>{const p=a.current;if(!p)return;let h=null,g=null;for(let m=0;m<2;m++)try{h=await ot.requestTelemetry(p.conversationId,"");break}catch(v){g=v instanceof Error?v:new Error("Unknown error"),m===0&&await new Promise(y=>setTimeout(y,2e3))}if(h){const m=Is(p.conversationId,qv(p,h),!1);r(v=>[...v,m])}else{const m=Is(p.conversationId,`Duty cycle poll failed after retry: ${(g==null?void 0:g.message)??"Unknown error"}`,!1);r(v=>[...v,m])}},[r]),f=F.useCallback(async(p,h)=>{const g=p.trim().toLowerCase();if(g==="dutycycle_start"){l();let m=null,v=null;for(let B=0;B<2;B++)try{m=await ot.requestTelemetry(h,"");break}catch(T){v=T instanceof Error?T:new Error("Unknown error"),B===0&&await new Promise(b=>setTimeout(b,2e3))}if(!m){const B=Is(h,`Failed to start duty cycle tracking after retry: ${(v==null?void 0:v.message)??"Unknown error"}`,!1);return r(T=>[...T,B]),!0}const y=Math.floor(Date.now()/1e3);a.current={startTime:y,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:h};const w=Is(h,`Airtime/duty cycle statistics gathering begins at ${y}. Logs will follow every 5 minutes. To stop, run dutycycle_stop or navigate away from this conversation.`,!1);return r(B=>[...B,w]),o.current=window.setInterval(d,Zv),!0}if(g==="dutycycle_stop"){if(a.current&&a.current.conversationId===h){await d(),l();const m=Is(h,"Airtime/duty cycle statistics gathering stopped.",!1);r(v=>[...v,m])}else{const m=Is(h,"Duty cycle tracking is not active.",!1);r(v=>[...v,m])}return!0}return!1},[r,l,d]);return F.useEffect(()=>()=>{o.current!==null&&clearInterval(o.current)},[]),{handleAirtimeCommand:f,stopTracking:l}}function Vu(r){if(r<60)return`${r}s`;const a=Math.floor(r/86400),o=Math.floor(r%86400/3600),l=Math.floor(r%3600/60);return a>0?o>0&&l>0?`${a}d${o}h${l}m`:o>0?`${a}d${o}h`:l>0?`${a}d${l}m`:`${a}d`:o>0?l>0?`${o}h${l}m`:`${o}h`:`${l}m`}function Kv(r){return["Telemetry",`Battery Voltage: ${r.battery_volts.toFixed(3)}V`,`Uptime: ${Vu(r.uptime_seconds)}`,`TX Airtime: ${Vu(r.airtime_seconds)}`,`RX Airtime: ${Vu(r.rx_airtime_seconds)}`,"",`Noise Floor: ${r.noise_floor_dbm} dBm`,`Last RSSI: ${r.last_rssi_dbm} dBm`,`Last SNR: ${r.last_snr_db.toFixed(1)} dB`,"",`Packets: ${r.packets_received.toLocaleString()} rx / ${r.packets_sent.toLocaleString()} tx`,`Flood: ${r.recv_flood.toLocaleString()} rx / ${r.sent_flood.toLocaleString()} tx`,`Direct: ${r.recv_direct.toLocaleString()} rx / ${r.sent_direct.toLocaleString()} tx`,`Duplicates: ${r.flood_dups.toLocaleString()} flood / ${r.direct_dups.toLocaleString()} direct`,"",`TX Queue: ${r.tx_queue_len}`,`Debug Flags: ${r.full_events}`].join(`
`)}function Qv(r){if(r.length===0)return`Neighbors
No neighbors reported`;const a=[...r].sort((l,d)=>d.snr-l.snr),o=[`Neighbors (${a.length})`];for(const l of a){const d=l.name||l.pubkey_prefix,f=l.snr>=0?`+${l.snr.toFixed(1)}`:l.snr.toFixed(1);o.push(`${d}, ${f} dB [${Vu(l.last_heard_seconds)} ago]`)}return o.join(`
`)}function $v(r){if(r.length===0)return`ACL
No ACL entries`;const a=[`ACL (${r.length})`];for(const o of r){const l=o.name||o.pubkey_prefix;a.push(`${l}: ${o.permission_name}`)}return a.join(`
`)}function jo(r,a,o,l=0){const d=Math.floor(Date.now()/1e3);return{id:-Date.now()-l,type:"PRIV",conversation_key:r,text:a,sender_timestamp:d,received_at:d,path:null,txt_type:0,signature:null,outgoing:o,acked:1}}function Yv(r,a,o){const[l,d]=F.useState(!1),{handleAirtimeCommand:f,stopTracking:p}=Gv(o);F.useEffect(()=>{d(!1),p()},[r==null?void 0:r.id,p]);const h=F.useMemo(()=>{if(!r||r.type!=="contact")return!1;const v=a.find(y=>y.public_key===r.id);return(v==null?void 0:v.type)===jc},[r,a]),g=F.useCallback(async v=>{if(!(!r||r.type!=="contact")&&h)try{const y=await ot.requestTelemetry(r.id,v),w=jo(r.id,Kv(y),!1,0),B=jo(r.id,Qv(y.neighbors),!1,1),T=jo(r.id,$v(y.acl),!1,2);o(b=>[...b,w,B,T]),d(!0)}catch(y){const w=jo(r.id,`Telemetry request failed: ${y instanceof Error?y.message:"Unknown error"}`,!1,0);o(B=>[...B,w])}},[r,h,o]),m=F.useCallback(async v=>{if(!r||r.type!=="contact"||!h||!l||await f(v,r.id))return;const w=jo(r.id,`> ${v}`,!0,0);o(B=>[...B,w]);try{const B=await ot.sendRepeaterCommand(r.id,v),T=jo(r.id,B.response,!1,1);B.sender_timestamp&&(T.sender_timestamp=B.sender_timestamp),o(b=>[...b,T])}catch(B){const T=jo(r.id,`Command failed: ${B instanceof Error?B.message:"Unknown error"}`,!1,1);o(b=>[...b,T])}},[r,h,l,o,f]);return{repeaterLoggedIn:l,activeContactIsRepeater:h,handleTelemetryRequest:g,handleRepeaterCommand:m}}const Xv=12;function Gs(r){return r.slice(0,Xv)}function v0(r,a){return!r||!a?!1:Gs(r)===Gs(a)}function Ei(r,a){return r||Gs(a)}const Jf="remoteterm-lastMessageTime";function Og(r){try{const a=localStorage.getItem(r);return a?JSON.parse(a):{}}catch{return{}}}function Jv(r,a){try{localStorage.setItem(r,JSON.stringify(a))}catch{}}function Ip(){return Og(Jf)}function Mf(r,a){const o=Og(Jf);return(!o[r]||a>o[r])&&(o[r]=a,Jv(Jf,o)),o}function Rr(r,a){return r==="channel"?`channel-${a}`:`contact-${Gs(a)}`}function Op(r,a){if(!a)return!1;const o=a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`@\\[${o}\\]`,"i").test(r)}function ey(r,a,o,l=null){const[d,f]=F.useState({}),[p,h]=F.useState({}),[g,m]=F.useState(Ip),v=F.useRef(l);F.useEffect(()=>{v.current=l},[l]);const y=F.useRef(new Set),w=F.useRef(new Set);F.useEffect(()=>{const D=r.filter(N=>!y.current.has(N.key)),P=a.filter(N=>N.public_key&&!w.current.has(N.public_key));if(D.length===0&&P.length===0)return;D.forEach(N=>y.current.add(N.key)),P.forEach(N=>w.current.add(N.public_key)),(async()=>{const N=[...D.map(I=>({type:"CHAN",conversation_key:I.key})),...P.map(I=>({type:"PRIV",conversation_key:I.public_key}))];if(N.length!==0)try{const I=await ot.getMessagesBulk(N,x0),z={},H={},j={};for(const ee of D){const Z=I[`CHAN:${ee.key}`]||[];if(Z.length>0){const V=Rr("channel",ee.key),ne=ee.last_read_at||0,J=Z.filter(he=>!he.outgoing&&he.received_at>ne);J.length>0&&(z[V]=J.length,J.some(he=>Op(he.text,v.current))&&(H[V]=!0));const ie=Math.max(...Z.map(he=>he.received_at));j[V]=ie,Mf(V,ie)}}for(const ee of P){const Z=I[`PRIV:${ee.public_key}`]||[];if(Z.length>0){const V=Rr("contact",ee.public_key),ne=ee.last_read_at||0,J=Z.filter(he=>!he.outgoing&&he.received_at>ne);J.length>0&&(z[V]=J.length,J.some(he=>Op(he.text,v.current))&&(H[V]=!0));const ie=Math.max(...Z.map(he=>he.received_at));j[V]=ie,Mf(V,ie)}}Object.keys(z).length>0&&f(ee=>({...ee,...z})),Object.keys(H).length>0&&h(ee=>({...ee,...H})),m(Ip())}catch(I){console.error("Failed to fetch messages bulk:",I)}})()},[r,a]),F.useEffect(()=>{if(o&&o.type!=="raw"&&o.type!=="map"){const D=Rr(o.type,o.id);f(P=>{if(P[D]){const S={...P};return delete S[D],S}return P}),h(P=>{if(P[D]){const S={...P};return delete S[D],S}return P}),o.type==="channel"?ot.markChannelRead(o.id).catch(P=>{console.error("Failed to mark channel as read on server:",P)}):o.type==="contact"&&ot.markContactRead(o.id).catch(P=>{console.error("Failed to mark contact as read on server:",P)})}},[o]);const B=F.useCallback((D,P)=>{f(S=>({...S,[D]:(S[D]||0)+1})),P&&h(S=>({...S,[D]:!0}))},[]),T=F.useCallback(()=>{f({}),h({}),ot.markAllRead().catch(D=>{console.error("Failed to mark all as read on server:",D)})},[]),b=F.useCallback(D=>{if(D.type==="raw"||D.type==="map")return;const P=Rr(D.type,D.id);f(S=>{if(S[P]){const N={...S};return delete N[P],N}return S}),h(S=>{if(S[P]){const N={...S};return delete N[P],N}return S}),D.type==="channel"?ot.markChannelRead(D.id).catch(S=>{console.error("Failed to mark channel as read on server:",S)}):D.type==="contact"&&ot.markContactRead(D.id).catch(S=>{console.error("Failed to mark contact as read on server:",S)})},[]),k=F.useCallback(D=>{let P=null;if(D.type==="CHAN"&&D.conversation_key?P=Rr("channel",D.conversation_key):D.type==="PRIV"&&D.conversation_key&&(P=Rr("contact",D.conversation_key)),P){const S=D.received_at||Math.floor(Date.now()/1e3),N=Mf(P,S);m(N)}},[]);return{unreadCounts:d,mentions:p,lastMessageTimes:g,incrementUnread:B,markAllRead:T,markConversationRead:b,trackNewMessage:k}}var y0=Ig();const jg=Ys(y0);function ty(r){if(typeof document>"u")return;let a=document.head||document.getElem 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 Ty=r=>r.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),Dy=r=>r.replace(/^([A-Z])|[\s-_]+(\w)/g,(a,o,l)=>l?l.toUpperCase():o.toLowerCase()),Hp=r=>{const a=Dy(r);return a.charAt(0).toUpperCase()+a.slice(1)},zg=(...r)=>r.filter((a,o,l)=>!!a&&a.trim()!==""&&l.indexOf(a)===o).join(" ").trim(),Ry=r=>{for(const a in r)if(a.startsWith("aria-")||a==="role"||a==="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 Fy={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 Ny=F.forwardRef(({color:r="currentColor",size:a=24,strokeWidth:o=2,absoluteStrokeWidth:l,className:d="",children:f,iconNode:p,...h},g)=>F.createElement("svg",{ref:g,...Fy,width:a,height:a,stroke:r,strokeWidth:l?Number(o)*24/Number(a):o,className:zg("lucide",d),...!f&&!Ry(h)&&{"aria-hidden":"true"},...h},[...p.map(([m,v])=>F.createElement(m,v)),...Array.isArray(f)?f:[f]]));/**
* @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 _0=(r,a)=>{const o=F.forwardRef(({className:l,...d},f)=>F.createElement(Ny,{ref:f,iconNode:a,className:zg(`lucide-${Ty(Hp(r))}`,`lucide-${r}`,l),...d}));return o.displayName=Hp(r),o};/**
* @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 Ly=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],My=_0("check",Ly);/**
* @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 Iy=[["path",{d:"M4 5h16",key:"1tepv9"}],["path",{d:"M4 12h16",key:"1lakjw"}],["path",{d:"M4 19h16",key:"1djgab"}]],Oy=_0("menu",Iy);/**
* @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 jy=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],Hg=_0("x",jy);function zy({health:r,config:a,onSettingsClick:o,onMenuClick:l}){const d=(r==null?void 0:r.radio_connected)??!1,[f,p]=F.useState(!1),h=async()=>{p(!0);try{const g=await ot.reconnectRadio();g.connected&&bt.success("Reconnected",{description:g.message})}catch(g){bt.error("Reconnection failed",{description:g instanceof Error?g.message:"Check radio connection and power"})}finally{p(!1)}};return E.jsxs("div",{className:"flex items-center gap-4 px-4 py-2 bg-[#252525] border-b border-[#333] text-xs",children:[l&&E.jsx("button",{onClick:l,className:"md:hidden p-1 bg-transparent border-none text-[#e0e0e0] cursor-pointer","aria-label":"Open menu",children:E.jsx(Oy,{className:"h-5 w-5"})}),E.jsx("h1",{className:"hidden lg:block text-base font-semibold mr-auto",children:"RemoteTerm"}),E.jsxs("div",{className:"flex items-center gap-1 text-[#888]",children:[E.jsx("div",{className:`w-2 h-2 rounded-full ${d?"bg-[#4caf50]":"bg-[#666]"}`}),E.jsx("span",{className:"hidden lg:inline text-[#e0e0e0]",children:d?"Connected":"Disconnected"})]}),a&&E.jsx("div",{className:"hidden lg:flex items-center gap-1 text-[#888]",children:E.jsx("span",{className:"text-[#e0e0e0]",children:a.name||"Unnamed"})}),E.jsx("div",{className:"flex-1 lg:hidden"}),!d&&E.jsx("button",{onClick:h,disabled:f,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:f?"Reconnecting...":"Reconnect"}),E.jsxs("button",{onClick:o,className:"px-3 py-1 bg-[#333] border border-[#444] text-[#e0e0e0] rounded text-xs cursor-pointer hover:bg-[#444]",children:[E.jsx("span",{role:"img","aria-label":"Settings",children:"🔧"})," ","Radio & Config"]})]})}const t0=2,Hy={text:"🛜",background:"#444444",textColor:"#ffffff"};function Vy(r){let a=0;for(let o=0;o<r.length;o++){const l=r.charCodeAt(o);a=(a<<5)-a+l,a=a&a}return Math.abs(a)}const Uy=/[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]|[\u{1F600}-\u{1F64F}]|[\u{1F680}-\u{1F6FF}]|[\u{1F1E0}-\u{1F1FF}]/u;function Zy(r,a){if(!r)return a.slice(0,2).toUpperCase();const o=r.match(Uy);if(o)return o[0];const l=r.match(/[a-zA-Z]/g);if(!l||l.length===0)return a.slice(0,2).toUpperCase();const d=r.indexOf(" ");if(d!==-1){const f=l[0],p=r.slice(d+1).match(/[a-zA-Z]/);if(p)return(f+p[0]).toUpperCase()}return l[0].toUpperCase()}function Wy(r){const a=Vy(r),o=a%360,l=50+(a>>8)%30,d=35+(a>>16)%20,f=`hsl(${o}, ${l}%, ${d}%)`,p=d<45?"#ffffff":"#000000";return{background:f,text:p}}function qy(r,a,o){if(o===t0)return Hy;const l=Zy(r,a),d=Wy(a);return{text:l,background:d.background,textColor:d.text}}function n0({name:r,publicKey:a,size:o=28,contactType:l}){const d=qy(r,a,l);return E.jsx("div",{className:"flex items-center justify-center rounded-full font-semibold flex-shrink-0 select-none",style:{backgroundColor:d.background,color:d.textColor,width:o,height:o,fontSize:o*.45},children:d.text})}const Vg="remoteterm-favorites";function zc(){try{const r=localStorage.getItem(Vg);return r?JSON.parse(r):[]}catch{return[]}}function Ug(r){try{localStorage.setItem(Vg,JSON.stringify(r))}catch{}}function Gy(r,a){const o=zc();if(o.some(d=>d.type===r&&d.id===a))return o;const l=[...o,{type:r,id:a}];return Ug(l),l}function Ky(r,a){const l=zc().filter(d=>!(d.type===r&&d.id===a));return Ug(l),l}function Us(r,a,o){return r.some(l=>l.type===a&&l.id===o)}function Qy(r,a){return zc().some(l=>l.type===r&&l.id===a)?Ky(r,a):Gy(r,a)}function Zg(r){var a,o,l="";if(typeof r=="string"||typeof r=="number")l+=r;else if(typeof r=="object")if(Array.isArray(r)){var d=r.length;for(a=0;a<d;a++)r[a]&&(o=Zg(r[a]))&&(l&&(l+=" "),l+=o)}else for(o in r)r[o]&&(l&&(l+=" "),l+=o);return l}function Wg(){for(var r,a,o=0,l="",d=arguments.length;o<d;o++)(r=arguments[o])&&(a=Zg(r))&&(l&&(l+=" "),l+=a);return l}const $y=(r,a)=>{const o=new Array(r.length+a.length);for(let l=0;l<r.length;l++)o[l]=r[l];for(let l=0;l<a.length;l++)o[r.length+l]=a[l];return o},Yy=(r,a)=>({classGroupId:r,validator:a}),qg=(r=new Map,a=null,o)=>({nextPart:r,validators:a,classGroupId:o}),Rc="-",Vp=[],Xy="arbitrary..",Jy=r=>{const a=t_(r),{conflictingClassGroups:o,conflictingClassGroupModifiers:l}=r;return{getClassGroupId:p=>{if(p.startsWith("[")&&p.endsWith("]"))return e_(p);const h=p.split(Rc),g=h[0]===""&&h.length>1?1:0;return Gg(h,g,a)},getConflictingClassGroupIds:(p,h)=>{if(h){const g=l[p],m=o[p];return g?m?$y(m,g):g:m||Vp}return o[p]||Vp}}},Gg=(r,a,o)=>{if(r.length-a===0)return o.classGroupId;const d=r[a],f=o.nextPart.get(d);if(f){const m=Gg(r,a+1,f);if(m)return m}const p=o.validators;if(p===null)return;const h=a===0?r.join(Rc):r.slice(a).join(Rc),g=p.length;for(let m=0;m<g;m++){const v=p[m];if(v.validator(h))return v.classGroupId}},e_=r=>r.slice(1,-1).indexOf(":")===-1?void 0:(()=>{const a=r.slice(1,-1),o=a.indexOf(":"),l=a.slice(0,o);return l?Xy+l:void 0})(),t_=r=>{conLine truncated
.`.concat(I1,` {
overflow: hidden `).concat(l,`;
padding-right: `).concat(h,"px ").concat(l,`;
}
body[`).concat(Ws,`] {
overflow: hidden `).concat(l,`;
overscroll-behavior: contain;
`).concat([a&&"position: relative ".concat(l,";"),o==="margin"&&`
padding-left: `.concat(d,`px;
padding-top: `).concat(f,`px;
padding-right: `).concat(p,`px;
margin-left:0;
margin-top:0;
margin-right: `).concat(h,"px ").concat(l,`;
`),o==="padding"&&"padding-right: ".concat(h,"px ").concat(l,";")].filter(Boolean).join(""),`
}
.`).concat(Zu,` {
right: `).concat(h,"px ").concat(l,`;
}
.`).concat(Wu,` {
margin-right: `).concat(h,"px ").concat(l,`;
}
.`).concat(Zu," .").concat(Zu,` {
right: 0 `).concat(l,`;
}
.`).concat(Wu," .").concat(Wu,` {
margin-right: 0 `).concat(l,`;
}
body[`).concat(Ws,`] {
`).concat(O1,": ").concat(h,`px;
}
`)},om=function(){var r=parseInt(document.body.getAttribute(Ws)||"0",10);return isFinite(r)?r:0},rw=function(){F.useEffect(function(){return document.body.setAttribute(Ws,(om()+1).toString()),function(){var r=om()-1;r<=0?document.body.removeAttribute(Ws):document.body.setAttribute(Ws,r.toString())}},[])},iw=function(r){var a=r.noRelative,o=r.noImportant,l=r.gapMode,d=l===void 0?"margin":l;rw();var f=F.useMemo(function(){return ew(d)},[d]);return F.createElement(tw,{styles:nw(f,!a,d,o?"":"!important")})},o0=!1;if(typeof window<"u")try{var Ou=Object.defineProperty({},"passive",{get:function(){return o0=!0,!0}});window.addEventListener("test",Ou,Ou),window.removeEventListener("test",Ou,Ou)}catch{o0=!1}var js=o0?{passive:!1}:!1,ow=function(r){return r.tagName==="TEXTAREA"},mA=function(r,a){if(!(r instanceof Element))return!1;var o=window.getComputedStyle(r);return o[a]!=="hidden"&&!(o.overflowY===o.overflowX&&!ow(r)&&o[a]==="visible")},sw=function(r){return mA(r,"overflowY")},aw=function(r){return mA(r,"overflowX")},sm=function(r,a){var o=a.ownerDocument,l=a;do{typeof ShadowRoot<"u"&&l instanceof ShadowRoot&&(l=l.host);var d=gA(r,l);if(d){var f=AA(r,l),p=f[1],h=f[2];if(p>h)return!0}l=l.parentNode}while(l&&l!==o.body);return!1},lw=function(r){var a=r.scrollTop,o=r.scrollHeight,l=r.clientHeight;return[a,o,l]},uw=function(r){var a=r.scrollLeft,o=r.scrollWidth,l=r.clientWidth;return[a,o,l]},gA=function(r,a){return r==="v"?sw(a):aw(a)},AA=function(r,a){return r==="v"?lw(a):uw(a)},cw=function(r,a){return r==="h"&&a==="rtl"?-1:1},dw=function(r,a,o,l,d){var f=cw(r,window.getComputedStyle(a).direction),p=f*l,h=o.target,g=a.contains(h),m=!1,v=p>0,y=0,w=0;do{if(!h)break;var B=AA(r,h),T=B[0],b=B[1],k=B[2],D=b-k-f*T;(T||D)&&gA(r,h)&&(y+=D,w+=T);var P=h.parentNode;h=P&&P.nodeType===Node.DOCUMENT_FRAGMENT_NODE?P.host:P}while(!g&&h!==document.body||g&&(a.contains(h)||a===h));return(v&&Math.abs(y)<1||!v&&Math.abs(w)<1)&&(m=!0),m},ju=function(r){return"changedTouches"in r?[r.changedTouches[0].clientX,r.changedTouches[0].clientY]:[0,0]},am=function(r){return[r.deltaX,r.deltaY]},lm=function(r){return r&&"current"in r?r.current:r},fw=function(r,a){return r[0]===a[0]&&r[1]===a[1]},hw=function(r){return`
.block-interactivity-`.concat(r,` {pointer-events: none;}
.allow-interactivity-`).concat(r,` {pointer-events: all;}
`)},pw=0,zs=[];function mw(r){var a=F.useRef([]),o=F.useRef([0,0]),l=F.useRef(),d=F.useState(pw++)[0],f=F.useState(pA)[0],p=F.useRef(r);F.useEffect(function(){p.current=r},[r]),F.useEffect(function(){if(r.inert){document.body.classList.add("block-interactivity-".concat(d));var b=M1([r.lockRef.current],(r.shards||[]).map(lm),!0).filter(Boolean);return b.forEach(function(k){return k.classList.add("allow-interactivity-".concat(d))}),function(){document.body.classList.remove("block-interactivity-".concat(d)),b.forEach(function(k){return k.classList.remove("allow-interactivity-".concat(d))})}}},[r.inert,r.lockRef.current,r.shards]);var h=F.useCallback(function(b,k){if("touches"in b&&b.touches.length===2||b.type==="wheel"&&b.ctrlKey)return!p.current.allowPinchZoom;var D=ju(b),P=o.current,S="deltaX"in b?b.deltaX:P[0]-D[0],N="deltaY"in b?b.deltaY:P[1]-D[1],I,z=b.target,H=Math.abs(S)>Math.abs(N)?"h":"v";if("touches"in b&&H==="h"&&z.type==="range")return!1;var j=window.getSelection(),ee=j&&j.anchorNode,Z=ee?ee===z||ee.contains(z):!1;if(Z)return!1;var V=sm(H,z);if(!V)return!0;if(V?I=H:(I=H==="v"?"h":"v",V=sm(H,z)),!V)return!1;if(!l.current&&"changedTouches"in b&&(S||N)&&(l.current=I),!I)return!0;var ne=l.current||I;return dw(ne,k,b,ne==="h"?S:N)},[]),g=F.useCallback(function(b){var k=b;if(!(!zs.length||zs[zs.length-1]!==f)){var D="deltaY"in k?am(k):ju(k),P=a.current.filter(function(I){return I.name===k.type&&(I.target===k.target||k.target===I.shadowParent)&&fw(I.delta,D)})[0];if(P&&P.should){k.cancelable&&k.preventDefault();return}if(!P){var S=(p.current.shards||[]).map(lm).filter(Boolean).filter(function(I){return I.contains(k.target)}),N=S.length>0?h(k,S[0]):!p.current.noIsolation;N&&k.cancelable&&k.preventDefault()}}},[]),m=F.useCallback(function(b,k,D,P){var S={name:b,delta:k,target:D,should:P,shadowParent:gw(D)};a.current.push(S),setTimeout(function(){a.current=a.current.filter(function(N){return N!==S})},1)},[]),v=F.useCallback(function(b){o.current=ju(b),l.current=void 0},[]),y=F.useCallback(function(b){m(b.type,am(b),b.target,h(b,r.lockRef.current))},[]),w=F.useCallback(function(b){m(b.type,ju(b),b.target,h(b,r.lockRef.current))},[]);F.useEffect(function(){return zs.push(f),r.setCallbacks({onScrollCapture:y,onWheelCapture:y,onTouchMoveCapture:w}),document.addEventListener("wheel",g,js),document.addEventListener("touchmove",g,js),document.addEventListener("touchstart",v,js),function(){zs=zs.filter(function(b){return b!==f}),document.removeEventListener("wheel",g,js),document.removeEventListener("touchmove",g,js),document.removeEventListener("touchstart",v,js)}},[]);var B=r.removeScrollBar,T=r.inert;return F.createElement(F.Fragment,null,T?F.createElement(f,{styles:hw(d)}):null,B?F.createElement(iw,{noRelative:r.noRelative,gapMode:r.gapMode}):null)}function gw(r){for(var a=null;r!==null;)r instanceof ShadowRoot&&(a=r.host,r=r.host),r=r.parentNode;return a}const Aw=W1(hA,mw);var xA=F.forwardRef(function(r,a){return F.createElement(Vc,$r({},r,{ref:a,sideCar:Aw}))});xA.classNames=Vc.classNames;var xw=function(r){if(typeof document>"u")return null;var a=Array.isArray(r)?r[0]:r;return a.ownerDocument.body},Hs=new WeakMap,zu=new WeakMap,Hu={},Wf=0,vA=function(r){return r&&(r.host||vA(r.parentNode))},vw=function(r,a){return a.map(function(o){if(r.contains(o))return o;var l=vA(o);return l&&r.contains(l)?l:(console.error("aria-hidden",o,"in not contained inside",r,". Doing nothing"),null)}).filter(function(o){return!!o})},yw=function(r,a,o,l){var d=vw(a,Array.isArray(r)?r:[r]);Hu[o]||(Hu[o]=new WeakMap);var f=Hu[o],p=[],h=new Set,g=new Set(d),m=function(y){!y||h.has(y)||(h.add(y),m(y.parentNode))};d.forEach(m);var v=function(y){!y||g.has(y)||Array.prototype.forEach.call(y.children,function(w){if(h.has(w))v(w);else try{var B=w.getAttribute(l),T=B!==null&&B!=="false",b=(Hs.get(w)||0)+1,k=(f.get(w)||0)+1;Hs.set(w,b),f.set(w,k),p.push(w),b===1&&T&&zu.set(w,!0),k===1&&w.setAttribute(o,"true"),T||w.setAttribute(l,"true")}catch(D){console.error("aria-hidden: cannot operate on ",w,D)}})};return v(a),h.clear(),Wf++,function(){p.forEach(function(y){var w=Hs.get(y)-1,B=f.get(y)-1;Hs.set(y,w),f.set(y,B),w||(zu.has(y)||y.removeAttribute(l),zu.delete(y)),B||y.removeAttribute(o)}),Wf--,Wf||(Hs=new WeakMap,Hs=new WeakMap,zu=new WeakMap,Hu={})}},_w=function(r,a,o){o===void 0&&(o="data-aria-hidden");var l=Array.from(Array.isArray(r)?r:[r]),d=xw(r);return d?(l.push.apply(l,Array.from(d.querySelectorAll("[aria-live], script"))),yw(l,d,o,"aria-hidden")):function(){return null}};function ww(r){const a=bw(r),o=F.forwardRef((l,d)=>{const{children:f,...p}=l,h=F.Children.toArray(f),g=h.find(Ew);if(g){const m=g.props.children,v=h.map(y=>y===g?F.Children.count(m)>1?F.Children.only(null):F.isValidElement(m)?m.props.children:null:y);return E.jsx(a,{...p,ref:d,children:F.isValidElement(m)?F.cloneElement(m,void 0,v):null})}return E.jsx(a,{...p,ref:d,children:f})});return o.displayName=`${r}.Slot`,o}function bw(r){const a=F.forwardRef((o,l)=>{const{chi Line truncated
If you want to hide the \`${a.titleName}\`, you can wrap it with our VisuallyHidden component.
For more information, see https://radix-ui.com/primitives/docs/components/${a.docsSlug}`;return F.useEffect(()=>{r&&(document.getElementById(r)||console.error(o))},[o,r]),null},Mw="DialogDescriptionWarning",Iw=({contentRef:r,descriptionId:a})=>{const l=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${NA(Mw).contentName}}.`;return F.useEffect(()=>{var f;const d=(f=r.current)==null?void 0:f.getAttribute("aria-describedby");a&&d&&(document.getElementById(a)||console.warn(l))},[l,r,a]),null},LA=_A,MA=CA,Zc=EA,Wc=kA,qc=BA,Gc=TA,IA=RA;const B0=LA,Ow=MA,OA=F.forwardRef(({className:r,...a},o)=>E.jsx(Zc,{ref:o,className:at("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",r),...a}));OA.displayName=Zc.displayName;const Kc=F.forwardRef(({className:r,children:a,...o},l)=>E.jsxs(Ow,{children:[E.jsx(OA,{}),E.jsxs(Wc,{ref:l,className:at("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",r),...o,children:[a,E.jsxs(IA,{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:[E.jsx(Hg,{className:"h-4 w-4"}),E.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));Kc.displayName=Wc.displayName;const Qc=({className:r,...a})=>E.jsx("div",{className:at("flex flex-col space-y-1.5 text-center sm:text-left",r),...a});Qc.displayName="DialogHeader";const P0=({className:r,...a})=>E.jsx("div",{className:at("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",r),...a});P0.displayName="DialogFooter";const $c=F.forwardRef(({className:r,...a},o)=>E.jsx(qc,{ref:o,className:at("text-lg font-semibold leading-none tracking-tight",r),...a}));$c.displayName=qc.displayName;const Yc=F.forwardRef(({className:r,...a},o)=>E.jsx(Gc,{ref:o,className:at("text-sm text-muted-foreground",r),...a}));Yc.displayName=Gc.displayName;function jw(){const r=window.location.hash.slice(1);if(!r)return null;if(r==="raw")return{type:"raw",name:"raw"};if(r==="map")return{type:"map",name:"map"};if(r.startsWith("map/focus/")){const d=r.slice(10);return d?{type:"map",name:"map",mapFocusKey:decodeURIComponent(d)}:{type:"map",name:"map"}}const a=r.indexOf("/");if(a===-1)return null;const o=r.slice(0,a),l=decodeURIComponent(r.slice(a+1));return(o==="channel"||o==="contact")&&l?{type:o,name:l}:null}function jA(r){return`#map/focus/${encodeURIComponent(r)}`}function zw(r){if(!r)return"";if(r.type==="raw")return"#raw";if(r.type==="map")return"#map";const a=r.type==="channel"&&r.name.startsWith("#")?r.name.slice(1):r.name;return`#${r.type}/${encodeURIComponent(a)}`}function Hw(r){const a=zw(r);a!==window.location.hash&&window.history.replaceState(null,"",a||window.location.pathname)}function Vw({open:r,onClose:a,path:o,senderInfo:l,contacts:d,config:f}){const p=J_(o,l,d,f);return E.jsx(B0,{open:r,onOpenChange:h=>!h&&a(),children:E.jsxs(Kc,{className:"max-w-md max-h-[80vh] flex flex-col",children:[E.jsxs(Qc,{children:[E.jsx($c,{children:"Message Path"}),E.jsxs(Yc,{children:["This shows ",E.jsx("em",{children:"one route"})," that this message traveled through the mesh network. Flood messages may arrive via multiple paths, and routers may be incorrectly identified due to prefix collisions between heard and non-heard router advertisements."]})]}),E.jsx("div",{className:"flex-1 overflow-y-auto py-2",children:E.jsx(Uw,{resolved:p,senderInfo:l})}),E.jsx(P0,{children:E.jsx(Pn,{onClick:a,children:"Close"})})]})})}function Uw({resolved:r,senderInfo:a}){const o=l=>{if(l===0)return Bt(r.sender.lat,r.sender.lon)?{lat:r.sender.lat,lon:r.sender.lon}:null;const d=r.hops[l-1];return d.matches.length>1||d.matches.length===0?null:Bt(d.matches[0].lat,d.matches[0].lon)?{lat:d.matches[0].lat,lon:d.matches[0].lon}:null};return E.jsxs("div",{className:"space-y-0",children:[E.jsx(um,{label:"Sender",name:r.sender.name,prefix:r.sender.prefix,distance:null,isFirst:!0,lat:r.sender.lat,lon:r.sender.lon,publicKey:a.publicKeyOrPrefix}),r.hops.map((l,d)=>E.jsx(Zw,{hop:l,hopNumber:d+1,prevLocation:o(d)},d)),E.jsx(um,{label:"Receiver (me)",name:r.receiver.name,prefix:r.receiver.prefix,distance:Ww(r),isLast:!0,lat:r.receiver.lat,lon:r.receiver.lon,publicKey:r.receiver.publicKey??void 0}),r.totalDistances&&r.totalDistances.length>0&&E.jsxs("div",{className:"pt-3 mt-3 border-t border-borde Line truncated
`).map(($,de,fe)=>E.jsxs("span",{children:[qw($,h),de<fe.length-1&&E.jsx("br",{})]},de)),!Y&&E.jsxs(E.Fragment,{children:[E.jsx("span",{className:"text-[10px] text-muted-foreground/50 ml-2",children:ll(j.sender_timestamp||j.received_at)}),!j.outgoing&&j.path&&E.jsxs("span",{className:"text-[10px] text-muted-foreground/50 ml-1 cursor-pointer hover:text-primary hover:underline",onClick:$=>{$.stopPropagation(),b({path:j.path,senderInfo:I(j,Z,ne)})},title:"View message path",children:["(",Mu(j.path)," hop",Mu(j.path)!==1?"s":"",")"]})]}),j.outgoing&&(j.acked>0?` ✓${j.acked>1?j.acked:""}`:" ?")]})]})]},j.id)})]}),w&&E.jsx("button",{onClick:P,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:E.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:E.jsx("polyline",{points:"6 9 12 15 18 9"})})}),T&&E.jsx(Vw,{open:!0,onClose:()=>b(null),path:T.path,senderInfo:T.senderInfo,contacts:a,config:g??null})]})}const cm=156,Kw=140,Qw=156,$w=120,Yw=8,Xw=F.forwardRef(function({onSend:a,disabled:o,placeholder:l,isRepeaterMode:d,conversationType:f,senderName:p},h){const[g,m]=F.useState(""),[v,y]=F.useState(!1),w=F.useRef(null);F.useImperativeHandle(h,()=>({appendText:I=>{var z;m(H=>H+I),(z=w.current)==null||z.focus()}}));const B=F.useMemo(()=>{if(f==="contact")return{warningAt:Kw,dangerAt:cm,hardLimit:cm};if(f==="channel"){const I=(p==null?void 0:p.length)??10,z=Math.max(1,Qw-I-2);return{warningAt:$w,dangerAt:Math.max(1,z-Yw),hardLimit:z}}return null},[f,p]),{limitState:T,warningMessage:b}=F.useMemo(()=>{if(!B)return{limitState:"normal",warningMessage:null};const I=g.length;return I>=B.hardLimit?{limitState:"error",warningMessage:"likely truncated by radio"}:I>=B.dangerAt?{limitState:"danger",warningMessage:"may impact multi-repeater hop delivery"}:I>=B.warningAt?{limitState:"warning",warningMessage:"may impact multi-repeater hop delivery"}:{limitState:"normal",warningMessage:null}},[g.length,B]),k=B?B.hardLimit-g.length:0,D=F.useCallback(async I=>{I.preventDefault();const z=g.trim();if(d){if(v||o)return;y(!0);try{await a(z),m("")}catch(H){console.error("Failed to request telemetry:",H),bt.error("Failed to request telemetry",{description:H instanceof Error?H.message:"Check radio connection"});return}finally{y(!1)}setTimeout(()=>{var H;return(H=w.current)==null?void 0:H.focus()},0)}else{if(!z||v||o)return;y(!0);try{await a(z),m("")}catch(H){console.error("Failed to send message:",H),bt.error("Failed to send message",{description:H instanceof Error?H.message:"Check radio connection"});return}finally{y(!1)}setTimeout(()=>{var H;return(H=w.current)==null?void 0:H.focus()},0)}},[g,v,o,a,d]),P=F.useCallback(I=>{I.key==="Enter"&&!I.shiftKey&&(I.preventDefault(),D(I))},[D]),S=d?!0:g.trim().length>0,N=!d&&B!==null;return E.jsxs("form",{className:"px-4 py-3 border-t border-border flex flex-col gap-1",onSubmit:D,children:[E.jsxs("div",{className:"flex gap-2",children:[E.jsx(Xt,{ref:w,type:d?"password":"text",autoComplete:d?"off":void 0,value:g,onChange:I=>m(I.target.value),onKeyDown:P,placeholder:l||(d?"Enter password for admin login...":"Type a message..."),disabled:o||v,className:"flex-1 min-w-0"}),E.jsx(Pn,{type:"submit",disabled:o||v||!S,className:"flex-shrink-0",children:v?d?"Logging in...":"Sending...":d?g.trim()?"Log in with password":"Log in as guest/use repeater ACLs":"Send"})]}),N&&E.jsxs("div",{className:"flex items-center justify-end gap-2 text-xs",children:[E.jsxs("span",{className:at("tabular-nums",T==="error"||T==="danger"?"text-red-500 font-medium":T==="warning"?"text-yellow-500":"text-muted-foreground"),children:[g.length,"/",B.hardLimit,k<0&&` (${k})`]}),b&&E.jsxs("span",{className:at(T==="error"?"text-red-500":"text-yellow-500"),children:["— ",b]})]})]})});function dm(r){const a=Jw(r),o=F.forwardRef((l,d)=>{const{children:f,...p}=l,h=F.Children.toArray(f),g=h.find(t2);if(g){const m=g.props.children,v=h.map(y=>y===g?F.Children.count(m)>1?F.Children.only(null):F.isValidElement(m)?m.props.children:null:y);return E.jsx(a,{...p,ref:d,children:F.isValidElement(m)?F.cloneElement(m,void 0,v):null})}return E.jsx(a,{...p,ref:d,children:f})});return o.displayName=`${r}.Slot`,o}function Jw(r){const a=F.forwardRef((o,l)=>{const{children:d,...f}=o;if(F.isValidElement(d)){const p=r2(d),h=n2(f,d.props);return d.type!==F.Fragment&&(h.ref=l?fl(l,p):p),F.cloneElement(d,h)}return F.Children.count(d)>1?F.Children.only(null):null});return a.displayName=`${r}.SlotClone`,a}var e2=Symbol("radix.slottable");function t2(r){return F.isValidElement(r)&&typeof r.type=="function"&&"__radixId"in r.type&&r.type.__radixId===e2}function n2(r,a){const o={...a};for(const l in a){const d=r[l],f=a[l];/^on[A-Z]/.test(l)?d&&f?o[l]=(...h 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 $2=ol.exports,pm;function Y2(){return pm||(pm=1,(function(r,a){(function(o,l){l(a)})($2,(function(o){var l="1.9.4";function d(t){var i,u,A,C;for(u=1,A=arguments.length;u<A;u++){C=arguments[u];for(i in C)t[i]=C[i]}return t}var f=Object.create||(function(){function t(){}return function(i){return t.prototype=i,new t}})();function p(t,i){var u=Array.prototype.slice;if(t.bind)return t.bind.apply(t,u.call(arguments,1));var A=u.call(arguments,2);return function(){return t.apply(i,A.length?A.concat(u.call(arguments)):arguments)}}var h=0;function g(t){return"_leaflet_id"in t||(t._leaflet_id=++h),t._leaflet_id}function m(t,i,u){var A,C,O,Q;return Q=function(){A=!1,C&&(O.apply(u,C),C=!1)},O=function(){A?C=arguments:(t.apply(u,arguments),setTimeout(Q,i),A=!0)},O}function v(t,i,u){var A=i[1],C=i[0],O=A-C;return t===A&&u?t:((t-C)%O+O)%O+C}function y(){return!1}function w(t,i){if(i===!1)return t;var u=Math.pow(10,i===void 0?6:i);return Math.round(t*u)/u}function B(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}function T(t){return B(t).split(/\s+/)}function b(t,i){Object.prototype.hasOwnProperty.call(t,"options")||(t.options=t.options?f(t.options):{});for(var u in i)t.options[u]=i[u];return t.options}function k(t,i,u){var A=[];for(var C in t)A.push(encodeURIComponent(u?C.toUpperCase():C)+"="+encodeURIComponent(t[C]));return(!i||i.indexOf("?")===-1?"?":"&")+A.join("&")}var D=/\{ *([\w_ -]+) *\}/g;function P(t,i){return t.replace(D,function(u,A){var C=i[A];if(C===void 0)throw new Error("No value provided for variable "+u);return typeof C=="function"&&(C=C(i)),C})}var S=Array.isArray||function(t){return Object.prototype.toString.call(t)==="[object Array]"};function N(t,i){for(var u=0;u<t.length;u++)if(t[u]===i)return u;return-1}var I="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";function z(t){return window["webkit"+t]||window["moz"+t]||window["ms"+t]}var H=0;function j(t){var i=+new Date,u=Math.max(0,16-(i-H));return H=i+u,window.setTimeout(t,u)}var ee=window.requestAnimationFrame||z("RequestAnimationFrame")||j,Z=window.cancelAnimationFrame||z("CancelAnimationFrame")||z("CancelRequestAnimationFrame")||function(t){window.clearTimeout(t)};function V(t,i,u){if(u&&ee===j)t.call(i);else return ee.call(window,p(t,i))}function ne(t){t&&Z.call(window,t)}var J={__proto__:null,extend:d,create:f,bind:p,get lastId(){return h},stamp:g,throttle:m,wrapNum:v,falseFn:y,formatNum:w,trim:B,splitWords:T,setOptions:b,getParamString:k,template:P,isArray:S,indexOf:N,emptyImageUrl:I,requestFn:ee,cancelFn:Z,requestAnimFrame:V,cancelAnimFrame:ne};function ie(){}ie.extend=function(t){var i=function(){b(this),this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()},u=i.__super__=this.prototype,A=f(u);A.constructor=i,i.prototype=A;for(var C in this)Object.prototype.hasOwnProperty.call(this,C)&&C!=="prototype"&&C!=="__super__"&&(i[C]=this[C]);return t.statics&&d(i,t.statics),t.includes&&(he(t.includes),d.apply(null,[A].concat(t.includes))),d(A,t),delete A.statics,delete A.includes,A.options&&(A.options=u.options?f(u.options):{},d(A.options,t.options)),A._initHooks=[],A.callInitHooks=function(){if(!this._initHooksCalled){u.callInitHooks&&u.callInitHooks.call(this),this._initHooksCalled=!0;for(var O=0,Q=A._initHooks.length;O<Q;O++)A._initHooks[O].call(this)}},i},ie.include=function(t){var i=this.prototype.options;return d(this.prototype,t),t.options&&(this.prototype.options=i,this.mergeOptions(t.options)),this},ie.mergeOptions=function(t){return d(this.prototype.options,t),this},ie.addInitHook=function(t){var i=Array.prototype.slice.call(arguments,1),u=typeof t=="function"?t:function(){this[t].apply(this,i)};return this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(u),this};function he(t){if(!(typeof L>"u"||!L||!L.Mixin)){t=S(t)?t:[t];for(var i=0;i<t.length;i++)t[i]===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 ae={on:function(t,i,u){if(typeof t=="object")for(var A in t)this._on(A,t[A],i);else{t=T(t);for(var C=0,O=t.length;C<O;C++)this._on(t[C],i,u)}return this},off:function(t,i,u){if(!arguments.length)delete this._events;else if(typeof t=="object")for(var A in t)this._off(A,t[A],i);else{t=T(t);for(var C=arguments.length===1,O=0,Q=t.length;O<Q;O++)C?this._off(t[O]):this._off(t[O],i,u)}return this},_on:function(t,i,u,A){if(typeof i!="function"){console.warn("wrong listener type: "+typeof i);return}if(this._listens(t,i,u)===!1){u===this&&(u=void 0);var C={fn:i,ctx:u};A&&(C.once=!0),this._events=this._events||{},this._events[t]=this._events[t]||[],this._events[t].push(C)}},_off:function(t,i,u){var A,C,O;if(this._events&&(A=this._events[t],!!A)){if(arguments.length===1){if(this._firingCount)for(C=0,O=A.length;C<O;C++)A[C].fn=y;delete this._events[t];return}if(typeof i!="function"){console.warn("wrong listener type: "+typeof i);return}var Q=tLine 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 d=o,f=d.lib,p=f.WordArray,h=f.Hasher,g=d.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]),v=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]),y=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]),B=p.create([0,1518500249,1859775393,2400959708,2840853838]),T=p.create([1352829926,1548603684,1836072691,2053994217,0]),b=g.RIPEMD160=h.extend({_doReset:function(){this._hash=p.create([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(z,H){for(var j=0;j<16;j++){var ee=H+j,Z=z[ee];z[ee]=(Z<<8|Z>>>24)&16711935|(Z<<24|Z>>>8)&4278255360}var V=this._hash.words,ne=B.words,J=T.words,ie=m.words,he=v.words,ae=y.words,pe=w.words,G,Y,q,R,U,K,$,de,fe,ke;K=G=V[0],$=Y=V[1],de=q=V[2],fe=R=V[3],ke=U=V[4];for(var Ae,j=0;j<80;j+=1)Ae=G+z[H+ie[j]]|0,j<16?Ae+=k(Y,q,R)+ne[0]:j<32?Ae+=D(Y,q,R)+ne[1]:j<48?Ae+=P(Y,q,R)+ne[2]:j<64?Ae+=S(Y,q,R)+ne[3]:Ae+=N(Y,q,R)+ne[4],Ae=Ae|0,Ae=I(Ae,ae[j]),Ae=Ae+U|0,G=U,U=R,R=I(q,10),q=Y,Y=Ae,Ae=K+z[H+he[j]]|0,j<16?Ae+=N($,de,fe)+J[0]:j<32?Ae+=S($,de,fe)+J[1]:j<48?Ae+=P($,de,fe)+J[2]:j<64?Ae+=D($,de,fe)+J[3]:Ae+=k($,de,fe)+J[4],Ae=Ae|0,Ae=I(Ae,pe[j]),Ae=Ae+ke|0,K=ke,ke=fe,fe=I(de,10),de=$,$=Ae;Ae=V[1]+q+fe|0,V[1]=V[2]+R+ke|0,V[2]=V[3]+U+K|0,V[3]=V[4]+G+$|0,V[4]=V[0]+Y+de|0,V[0]=Ae},_doFinalize:function(){var z=this._data,H=z.words,j=this._nDataBytes*8,ee=z.sigBytes*8;H[ee>>>5]|=128<<24-ee%32,H[(ee+64>>>9<<4)+14]=(j<<8|j>>>24)&16711935|(j<<24|j>>>8)&4278255360,z.sigBytes=(H.length+1)*4,this._process();for(var Z=this._hash,V=Z.words,ne=0;ne<5;ne++){var J=V[ne];V[ne]=(J<<8|J>>>24)&16711935|(J<<24|J>>>8)&4278255360}return Z},clone:function(){var z=h.clone.call(this);return z._hash=this._hash.clone(),z}});function k(z,H,j){return z^H^j}function D(z,H,j){return z&H|~z&j}function P(z,H,j){return(z|~H)^j}function S(z,H,j){return z&j|H&~j}function N(z,H,j){return z^(H|~j)}function I(z,H){return z<<H|z>>>32-H}d.RIPEMD160=h._createHelper(b),d.HmacRIPEMD160=h._createHmacHelper(b)})(),o.RIPEMD160})})(sc)),sc.exports}var ac={exports:{}},zb=ac.exports,Fm;function id(){return Fm||(Fm=1,(function(r,a){(function(o,l){r.exports=l(dt())})(zb,function(o){(function(){var l=o,d=l.lib,f=d.Base,p=l.enc,h=p.Utf8,g=l.algo;g.HMAC=f.extend({init:function(m,v){m=this._hasher=new m.init,typeof v=="string"&&(v=h.parse(v));var y=m.blockSize,w=y*4;v.sigBytes>w&&(v=m.finalize(v)),v.clamp();for(var B=this._oKey=v.clone(),T=this._iKey=v.clone(),b=B.words,k=T.words,D=0;D<y;D++)b[D]^=1549556828,k[D]^=909522486;B.sigBytes=T.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 v=this._hasher,y=v.finalize(m);v.reset();var w=v.finalize(this._oKey.clone().concat(y));return w}})})()})})(ac)),ac.exports}var lc={exports:{}},Hb=lc.exports,Nm;function Vb(){return Nm||(Nm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),ml(),id())})(Hb,function(o){return(function(){var l=o,d=l.lib,f=d.Base,p=d.WordArray,h=l.algo,g=h.SHA256,m=h.HMAC,v=h.PBKDF2=f.extend({cfg:f.extend({keySize:128/32,hasher:g,iterations:25e4}),init:function(y){this.cfg=this.cfg.extend(y)},compute:function(y,w){for(var B=this.cfg,T=m.create(B.hasher,y),b=p.create(),k=p.create([1]),D=b.words,P=k.words,S=B.keySize,N=B.iterations;D.length<S;){var I=T.update(w).finalize(k);T.reset();for(var z=I.words,H=z.length,j=I,ee=1;ee<N;ee++){j=T.finalize(j),T.reset();for(var Z=j.words,V=0;V<H;V++)z[V]^=Z[V]}b.concat(I),P[0]++}return b.sigBytes=S*4,b}});l.PBKDF2=function(y,w,B){return v.create(B).compute(y,w)}})(),o.PBKDF2})})(lc)),lc.exports}var uc={exports:{}},Ub=uc.exports,Lm;function fo(){return Lm||(Lm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),bx(),id())})(Ub,function(o){return(function(){var l=o,d=l.lib,f=d.Base,p=d.WordArray,h=l.algo,g=h.MD5,m=h.EvpKDF=f.extend({cfg:f.extend({keySize:128/32,hasher:g,iterations:1}),init:function(v){this.cfg=this.cfg.extend(v)},compute:function(v,y){for(var w,B=this.cfg,T=B.hasher.create(),b=p.create(),k=b.words,D=B.keySize,P=B.iterations;k.length<D;){w&&T.update(w),w=T.update(v).finalize(y),T.reset();for(var S=1;S<P;S++)w=T.finalize(w),T.reset();b.concat(w)}return b.sigBytes=D*4,b}});l.EvpKDF=function(v,y,w){return m.create(w).compute(v,y)}})(),o.EvpKDF})})(uc)),uc.exports}var cc={exports:{}},Zb=cc.exports,Line truncated
* Counter block mode compatible with Dr Brian Gladman fileenc.c
* derived from CryptoJS.mode.CTR
* Jan Hruby jhruby.web@gmail.com
*/return o.mode.CTRGladman=(function(){var l=o.lib.BlockCipherMode.extend();function d(h){if((h>>24&255)===255){var g=h>>16&255,m=h>>8&255,v=h&255;g===255?(g=0,m===255?(m=0,v===255?v=0:++v):++m):++g,h=0,h+=g<<16,h+=m<<8,h+=v}else h+=1<<24;return h}function f(h){return(h[0]=d(h[0]))===0&&(h[1]=d(h[1])),h}var p=l.Encryptor=l.extend({processBlock:function(h,g){var m=this._cipher,v=m.blockSize,y=this._iv,w=this._counter;y&&(w=this._counter=y.slice(0),this._iv=void 0),f(w);var B=w.slice(0);m.encryptBlock(B,0);for(var T=0;T<v;T++)h[g+T]^=B[T]}});return l.Decryptor=p,l})(),o.mode.CTRGladman})})(hc)),hc.exports}var pc={exports:{}},Yb=pc.exports,zm;function Xb(){return zm||(zm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),pn())})(Yb,function(o){return o.mode.OFB=(function(){var l=o.lib.BlockCipherMode.extend(),d=l.Encryptor=l.extend({processBlock:function(f,p){var h=this._cipher,g=h.blockSize,m=this._iv,v=this._keystream;m&&(v=this._keystream=m.slice(0),this._iv=void 0),h.encryptBlock(v,0);for(var y=0;y<g;y++)f[p+y]^=v[y]}});return l.Decryptor=d,l})(),o.mode.OFB})})(pc)),pc.exports}var mc={exports:{}},Jb=mc.exports,Hm;function eC(){return Hm||(Hm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),pn())})(Jb,function(o){return o.mode.ECB=(function(){var l=o.lib.BlockCipherMode.extend();return l.Encryptor=l.extend({processBlock:function(d,f){this._cipher.encryptBlock(d,f)}}),l.Decryptor=l.extend({processBlock:function(d,f){this._cipher.decryptBlock(d,f)}}),l})(),o.mode.ECB})})(mc)),mc.exports}var gc={exports:{}},tC=gc.exports,Vm;function nC(){return Vm||(Vm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),pn())})(tC,function(o){return o.pad.AnsiX923={pad:function(l,d){var f=l.sigBytes,p=d*4,h=p-f%p,g=f+h-1;l.clamp(),l.words[g>>>2]|=h<<24-g%4*8,l.sigBytes+=h},unpad:function(l){var d=l.words[l.sigBytes-1>>>2]&255;l.sigBytes-=d}},o.pad.Ansix923})})(gc)),gc.exports}var Ac={exports:{}},rC=Ac.exports,Um;function iC(){return Um||(Um=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),pn())})(rC,function(o){return o.pad.Iso10126={pad:function(l,d){var f=d*4,p=f-l.sigBytes%f;l.concat(o.lib.WordArray.random(p-1)).concat(o.lib.WordArray.create([p<<24],1))},unpad:function(l){var d=l.words[l.sigBytes-1>>>2]&255;l.sigBytes-=d}},o.pad.Iso10126})})(Ac)),Ac.exports}var xc={exports:{}},oC=xc.exports,Zm;function sC(){return Zm||(Zm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),pn())})(oC,function(o){return o.pad.Iso97971={pad:function(l,d){l.concat(o.lib.WordArray.create([2147483648],1)),o.pad.ZeroPadding.pad(l,d)},unpad:function(l){o.pad.ZeroPadding.unpad(l),l.sigBytes--}},o.pad.Iso97971})})(xc)),xc.exports}var vc={exports:{}},aC=vc.exports,Wm;function lC(){return Wm||(Wm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),pn())})(aC,function(o){return o.pad.ZeroPadding={pad:function(l,d){var f=d*4;l.clamp(),l.sigBytes+=f-(l.sigBytes%f||f)},unpad:function(l){for(var d=l.words,f=l.sigBytes-1,f=l.sigBytes-1;f>=0;f--)if(d[f>>>2]>>>24-f%4*8&255){l.sigBytes=f+1;break}}},o.pad.ZeroPadding})})(vc)),vc.exports}var yc={exports:{}},uC=yc.exports,qm;function cC(){return qm||(qm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),pn())})(uC,function(o){return o.pad.NoPadding={pad:function(){},unpad:function(){}},o.pad.NoPadding})})(yc)),yc.exports}var _c={exports:{}},dC=_c.exports,Gm;function fC(){return Gm||(Gm=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),pn())})(dC,function(o){return(function(l){var d=o,f=d.lib,p=f.CipherParams,h=d.enc,g=h.Hex,m=d.format;m.Hex={stringify:function(v){return v.ciphertext.toString(g)},parse:function(v){var y=g.parse(v);return p.create({ciphertext:y})}}})(),o.format.Hex})})(_c)),_c.exports}var wc={exports:{}},hC=wc.exports,Km;function pC(){return Km||(Km=1,(function(r,a){(function(o,l,d){r.exports=l(dt(),Qo(),$o(),fo(),pn())})(hC,function(o){return(function(){var l=o,d=l.lib,f=d.BlockCipher,p=l.algo,h=[],g=[],m=[],v=[],y=[],w=[],B=[],T=[],b=[],k=[];(function(){for(var S=[],N=0;N<256;N++)N<128?S[N]=N<<1:S[N]=N<<1^283;for(var I=0,z=0,N=0;N<256;N++){var H=z^z<<1^z<<2^z<<3^z<<4;H=H>>>8^H&255^99,h[I]=H,g[H]=I;var j=S[I],ee=S[j],Z=S[ee],V=S[H]*257^H*16843008;m[I]=V<<24|V>>>8,v[I]=V<<16|V>>>16,y[I]=V<<8|V>>>24,w[I]=V;var V=Z*16843009^ee*65537^j*257^I*16843008;B[H]=V<<24|V>>>8,T[H]=V<<16|V>>>16,b[H]=V<<8|V>>>24,k[H]=V,I?(I=j^S[S[S[Z^j]]],z^=S[S[z]]):I=z=1}})();var D=[0,1,2,4,8,16,32,64,128,27,54],P=p.AES=f.extend({_doReset:function(){var S;if(!(this._nRounds&&this._keyPriorReset===this._key)){for(var N=this._keyPriorReset=this._key,I=N.words,z=N.sigBytes/4,H=this._nRounds=z+6,j=(H+1)*4,ee=this._keySchedule=[],Z=0;Z<j;Z++)Z<z?ee[Z]=I[Z]:(S=ee[Z-1],Z%z?z>6&&Z%z==4&&(S=h[S>>>24]<<24|h[S>>>16&255]<<16|h[S>>>8&255]<<8|h[S&255]):(S=S<<8|S>>>24,S=h[S>>>24]<<24|h[S>>>16&255]<<16|h[S>>>8&255]<<8|h[S&255],S^=D[Z/z|0]<<24),ee[Z]=ee[Z-z]^S);for(var V=this._invKeySchedule=[],ne=0;ne<j;ne++){var Z=j-ne;if(ne%4)var S=ee[Z];else var S=ee[Z-4];ne<4||Z<=4?V[ne]=S:V[ne]=B[h[S>>>24]]^T[h[S>>>16&255]]^b[h[S>>>8&255]]^k[h[S&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:h+g,endByte:h+d.length-1,value:w});const B={type:r.PayloadType.Request,version:r.PayloadVersion.Version1,isValid:!0,timestamp:0,requestType:r.RequestType.GetStats,requestData:"",destinationHash:m,sourceHash:v,cipherMac:y,ciphertext:w};return f!=null&&f.includeSegments&&(B.segments=p),B}catch(p){return{type:r.PayloadType.Request,version:r.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode request payload"],timestamp:0,requestType:r.RequestType.GetStats,requestData:"",destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:""}}}}return Xa.RequestPayloadDecoder=o,Xa}var Ja={},Ag;function $C(){if(Ag)return Ja;Ag=1,Object.defineProperty(Ja,"__esModule",{value:!0}),Ja.ResponsePayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<4){const T={type:r.PayloadType.Response,version:r.PayloadVersion.Version1,isValid:!1,errors:["Response payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return f!=null&&f.includeSegments&&(T.segments=[{name:"Invalid Response Data",description:"Response payload too short (minimum 4 bytes required)",startByte:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),T}const p=[],h=(f==null?void 0:f.segmentOffset)||0;let g=0;const m=(0,a.byteToHex)(d[g]);f!=null&&f.includeSegments&&p.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:h+g,endByte:h+g,value:m}),g+=1;const v=(0,a.byteToHex)(d[g]);f!=null&&f.includeSegments&&p.push({name:"Source Hash",description:"First byte of source node public key",startByte:h+g,endByte:h+g,value:v}),g+=1;const y=(0,a.bytesToHex)(d.subarray(g,g+2));f!=null&&f.includeSegments&&p.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:h+g,endByte:h+g+1,value:y}),g+=2;const w=(0,a.bytesToHex)(d.subarray(g));f!=null&&f.includeSegments&&d.length>g&&p.push({name:"Ciphertext",description:"Encrypted response data (tag + content)",startByte:h+g,endByte:h+d.length-1,value:w});const B={type:r.PayloadType.Response,version:r.PayloadVersion.Version1,isValid:!0,destinationHash:m,sourceHash:v,cipherMac:y,ciphertext:w,ciphertextLength:d.length-4};return f!=null&&f.includeSegments&&(B.segments=p),B}catch(p){return{type:r.PayloadType.Response,version:r.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode response payload"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return Ja.ResponsePayloadDecoder=o,Ja}var el={},xg;function YC(){if(xg)return el;xg=1,Object.defineProperty(el,"__esModule",{value:!0}),el.AnonRequestPayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<35){const T={type:r.PayloadType.AnonRequest,version:r.PayloadVersion.Version1,isValid:!1,errors:["AnonRequest payload too short (minimum 35 bytes: dest + public key + MAC)"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return f!=null&&f.includeSegments&&(T.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:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),T}const p=[],h=(f==null?void 0:f.segmentOffset)||0;let g=0;const m=(0,a.byteToHex)(d[0]);f!=null&&f.includeSegments&&p.push({name:"Destination Hash",description:`First byte of destination node public key: 0x${m}`,startByte:h+g,endByte:h+g,value:m}),g+=1;const v=(0,a.bytesToHex)(d.subarray(1,33));f!=null&&f.includeSegments&&p.push({name:"Sender Public Key",description:"Ed25519 public key of the sender (32 bytes)",startByte:h+g,endByte:h+g+31,value:v}),g+=32;const y=(0,a.bytesToHex)(d.subarray(33,35));f!=null&&f.includeSegments&&p.push({name:"Cipher MAC",description:"MAC for encrypted data verification (2 bytes)",startByte:h+g,endByte:h+g+1,value:y}),g+=2;const w=(0,a.bytesToHex)(d.subarray(35));f!=null&&f.includeSegments&&d.length>35&&p.push({name:"Ciphertext",description:`Encrypted message data (${d.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:h+g,endByte:h+d.length-1,value:w});const B={type:r.PayloadType.AnonRequest,version:r.PayloadVersion.Version1,isValid:!0,destinationHash:m,senderPublicKey:v,cipherMac:y,ciphertext:w,ciphertextLength:d.length-35};return f!=null&&f.includeSegments&&(B.segments=p),B}catch(p){return{type:r.PayloadType.AnonRequest,version:r.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode AnonRequest payload"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return el.AnonRequestPayloadDecoder=o,el}var tl={},vg;function XC(){if(vg)return tl;vg=1,Object.defineProperty(tl,"__esModule",{value:!0}),tl.AckPayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<4){const v={type:r.PayloadType.Ack,version:r.PayloadVersion.Version1,isValid:!1,errors:["Ack payload too short (minimum 4 bytes for checksum)"],checksum:""};return f!=null&&f.includeSegments&&(v.segments=[{name:"Invalid Ack Data",description:"Ack payload too short (minimum 4 bytes required for checksum)",startByte:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),v}const p=[],h=(f==null?void 0:f.segmentOffset)||0,g=(0,a.bytesToHex)(d.subarray(0,4));f!=null&&f.includeSegments&&p.push({name:"Checksum",description:`CRC checksum of message timestamp, text, and sender pubkey: 0x${g}`,startByte:h,endByte:h+3,value:g}),f!=null&&f.includeSegments&&d.length>4&&p.push({name:"Additional Data",description:"Extra data in Ack payload",startByte:h+4,endByte:h+d.length-1,value:(0,a.bytesToHex)(d.subarray(4))});const m={type:r.PayloadType.Ack,version:r.PayloadVersion.Version1,isValid:!0,checksum:g};return f!=null&&f.includeSegments&&(m.segments=p),m}catch(p){return{type:r.PayloadType.Ack,version:r.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode Ack payload"],checksum:""}}}}return tl.AckPayloadDecoder=o,tl}var nl={},yg;function JC(){if(yg)return nl;yg=1,Object.defineProperty(nl,"__esModule",{value:!0}),nl.PathPayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d){try{if(d.length<2)return{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!1,errors:["Path payload too short (minimum 2 bytes: path length + extra type)"],pathLength:0,pathHashes:[],extraType:0,extraData:""};const f=d[0];if(d.length<1+f+1)return{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!1,errors:[`Path payload too short (need ${1+f+1} bytes for path length + path + extra type)`],pathLength:f,pathHashes:[],extraType:0,extraData:""};const p=[];for(let m=0;m<f;m++)p.push((0,a.byteToHex)(d[1+m]));const h=d[1+f];let g="";return d.length>1+f+1&&(g=(0,a.bytesToHex)(d.subarray(1+f+1))),{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!0,pathLength:f,pathHashes:p,extraType:h,extraData:g}}catch(f){return{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!1,errors:[f instanceof Error?f.message:"Failed to decode Path payload"],pathLength:0,pathHashes:[],extraType:0,extraData:""}}}}return nl.PathPayloadDecoder=o,nl}var rl={},_g;function eE(){if(_g)return rl;_g=1,Object.defineProperty(rl,"__esModule",{value:!0}),rl.TextMessagePayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<4){const T={type:r.PayloadType.TextMessage,version:r.PayloadVersion.Version1,isValid:!1,errors:["TextMessage payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return f!=null&&f.includeSegments&&(T.segments=[{name:"Invalid TextMessage Data",description:"TextMessage payload too short (minimum 4 bytes required)",startByte:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),T}const p=[],h=(f==null?void 0:f.segmentOffset)||0;let g=0;const m=(0,a.byteToHex)(d[g]);f!=null&&f.includeSegments&&p.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:h+g,endByte:h+g,value:m}),g+=1;const v=(0,a.byteToHex)(d[g]);f!=null&&f.includeSegments&&p.push({name:"Source Hash",description:"First byte of source node public key",startByte:h+g,endByte:h+g,value:v}),g+=1;const y=(0,a.bytesToHex)(d.subarray(g,g+2));f!=null&&f.includeSegments&&p.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:h+g,endByte:h+g+1,value:y}),g+=2;const w=(0,a.bytesToHex)(d.subarray(g));f!=null&&f.includeSegments&&d.length>g&&p.push({name:"Ciphertext",description:"Encrypted message data (timestamp + message text)",startByte:h+g,endByte:h+d.length-1,value:w});const B={type:r.PayloadType.TextMessage,version:r.PayloadVersion.Version1,isValid:!0,destinationHash:m,sourceHash:v,cipherMac:y,ciphertext:w,ciphertextLength:d.length-4};return f!=null&&f.includeSegments&&(B.segments=p),B}catch(p){return{type:r.PayloadType.TextMessage,version:r.PayloadVersion.Version1,i Line 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 a=await navigator.gpu.requestAdapter();if(!a)return console.warn("No GPU adapter found"),!1;this.device=await a.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 d=0;d<2;d++)this.matchCountReadBuffers[d]=this.device.createBuffer({size:4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),this.matchIndicesReadBuffers[d]=this.device.createBuffer({size:1024*4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST});const o=this.device.createShaderModule({code:this.shaderCode}),l=this.device.createPipelineLayout({bindGroupLayouts:[this.bindGroupLayout]});return this.pipeline=this.device.createComputePipeline({layout:l,compute:{module:o,entryPoint:"main"}}),!0}catch(a){return console.error("WebGPU initialization failed:",a),!1}}isAvailable(){return this.device!==null&&this.pipeline!==null}indexToRoomName(a,o){return qo(o,a)}countNamesForLength(a){return sl(a)}async runBatch(a,o,l,d,f,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 h=this.currentReadBufferIndex;this.currentReadBufferIndex=1-this.currentReadBufferIndex;const g=this.matchCountReadBuffers[h],m=this.matchIndicesReadBuffers[h],v=f&&p?1:0;let y,w=0,B=0;if(v){const I=new Uint8Array(f.length/2);for(let Z=0;Z<I.length;Z++)I[Z]=parseInt(f.substr(Z*2,2),16);w=I.length*8;const z=Math.ceil(I.length/4)*4,H=new Uint8Array(z);H.set(I),y=new Uint32Array(z/4);for(let Z=0;Z<y.length;Z++)y[Z]=H[Z*4]<<24|H[Z*4+1]<<16|H[Z*4+2]<<8|H[Z*4+3];const j=parseInt(p.substr(0,2),16),ee=parseInt(p.substr(2,2),16);B=j<<24|ee<<16}else y=new Uint32Array([0]);const T=Math.max(y.length*4,4);(!this.ciphertextBuffer||this.ciphertextBufferSize<T)&&(this.ciphertextBuffer&&this.ciphertextBuffer.destroy(),this.ciphertextBuffer=this.device.createBuffer({size:T,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.ciphertextBufferSize=T,this.bindGroupDirty=!0);const b=new Uint32Array([a,l,o,d,B,y.length,w,v]);this.device.queue.writeBuffer(this.paramsBuffer,0,b),this.device.queue.writeBuffer(this.ciphertextBuffer,0,y),this.device.queue.writeBuffer(this.matchCountBuffer,0,sd.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 k=this.device.createCommandEncoder(),D=k.beginComputePass();D.setPipeline(this.pipeline),D.setBindGroup(0,this.bindGroup),D.dispatchWorkgroups(Math.ceil(d/(256*32))),D.end(),k.copyBufferToBuffer(this.matchCountBuffer,0,g,0,4),k.copyBufferToBuffer(this.matchIndicesBuffer,0,m,0,1024*4),this.device.queue.submit([k.finish()]),await g.mapAsync(GPUMapMode.READ);const S=new Uint32Array(g.getMappedRange())[0];g.unmap();const N=[];if(S>0){await m.mapAsync(GPUMapMode.READ);const I=new Uint32Array(m.getMappedRange());for(let z=0;z<Math.min(S,1024);z++)N.push(I[z]);m.unmap()}return N}destroy(){var a,o,l,d,f,p,h,g;(a=this.paramsBuffer)==null||a.destroy(),(o=this.matchCountBuffer)==null||o.destroy(),(l=this.matchIndicesBuffer)==null||l.destroy(),(d=this.ciphertextBuffer)==null||d.destroy(),(f=this.matchCountReadBuffers[0])==null||f.destroy(),(p=this.matchCountReadBuffers[1])==null||p.destroy(),(h=this.matchIndicesReadBuffers[0])==null||h.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}}sd.ZERO_DATA=new Uint32Array([0]);function pE(){return typeof navigator<"u"&&"gpu"in navigator}class Dg{runBatch(a,o,l,d,f,p){const h=[],g=a.toString(16).padStart(2,"0 Line truncated
`).map(f=>f.trim().toLowerCase()).filter(f=>f.length>0);this.wordlist=d.filter(Rg)}setWordlist(a){this.wordlist=a.map(o=>o.trim().toLowerCase()).filter(Rg)}abort(){this.abortFlag=!0}isGpuAvailable(){return pE()}async decodePacket(a){var l;const o=a.trim().replace(/\s+/g,"").replace(/^0x/i,"");if(!o||!/^[0-9a-fA-F]+$/.test(o))return null;try{const f=(l=(await Bg.MeshCorePacketDecoder.decodeWithVerification(o,{})).payload)==null?void 0:l.decoded;return!(f!=null&&f.channelHash)||!(f!=null&&f.ciphertext)||!(f!=null&&f.cipherMac)?null:{channelHash:f.channelHash,ciphertext:f.ciphertext,cipherMac:f.cipherMac,isGroupText:!0}}catch{return null}}async crack(a,o,l){this.abortFlag=!1,this.useTimestampFilter=(o==null?void 0:o.useTimestampFilter)??!0,this.useUtf8Filter=(o==null?void 0:o.useUtf8Filter)??!0,this.useSenderFilter=(o==null?void 0:o.useSenderFilter)??!0,this.validSeconds=(o==null?void 0:o.validSeconds)??h0,this.useCpu=(o==null?void 0:o.forceCpu)??!1;const d=(o==null?void 0:o.maxLength)??8,f=(o==null?void 0:o.startingLength)??1,p=(o==null?void 0:o.useDictionary)??!0,h=(o==null?void 0:o.startFromType)??"bruteforce",g=a.toLowerCase(),m=await this.decodePacket(g);if(!m)return{found:!1,error:"Invalid packet or not a GroupText packet"};const{channelHash:v,ciphertext:y,cipherMac:w}=m,B=parseInt(v,16);this.useCpu?this.cpuInstance||(this.cpuInstance=new Dg):this.gpuInstance||(this.gpuInstance=new sd,await this.gpuInstance.init()||(this.useCpu=!0,this.cpuInstance=new Dg));const T=performance.now();let b=0,k=performance.now(),D=f,P=0,S=0,N=!1;if(o!=null&&o.startFrom){const J=o.startFrom.toLowerCase();if(h==="dictionary"){const ie=this.wordlist.indexOf(J);ie>=0&&(S=ie+1)}else{N=!0;const ie=dE(J);ie&&(D=Math.max(f,ie.length),P=ie.index+1,P>=sl(D)&&(D++,P=0))}}let I=0;p&&!N&&this.wordlist.length>0&&(I+=this.wordlist.length-S);for(let J=D;J<=d;J++)I+=sl(J);I-=P;const z=(J,ie,he)=>{if(!l)return;const pe=(performance.now()-T)/1e3,G=pe>0?Math.round(b/pe):0,Y=I-b,q=G>0?Y/G:0;l({checked:b,total:I,percent:I>0?Math.min(100,b/I*100):0,rateKeysPerSec:G,etaSeconds:q,elapsedSeconds:pe,currentLength:ie,currentPosition:he,phase:J})},H=J=>{if(!Wx(y,w,J))return{valid:!1};const ie=Bg.ChannelCrypto.decryptGroupTextMessage(y,w,J);return!ie.success||!ie.data?{valid:!1}:this.useTimestampFilter&&!fE(ie.data.timestamp,this.validSeconds)?{valid:!1}:this.useUtf8Filter&&!hE(ie.data.message)?{valid:!1}:this.useSenderFilter&&!ie.data.sender?{valid:!1}:{valid:!0,message:ie.data.sender?`${ie.data.sender}: ${ie.data.message}`:ie.data.message}};if(!N&&S===0&&D===f&&P===0){z("public-key",0,f0);const J=m0(Dc);if(v===J){const ie=H(Dc);if(ie.valid)return{found:!0,roomName:f0,key:Dc,decryptedMessage:ie.message}}}if(p&&!N&&this.wordlist.length>0)for(let J=S;J<this.wordlist.length;J++){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:this.wordlist[J],resumeType:"dictionary"};const ie=this.wordlist[J],he=p0("#"+ie),ae=m0(he);if(parseInt(ae,16)===B){const G=H(he);if(G.valid)return{found:!0,roomName:ie,key:he,decryptedMessage:G.message,resumeFrom:ie,resumeType:"dictionary"}}b++;const pe=performance.now();pe-k>=200&&(z("wordlist",ie.length,ie),k=pe,await new Promise(G=>setTimeout(G,0)))}const j=this.useCpu?1024:32768,ee=(o==null?void 0:o.gpuDispatchMs)??1e3;let Z=j,V=!1;for(let J=D;J<=d;J++){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:qo(J,0)||void 0,resumeType:"bruteforce"};const ie=sl(J);let he=J===D?P:0;for(;he<ie;){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:qo(J,he)||void 0,resumeType:"bruteforce"};const ae=Math.min(Z,ie-he),pe=performance.now();let G;this.useCpu?G=this.cpuInstance.runBatch(B,J,he,ae,y,w):G=await this.gpuInstance.runBatch(B,J,he,ae,y,w);const Y=performance.now()-pe;if(b+=ae,!this.useCpu&&!V&&ae>=j&&Y>0){const R=ee/Y,U=Math.round(ae*R),K=Math.pow(2,Math.round(Math.log2(Math.max(j,U))));Z=Math.max(j,K),V=!0}for(const R of G){const U=qo(J,R);if(!U)continue;const K=p0("#"+U),$=H(K);if($.valid)return{found:!0,roomName:U,key:K,decryptedMessage:$.message,resumeFrom:U,resumeType:"bruteforce"}}he+=ae;const q=performance.now();if(q-k>=200){const R=qo(J,Math.min(he,ie-1))||"";z("bruteforce",J,R),k=q,await new Promise(U=>setTimeout(U,0))}}}return{found:!1,resumeFrom:qo(d,sl(d)-1)||void 0,resumeType:"bruteforce"}}destroy(){this.gpuInstance&&(this.gpuInstance.destroy(),this.gpuInstance=null),this.cpuInstance&&(this.cpuInstance.destroy(),this.cpuInstance=null)}}var Yf,Fg;function vE(){return Fg||(Fg=1,Yf={webm:"data:video/webm;base64,GkXfowEAAAAAAAAfQoaBAUL3gQFC8oEEQvOBCEKChHdlYm1Ch4EEQoWBAhhTgGcBAAAAAAAVkhFNm3RALE27i1OrhBVJqWZTrIHfTbuMU6uEFlSua1OsggEwTbuMU6uEHFO7a1OsghV17AEAAAAAAACkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmAQAAAAAAAEUq17GDD0JATYCNTGF2ZjU1LjMzLjEwMFdBjUxhdmY1NS4zMy4xMDBzpJBlrrXf3DCDVB8KcgbMpcr+RImIQJBgAAAAAAAWVK5rAQAAAAAAD++uAQAAAAA 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(h=>(this.enabled=!0,h)).catch(h=>{throw this.enabled=!1,h})}disable(){l()?(this._wakeLock&&this._wakeLock.release(),this._wakeLock=null):o()?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 Xf=d,Xf}var _E=yE();const wE=Ys(_E);function bE(r){if(r.length<4)return null;try{const o=parseInt(r.slice(0,2),16)&3;let l=2;if(o===0||o===3){if(r.length<l+8)return null;l+=8}if(r.length<l+2)return null;const d=parseInt(r.slice(l,l+2),16);l+=2;const f=d*2;return r.length<l+f?null:(l+=f,r.slice(l))}catch{return null}}function CE({packets:r,channels:a,onChannelCreate:o,onRunningChange:l,visible:d=!1}){const[f,p]=F.useState(!1),[h,g]=F.useState(6),[m,v]=F.useState(!1),[y,w]=F.useState(!0),[B,T]=F.useState(!1),[b,k]=F.useState(null),[D,P]=F.useState(new Map),[S,N]=F.useState([]),[I,z]=F.useState(!1),[H,j]=F.useState(null),[ee,Z]=F.useState(null),[V,ne]=F.useState(0),J=F.useRef(null),ie=F.useRef(null),he=F.useRef(!1),ae=F.useRef(!1),pe=F.useRef(!1),G=F.useRef(new Map),Y=F.useRef(!1),q=F.useRef(6),R=F.useRef(!0),U=F.useRef(!1),K=F.useRef(new Set),$=F.useRef(new Set);F.useEffect(()=>{const Se=new xE;J.current=Se,j(Se.isGpuAvailable());const Ze=new wE;return ie.current=Ze,()=>{Se.destroy(),J.current=null,Ze.disable(),ie.current=null}},[]),F.useEffect(()=>{!d||I||gb(async()=>{const{ENGLISH_WORDLIST:Se}=await import("./wordlist-BtmChKSf.js");return{ENGLISH_WORDLIST:Se}},[]).then(({ENGLISH_WORDLIST:Se})=>{J.current&&(J.current.setWordlist(Se),z(!0))}).catch(Se=>{console.error("Failed to load wordlist:",Se),bt.error("Failed to load wordlist",{description:"Cracking will not be available"})})},[d,I]),F.useEffect(()=>{const Se=()=>{ot.getUndecryptedPacketCount().then(({count:lt})=>Z(lt)).catch(()=>Z(null))};Se();const Ze=setInterval(Se,3e4);return()=>clearInterval(Ze)},[]);const de=F.useMemo(()=>new Set(a.map(Se=>Se.key.toUpperCase())),[a]),fe=r.filter(Se=>Se.payload_type==="GROUP_TEXT"&&!Se.decrypted);F.useEffect(()=>{let Se=0;P(Ze=>{const lt=new Map(Ze);let Rt=!1;for(const xt of fe)if(!lt.has(xt.id)){const it=bE(xt.data);if(it&&$.current.has(it)){Se++;continue}it&&$.current.add(it),lt.set(xt.id,{packet:xt,attempts:0,lastAttemptLength:0,status:"pending"}),Rt=!0}return Rt?(G.current=lt,lt):Ze}),Se>0&&ne(Ze=>Ze+Se)},[fe.length]),F.useEffect(()=>{G.current=D},[D]),F.useEffect(()=>{Y.current=m},[m]),F.useEffect(()=>{q.current=h},[h]),F.useEffect(()=>{R.current=y},[y]),F.useEffect(()=>{U.current=B},[B]),F.useEffect(()=>{K.current=new Set(fe.map(Se=>Se.id))},[fe]),F.useEffect(()=>{l==null||l(f)},[f,l]);const ke=Array.from(D.values()).filter(Se=>Se.status==="pending").length,Ae=Array.from(D.values()).filter(Se=>Se.status==="cracked").length,We=Array.from(D.values()).filter(Se=>Se.status==="failed").length,$e=F.useCallback(async()=>{if(pe.current||!J.current||!he.current)return;const Se=G.current;let Ze=null,lt=null;for(const[Qe,Xe]of Se.entries())if(Xe.status==="pending"){Ze=Xe,lt=Qe;break}if(!Ze&&Y.current){const Qe=Array.from(Se.entries()).filter(([,Xe])=>Xe.status==="failed"&&Xe.lastAttemptLength<10);Qe.length>0&&(Qe.sort((Xe,xe)=>Xe[1].lastAttemptLength-xe[1].lastAttemptLength),[lt,Ze]=Qe[0])}if(!Ze||lt===null){he.current&&setTimeout(()=>$e(),1e3);return}if(!K.current.has(lt)){P(Qe=>{const Xe=new Map(Qe);return Xe.delete(lt),Xe}),he.current&&setTimeout(()=>$e(),10);return}pe.current=!0;const Rt=q.current,xt=Ze.lastAttemptLength>0,it=xt?Ze.lastAttemptLength+1:Rt;try{const Qe=await J.current.crack(Ze.packet.data,{maxLength:it,useSenderFilter:!0,useTimestampFilter:!0,useUtf8Filter:!0,...U.current&&{gpuDispatchMs:1e4},...xt&&{useDictionary:!1,startingLength:it}},Xe=>{k(Xe)});if(ae.current){ae.current=!1,pe.current=!1,k(null);return}if(Qe.found&&Qe.roomName&&Qe.key){P(Te=>{const pt=new Map(Te),Zt=pt.get(lt);return Zt&&pt.set(lt,{...Zt,status:"cracked",attempts:Zt.attempts+1,lastAttemptLength:it}),pt});const Xe={roomName:Qe.roomName,key:Qe.key,packetId:lt,message:Qe.decryptedMessage||"",crackedAt:Date.now()};N(Te=>[...Te,Xe]);const xe=Qe.key.toUpperCase();if(!de.has(xe))try{const Te="#"+Qe.roomName;await o(Te,Qe.key),R.current&&await ot.decryptHistoricalPackets({key_type:"channel",channel_name:Te})}catch(Te){console.error("Failed to create channel or decrypt historical:",Te),bt.error("Failed to save cracked channel",{description:Te instanceof Error?Te.message:"Channel discovered but could not be saved"})}}else P(Xe=>{const xe=new Map(Xe),Te=xe.get(lt);return Te&&xe.set(lt,{...Te,status:"failed",attempts:Te.attempts+1,lastAttemptLength:it}),xe})}catch(Qe){console.error("Cracking error:",Qe),P(Xe=>{const xe=new Map(Xe),Te=xe.get(lt);return Te&&xe.set(lt,{...Te,status:"failed",attempts:Te.attempts+1,lastAttemptLength:it}),xe})}pe.current=!1,k(null),he.current&&setTimeout(()=>$e(),100)},[de,o]),wt=()=>{var Se;if(!H){bt.error("WebGPU not available",{description:"Cracking requires Chrome 113+ or Edge 113+ with WebGPU support."});return}p(!0),he.current=!0,ae.current=!1,(Se=ie.current)==null||Se.enable(),$e()},ft=()=>{var Se,Ze;p(!1),he.current=!1,ae.current=!0,(Se=J.current)==null||Se.abort(),(Ze=ie.current)==nu Line truncated
//# sourceMappingURL=index-r2fyhyDF.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,IAAI,EAAE,CAAC,UAAU,UAAU,CAAC,MAAM,EAAE,EAAE,mBAAmB,UAAU,GAAG,oBAAoB,UAAU,GAAG,gBAAgB,UAAU,EAAE,EAAEC,EAAE,OAAO,OAAOC,EAAE,GAAG,SAASC,EAAEH,EAAEI,EAAEC,EAAE,CAAC,KAAK,MAAML,EAAE,KAAK,QAAQI,EAAE,KAAK,KAAKF,EAAE,KAAK,QAAQG,GAAG,CAAC,CAACF,EAAE,UAAU,iBAAiB,GACnQA,EAAE,UAAU,SAAS,SAASH,EAAEI,EAAE,CAAC,GAAc,OAAOJ,GAAlB,UAAkC,OAAOA,GAApB,YAA6BA,GAAN,KAAQ,MAAM,MAAM,uHAAuH,EAAE,KAAK,QAAQ,gBAAgB,KAAKA,EAAEI,EAAE,UAAU,CAAC,EAAED,EAAE,UAAU,YAAY,SAASH,EAAE,CAAC,KAAK,QAAQ,mBAAmB,KAAKA,EAAE,aAAa,CAAC,EAAE,SAASM,GAAG,EAAEA,EAAE,UAAUH,EAAE,UAAU,SAASI,EAAEP,EAAEI,EAAEC,EAAE,CAAC,KAAK,MAAML,EAAE,KAAK,QAAQI,EAAE,KAAK,KAAKF,EAAE,KAAK,QAAQG,GAAG,CAAC,CAAC,IAAIG,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,EAAEb,EAAEI,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,GAAGnB,GAAGA,EAAE,aAAa,IAAIc,KAAKI,GAAElB,EAAE,aAAakB,GAAWH,GAAED,CAAC,IAAZ,SAAgBC,GAAED,CAAC,EAAEI,GAAEJ,CAAC,GAAG,MAAM,CAAC,SAAS3B,EAAE,KAAKa,EAAE,IAAIgB,GAAE,IAAIC,GAAE,MAAMF,GAAE,OAAOJ,EAAE,OAAO,CAAC,CAC7a,SAASU,GAAErB,EAAEI,EAAE,CAAC,MAAM,CAAC,SAASjB,EAAE,KAAKa,EAAE,KAAK,IAAII,EAAE,IAAIJ,EAAE,IAAI,MAAMA,EAAE,MAAM,OAAOA,EAAE,MAAM,CAAC,CAAC,SAASsB,EAAEtB,EAAE,CAAC,OAAiB,OAAOA,GAAlB,UAA4BA,IAAP,MAAUA,EAAE,WAAWb,CAAC,CAAC,SAASoC,EAAOvB,EAAE,CAAC,IAAII,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,EAAE,MAAM,IAAIJ,EAAE,QAAQ,QAAQ,SAASA,EAAE,CAAC,OAAOI,EAAEJ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAIwB,GAAE,OAAO,SAASC,EAAEzB,EAAEI,EAAE,CAAC,OAAiB,OAAOJ,GAAlB,UAA4BA,IAAP,MAAgBA,EAAE,KAAR,KAAYuB,EAAO,GAAGvB,EAAE,GAAG,EAAEI,EAAE,SAAS,EAAE,CAAC,CAC/W,SAASsB,GAAE1B,EAAEI,EAAEC,EAAES,EAAEC,GAAE,CAAC,IAAIC,GAAE,OAAOhB,GAAmBgB,KAAd,aAA6BA,KAAZ,aAAchB,EAAE,MAAK,IAAIiB,GAAE,GAAG,GAAUjB,IAAP,KAASiB,GAAE,OAAQ,QAAOD,GAAC,CAAE,IAAK,SAAS,IAAK,SAASC,GAAE,GAAG,MAAM,IAAK,SAAS,OAAOjB,EAAE,SAAQ,CAAE,KAAKb,EAAE,KAAKC,EAAE6B,GAAE,EAAE,CAAC,CAAC,GAAGA,GAAE,OAAOA,GAAEjB,EAAEe,GAAEA,GAAEE,EAAC,EAAEjB,EAAOc,IAAL,GAAO,IAAIW,EAAER,GAAE,CAAC,EAAEH,EAAEL,EAAEM,EAAC,GAAGV,EAAE,GAASL,GAAN,OAAUK,EAAEL,EAAE,QAAQwB,GAAE,KAAK,EAAE,KAAKE,GAAEX,GAAEX,EAAEC,EAAE,GAAG,SAASL,GAAE,CAAC,OAAOA,EAAC,CAAC,GAASe,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,KAAKxB,CAAC,GAAGI,EAAE,KAAKW,EAAC,GAAG,EAAyB,GAAvBE,GAAE,EAAEH,EAAOA,IAAL,GAAO,IAAIA,EAAE,IAAOL,EAAET,CAAC,EAAE,QAAQkB,GAAE,EAAEA,GAAElB,EAAE,OAAOkB,KAAI,CAACF,GACrfhB,EAAEkB,EAAC,EAAE,IAAIC,GAAEL,EAAEW,EAAET,GAAEE,EAAC,EAAED,IAAGS,GAAEV,GAAEZ,EAAEC,EAAEc,GAAEJ,EAAC,CAAC,SAASI,GAAEpB,EAAEC,CAAC,EAAe,OAAOmB,IAApB,WAAsB,IAAInB,EAAEmB,GAAE,KAAKnB,CAAC,EAAEkB,GAAE,EAAE,EAAEF,GAAEhB,EAAE,KAAI,GAAI,MAAMgB,GAAEA,GAAE,MAAMG,GAAEL,EAAEW,EAAET,GAAEE,IAAG,EAAED,IAAGS,GAAEV,GAAEZ,EAAEC,EAAEc,GAAEJ,EAAC,UAAqBC,KAAX,SAAa,MAAMZ,EAAE,OAAOJ,CAAC,EAAE,MAAM,mDAAuEI,IAApB,kBAAsB,qBAAqB,OAAO,KAAKJ,CAAC,EAAE,KAAK,IAAI,EAAE,IAAII,GAAG,2EAA2E,EAAE,OAAOa,EAAC,CACzZ,SAASU,GAAE3B,EAAEI,EAAEC,EAAE,CAAC,GAASL,GAAN,KAAQ,OAAOA,EAAE,IAAIc,EAAE,GAAGC,GAAE,EAAE,OAAAW,GAAE1B,EAAEc,EAAE,GAAG,GAAG,SAASd,GAAE,CAAC,OAAOI,EAAE,KAAKC,EAAEL,GAAEe,IAAG,CAAC,CAAC,EAASD,CAAC,CAAC,SAASc,GAAE5B,EAAE,CAAC,GAAQA,EAAE,UAAP,GAAe,CAAC,IAAII,EAAEJ,EAAE,QAAQI,EAAEA,EAAC,EAAGA,EAAE,KAAK,SAASA,EAAE,EAAQJ,EAAE,UAAN,GAAoBA,EAAE,UAAP,MAAeA,EAAE,QAAQ,EAAEA,EAAE,QAAQI,EAAC,EAAE,SAASA,EAAE,EAAQJ,EAAE,UAAN,GAAoBA,EAAE,UAAP,MAAeA,EAAE,QAAQ,EAAEA,EAAE,QAAQI,EAAC,CAAC,EAAOJ,EAAE,UAAP,KAAiBA,EAAE,QAAQ,EAAEA,EAAE,QAAQI,EAAE,CAAC,GAAOJ,EAAE,UAAN,EAAc,OAAOA,EAAE,QAAQ,QAAQ,MAAMA,EAAE,OAAQ,CAC5Z,IAAI6B,GAAE,CAAC,QAAQ,IAAI,EAAEC,EAAE,CAAC,WAAW,IAAI,EAAEC,EAAE,CAAC,uBAAuBF,GAAE,wBAAwBC,EAAE,kBAAkBnB,CAAC,EAAE,SAASqB,GAAG,CAAC,MAAM,MAAM,0DAA0D,CAAE,CACzM,OAAAC,GAAA,SAAiB,CAAC,IAAIN,GAAE,QAAQ,SAAS3B,EAAEI,EAAEC,EAAE,CAACsB,GAAE3B,EAAE,UAAU,CAACI,EAAE,MAAM,KAAK,SAAS,CAAC,EAAEC,CAAC,CAAC,EAAE,MAAM,SAASL,EAAE,CAAC,IAAII,EAAE,EAAE,OAAAuB,GAAE3B,EAAE,UAAU,CAACI,GAAG,CAAC,EAASA,CAAC,EAAE,QAAQ,SAASJ,EAAE,CAAC,OAAO2B,GAAE3B,EAAE,SAASA,EAAE,CAAC,OAAOA,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,SAASA,EAAE,CAAC,GAAG,CAACsB,EAAEtB,CAAC,EAAE,MAAM,MLine truncated
+2 -2
View File
@@ -13,8 +13,8 @@
<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-DlEnSqQ7.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-aLTdJARH.css">
<script type="module" crossorigin src="/assets/index-r2fyhyDF.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DIRlMkt4.css">
</head>
<body>
<div id="root"></div>
+65 -6
View File
@@ -21,7 +21,8 @@ import { Toaster, toast } from './components/ui/sonner';
import { getStateKey } from './utils/conversationState';
import { formatTime } from './utils/messageParser';
import { pubkeysMatch, getContactDisplayName } from './utils/pubkey';
import { parseHashConversation, updateUrlHash } from './utils/urlHash';
import { parseHashConversation, updateUrlHash, getMapFocusHash } from './utils/urlHash';
import { isValidLocation, calculateDistance, formatDistance } from './utils/pathUtils';
import { loadFavorites, toggleFavorite, isFavorite, type Favorite } from './utils/favorites';
import { cn } from '@/lib/utils';
import type {
@@ -121,6 +122,8 @@ export function App() {
toast.success('Radio connected', {
description: data.serial_port ? `Connected to ${data.serial_port}` : undefined,
});
// Refresh config after reconnection (may have changed after reboot)
api.getRadioConfig().then(setConfig).catch(console.error);
} else {
toast.error('Radio disconnected', {
description: 'Check radio connection and power',
@@ -272,6 +275,14 @@ export function App() {
if (hashConv.type === 'raw') {
return { type: 'raw', id: 'raw', name: 'Raw Packet Feed' };
}
if (hashConv.type === 'map') {
return {
type: 'map',
id: 'map',
name: 'Node Map',
mapFocusKey: hashConv.mapFocusKey,
};
}
if (hashConv.type === 'channel') {
const channel = channels.find(
(c) => c.name === hashConv.name || c.name === `#${hashConv.name}`
@@ -588,7 +599,7 @@ export function App() {
Node Map
</div>
<div className="flex-1 overflow-hidden">
<MapView contacts={contacts} />
<MapView contacts={contacts} focusedKey={activeConversation.mapFocusKey} />
</div>
</>
) : activeConversation.type === 'raw' ? (
@@ -612,8 +623,22 @@ export function App() {
: ''}
{activeConversation.name}
</span>
<span className="font-normal text-sm text-muted-foreground font-mono truncate">
{activeConversation.id}
<span
className="font-normal text-sm text-muted-foreground font-mono truncate cursor-pointer hover:text-primary"
onClick={(e) => {
e.stopPropagation();
navigator.clipboard.writeText(activeConversation.id);
toast.success(
activeConversation.type === 'channel'
? 'Room key copied!'
: 'Contact key copied!'
);
}}
title="Click to copy"
>
{activeConversation.type === 'channel'
? activeConversation.id.toLowerCase()
: activeConversation.id}
</span>
{activeConversation.type === 'contact' &&
(() => {
@@ -621,7 +646,7 @@ export function App() {
(c) => c.public_key === activeConversation.id
);
if (!contact) return null;
const parts: string[] = [];
const parts: React.ReactNode[] = [];
if (contact.last_seen) {
parts.push(`Last heard: ${formatTime(contact.last_seen)}`);
}
@@ -634,9 +659,43 @@ export function App() {
`${contact.last_path_len} hop${contact.last_path_len > 1 ? 's' : ''}`
);
}
// Add coordinate link if contact has valid location
if (isValidLocation(contact.lat, contact.lon)) {
// Calculate distance from us if we have valid location
const distFromUs =
config && isValidLocation(config.lat, config.lon)
? calculateDistance(config.lat, config.lon, contact.lat, contact.lon)
: null;
parts.push(
<span key="coords">
<span
className="font-mono cursor-pointer hover:text-primary hover:underline"
onClick={(e) => {
e.stopPropagation();
const url =
window.location.origin +
window.location.pathname +
getMapFocusHash(contact.public_key);
window.open(url, '_blank');
}}
title="View on map"
>
{contact.lat!.toFixed(3)}, {contact.lon!.toFixed(3)}
</span>
{distFromUs !== null && ` (${formatDistance(distFromUs)})`}
</span>
);
}
return parts.length > 0 ? (
<span className="font-normal text-sm text-muted-foreground flex-shrink-0">
({parts.join(', ')})
(
{parts.map((part, i) => (
<span key={i}>
{i > 0 && ', '}
{part}
</span>
))}
)
</span>
) : null;
})()}
+48 -6
View File
@@ -1,13 +1,16 @@
import { useEffect, useState, useMemo } from 'react';
import { useEffect, useState, useMemo, useRef, useCallback } from 'react';
import { MapContainer, TileLayer, CircleMarker, Popup, useMap } from 'react-leaflet';
import type { LatLngBoundsExpression } from 'leaflet';
import type { LatLngBoundsExpression, CircleMarker as LeafletCircleMarker } from 'leaflet';
import 'leaflet/dist/leaflet.css';
import type { Contact } from '../types';
import { formatTime } from '../utils/messageParser';
import { CONTACT_TYPE_REPEATER } from '../types';
import { pubkeysMatch } from '../utils/pubkey';
interface MapViewProps {
contacts: Contact[];
/** Public key (or prefix) of contact to focus on and open popup */
focusedKey?: string | null;
}
// Calculate marker color based on how recently the contact was heard
@@ -24,11 +27,24 @@ function getMarkerColor(lastSeen: number): string {
}
// Component to handle map bounds fitting
function MapBoundsHandler({ contacts }: { contacts: Contact[] }) {
function MapBoundsHandler({
contacts,
focusedContact,
}: {
contacts: Contact[];
focusedContact: Contact | null;
}) {
const map = useMap();
const [hasInitialized, setHasInitialized] = useState(false);
useEffect(() => {
// If we have a focused contact, center on it immediately (even if already initialized)
if (focusedContact && focusedContact.lat != null && focusedContact.lon != null) {
map.setView([focusedContact.lat, focusedContact.lon], 12);
setHasInitialized(true);
return;
}
if (hasInitialized) return;
const fitToContacts = () => {
@@ -72,12 +88,12 @@ function MapBoundsHandler({ contacts }: { contacts: Contact[] }) {
// No geolocation support - fit to contacts
fitToContacts();
}
}, [map, contacts, hasInitialized]);
}, [map, contacts, hasInitialized, focusedContact]);
return null;
}
export function MapView({ contacts }: MapViewProps) {
export function MapView({ contacts, focusedKey }: MapViewProps) {
// Filter to contacts with GPS coordinates, heard within the last 7 days
const mappableContacts = useMemo(() => {
const sevenDaysAgo = Date.now() / 1000 - 7 * 24 * 60 * 60;
@@ -86,6 +102,31 @@ export function MapView({ contacts }: MapViewProps) {
);
}, [contacts]);
// Find the focused contact by key prefix
const focusedContact = useMemo(() => {
if (!focusedKey) return null;
return mappableContacts.find((c) => pubkeysMatch(c.public_key, focusedKey)) || null;
}, [focusedKey, mappableContacts]);
// Track marker refs to open popup programmatically
const markerRefs = useRef<Record<string, LeafletCircleMarker | null>>({});
// Store ref for a marker
const setMarkerRef = useCallback((key: string, ref: LeafletCircleMarker | null) => {
markerRefs.current[key] = ref;
}, []);
// Open popup for focused contact after map is ready
useEffect(() => {
if (focusedContact && markerRefs.current[focusedContact.public_key]) {
// Small delay to ensure map has finished rendering
const timer = setTimeout(() => {
markerRefs.current[focusedContact.public_key]?.openPopup();
}, 100);
return () => clearTimeout(timer);
}
}, [focusedContact]);
return (
<div className="flex flex-col h-full">
{/* Info bar */}
@@ -122,7 +163,7 @@ export function MapView({ contacts }: MapViewProps) {
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<MapBoundsHandler contacts={mappableContacts} />
<MapBoundsHandler contacts={mappableContacts} focusedContact={focusedContact} />
{mappableContacts.map((contact) => {
const isRepeater = contact.type === CONTACT_TYPE_REPEATER;
@@ -132,6 +173,7 @@ export function MapView({ contacts }: MapViewProps) {
return (
<CircleMarker
key={contact.public_key}
ref={(ref) => setMarkerRef(contact.public_key, ref)}
center={[contact.lat!, contact.lon!]}
radius={isRepeater ? 10 : 7}
pathOptions={{
+97 -12
View File
@@ -12,10 +12,12 @@ import {
resolvePath,
calculateDistance,
isValidLocation,
formatDistance,
type SenderInfo,
type ResolvedPath,
type PathHop,
} from '../utils/pathUtils';
import { getMapFocusHash } from '../utils/urlHash';
interface PathModalProps {
open: boolean;
@@ -42,7 +44,7 @@ export function PathModal({ open, onClose, path, senderInfo, contacts, config }:
</DialogHeader>
<div className="flex-1 overflow-y-auto py-2">
<PathVisualization resolved={resolved} />
<PathVisualization resolved={resolved} senderInfo={senderInfo} />
</div>
<DialogFooter>
@@ -55,9 +57,10 @@ export function PathModal({ open, onClose, path, senderInfo, contacts, config }:
interface PathVisualizationProps {
resolved: ResolvedPath;
senderInfo: SenderInfo;
}
function PathVisualization({ resolved }: PathVisualizationProps) {
function PathVisualization({ resolved, senderInfo }: PathVisualizationProps) {
// Track previous location for each hop to calculate distances
// Returns null if previous hop was ambiguous or has invalid location
const getPrevLocation = (hopIndex: number): { lat: number | null; lon: number | null } | null => {
@@ -93,6 +96,9 @@ function PathVisualization({ resolved }: PathVisualizationProps) {
prefix={resolved.sender.prefix}
distance={null}
isFirst
lat={resolved.sender.lat}
lon={resolved.sender.lon}
publicKey={senderInfo.publicKeyOrPrefix}
/>
{/* Hops */}
@@ -112,6 +118,9 @@ function PathVisualization({ resolved }: PathVisualizationProps) {
prefix={resolved.receiver.prefix}
distance={calculateReceiverDistance(resolved)}
isLast
lat={resolved.receiver.lat}
lon={resolved.receiver.lon}
publicKey={resolved.receiver.publicKey ?? undefined}
/>
{/* Total distance */}
@@ -120,9 +129,36 @@ function PathVisualization({ resolved }: PathVisualizationProps) {
<span className="text-sm text-muted-foreground">
Presumed unambiguous distance covered:{' '}
</span>
<span className="text-sm font-medium">{formatDistance(resolved.totalDistances[0])}</span>
<span className="text-sm font-medium">
{resolved.hasGaps ? '>' : ''}
{formatDistance(resolved.totalDistances[0])}
</span>
</div>
)}
{/* Straight-line distance (when both sender and receiver have coordinates) */}
{isValidLocation(resolved.sender.lat, resolved.sender.lon) &&
isValidLocation(resolved.receiver.lat, resolved.receiver.lon) && (
<div
className={
resolved.totalDistances && resolved.totalDistances.length > 0
? 'pt-1'
: 'pt-3 mt-3 border-t border-border'
}
>
<span className="text-sm text-muted-foreground">Straight-line distance: </span>
<span className="text-sm font-medium">
{formatDistance(
calculateDistance(
resolved.sender.lat,
resolved.sender.lon,
resolved.receiver.lat,
resolved.receiver.lon
)!
)}
</span>
</div>
)}
</div>
);
}
@@ -134,9 +170,26 @@ interface PathNodeProps {
distance: number | null;
isFirst?: boolean;
isLast?: boolean;
/** Optional coordinates for map link */
lat?: number | null;
lon?: number | null;
/** Public key for map focus link (required if lat/lon provided) */
publicKey?: string;
}
function PathNode({ label, name, prefix, distance, isFirst, isLast }: PathNodeProps) {
function PathNode({
label,
name,
prefix,
distance,
isFirst,
isLast,
lat,
lon,
publicKey,
}: PathNodeProps) {
const hasLocation = isValidLocation(lat ?? null, lon ?? null) && publicKey;
return (
<div className="flex gap-3">
{/* Vertical line and dot column */}
@@ -151,10 +204,11 @@ function PathNode({ label, name, prefix, distance, isFirst, isLast }: PathNodePr
<div className="text-xs text-muted-foreground font-medium">{label}</div>
<div className="font-medium truncate">
{name} <span className="text-muted-foreground font-mono text-sm">({prefix})</span>
{distance !== null && (
<span className="text-xs text-muted-foreground ml-1">- {formatDistance(distance)}</span>
)}
{hasLocation && <CoordinateLink lat={lat!} lon={lon!} publicKey={publicKey!} />}
</div>
{distance !== null && (
<div className="text-xs text-muted-foreground">{formatDistance(distance)}</div>
)}
</div>
</div>
);
@@ -210,6 +264,7 @@ function HopNode({ hop, hopNumber, prevLocation }: HopNodeProps) {
<div>
{hop.matches.map((contact) => {
const dist = getDistanceForContact(contact);
const hasLocation = isValidLocation(contact.lat, contact.lon);
return (
<div key={contact.public_key} className="font-medium truncate">
{contact.name || contact.public_key.slice(0, 12)}{' '}
@@ -221,6 +276,13 @@ function HopNode({ hop, hopNumber, prevLocation }: HopNodeProps) {
- {formatDistance(dist)}
</span>
)}
{hasLocation && (
<CoordinateLink
lat={contact.lat!}
lon={contact.lon!}
publicKey={contact.public_key}
/>
)}
</div>
);
})}
@@ -234,6 +296,13 @@ function HopNode({ hop, hopNumber, prevLocation }: HopNodeProps) {
- {formatDistance(hop.distanceFromPrev)}
</span>
)}
{isValidLocation(hop.matches[0].lat, hop.matches[0].lon) && (
<CoordinateLink
lat={hop.matches[0].lat!}
lon={hop.matches[0].lon!}
publicKey={hop.matches[0].public_key}
/>
)}
</div>
)}
</div>
@@ -241,11 +310,27 @@ function HopNode({ hop, hopNumber, prevLocation }: HopNodeProps) {
);
}
function formatDistance(km: number): string {
if (km < 1) {
return `${Math.round(km * 1000)}m`;
}
return `${km.toFixed(1)}km`;
/**
* Render clickable coordinates that open the map focused on the contact
*/
function CoordinateLink({ lat, lon, publicKey }: { lat: number; lon: number; publicKey: string }) {
const handleClick = (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
// Open map in new tab with focus on this contact
const url = window.location.origin + window.location.pathname + getMapFocusHash(publicKey);
window.open(url, '_blank');
};
return (
<span
className="text-xs text-muted-foreground/70 font-mono cursor-pointer hover:text-primary hover:underline ml-1"
onClick={handleClick}
title="View on map"
>
({lat.toFixed(4)}, {lon.toFixed(4)})
</span>
);
}
function calculateReceiverDistance(resolved: ResolvedPath): number | null {
+99
View File
@@ -6,6 +6,7 @@ import {
sortContactsByDistance,
getHopCount,
resolvePath,
formatDistance,
} from '../utils/pathUtils';
import type { Contact, RadioConfig } from '../types';
import { CONTACT_TYPE_REPEATER, CONTACT_TYPE_CLIENT } from '../types';
@@ -473,4 +474,102 @@ describe('resolvePath', () => {
// But second hop CAN have distance (from first hop)
expect(result.hops[1].distanceFromPrev).not.toBeNull();
});
it('sets hasGaps to false when all hops are unambiguous with locations', () => {
const result = resolvePath('1A2B', sender, contacts, config);
expect(result.hasGaps).toBe(false);
});
it('sets hasGaps to true when path has unknown hops', () => {
const result = resolvePath('XX', sender, contacts, config);
expect(result.hasGaps).toBe(true);
});
it('sets hasGaps to true when path has ambiguous hops', () => {
const ambiguousContacts = [
createContact({
public_key: '1A' + 'A'.repeat(62),
name: 'Repeater1A',
type: CONTACT_TYPE_REPEATER,
lat: 40.75,
lon: -74.0,
}),
createContact({
public_key: '1A' + 'B'.repeat(62),
name: 'Repeater1B',
type: CONTACT_TYPE_REPEATER,
lat: 40.76,
lon: -73.99,
}),
];
const result = resolvePath('1A', sender, ambiguousContacts, config);
expect(result.hasGaps).toBe(true);
});
it('sets hasGaps to true when sender has no location', () => {
const senderNoLocation = {
name: 'SenderNoLoc',
publicKeyOrPrefix: '5E' + 'E'.repeat(62),
lat: null,
lon: null,
};
const result = resolvePath('1A', senderNoLocation, contacts, config);
expect(result.hasGaps).toBe(true);
});
it('sets hasGaps to true when receiver has no valid location', () => {
const configNoLocation = createConfig({
public_key: 'FF' + 'F'.repeat(62),
name: 'MyRadio',
lat: 0,
lon: 0,
});
const result = resolvePath('1A', sender, contacts, configNoLocation);
expect(result.hasGaps).toBe(true);
});
it('includes receiver public key when config has one', () => {
const result = resolvePath('1A', sender, contacts, config);
expect(result.receiver.publicKey).toBe(config.public_key);
});
it('sets receiver public key to null when config has no public key', () => {
const configNoKey = createConfig({
public_key: undefined as unknown as string,
name: 'NoKeyRadio',
});
const result = resolvePath('1A', sender, contacts, configNoKey);
expect(result.receiver.publicKey).toBeNull();
});
});
describe('formatDistance', () => {
it('formats distances under 1km in meters', () => {
expect(formatDistance(0.5)).toBe('500m');
expect(formatDistance(0.123)).toBe('123m');
expect(formatDistance(0.9999)).toBe('1000m');
});
it('formats distances at or above 1km with one decimal', () => {
expect(formatDistance(1)).toBe('1.0km');
expect(formatDistance(1.5)).toBe('1.5km');
expect(formatDistance(12.34)).toBe('12.3km');
expect(formatDistance(100)).toBe('100.0km');
});
it('rounds meters to nearest integer', () => {
expect(formatDistance(0.4567)).toBe('457m');
expect(formatDistance(0.001)).toBe('1m');
});
});
+65 -1
View File
@@ -6,7 +6,7 @@
*/
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { parseHashConversation, getConversationHash } from '../utils/urlHash';
import { parseHashConversation, getConversationHash, getMapFocusHash } from '../utils/urlHash';
import type { Conversation } from '../types';
describe('parseHashConversation', () => {
@@ -36,6 +36,38 @@ describe('parseHashConversation', () => {
expect(result).toEqual({ type: 'raw', name: 'raw' });
});
it('parses #map as map type', () => {
window.location.hash = '#map';
const result = parseHashConversation();
expect(result).toEqual({ type: 'map', name: 'map' });
});
it('parses #map/focus/PUBKEY with focus key', () => {
window.location.hash = '#map/focus/ABCD1234';
const result = parseHashConversation();
expect(result).toEqual({ type: 'map', name: 'map', mapFocusKey: 'ABCD1234' });
});
it('parses #map/focus/ with empty focus as plain map', () => {
window.location.hash = '#map/focus/';
const result = parseHashConversation();
expect(result).toEqual({ type: 'map', name: 'map' });
});
it('decodes URL-encoded map focus key', () => {
window.location.hash = '#map/focus/AB%20CD';
const result = parseHashConversation();
expect(result).toEqual({ type: 'map', name: 'map', mapFocusKey: 'AB CD' });
});
it('parses channel hash', () => {
window.location.hash = '#channel/Public';
@@ -108,6 +140,14 @@ describe('getConversationHash', () => {
expect(result).toBe('#raw');
});
it('returns #map for map conversation', () => {
const conv: Conversation = { type: 'map', id: 'map', name: 'Node Map' };
const result = getConversationHash(conv);
expect(result).toBe('#map');
});
it('generates channel hash', () => {
const conv: Conversation = { type: 'channel', id: 'key123', name: 'Public' };
@@ -189,4 +229,28 @@ describe('parseHashConversation and getConversationHash roundtrip', () => {
expect(parsed).toEqual({ type: 'raw', name: 'raw' });
});
it('map roundtrip preserves type', () => {
const conv: Conversation = { type: 'map', id: 'map', name: 'Node Map' };
const hash = getConversationHash(conv);
window.location.hash = hash;
const parsed = parseHashConversation();
expect(parsed).toEqual({ type: 'map', name: 'map' });
});
});
describe('getMapFocusHash', () => {
it('generates hash with focus key', () => {
const result = getMapFocusHash('ABCD1234');
expect(result).toBe('#map/focus/ABCD1234');
});
it('encodes special characters in key', () => {
const result = getMapFocusHash('AB CD/12');
expect(result).toBe('#map/focus/AB%20CD%2F12');
});
});
+2
View File
@@ -98,6 +98,8 @@ export interface Conversation {
/** PublicKey for contacts, ChannelKey for channels, 'raw'/'map' for special views */
id: string;
name: string;
/** For map view: public key prefix to focus on */
mapFocusKey?: string;
}
export interface RawPacket {
+29 -1
View File
@@ -10,8 +10,16 @@ export interface PathHop {
export interface ResolvedPath {
sender: { name: string; prefix: string; lat: number | null; lon: number | null };
hops: PathHop[];
receiver: { name: string; prefix: string; lat: number | null; lon: number | null };
receiver: {
name: string;
prefix: string;
lat: number | null;
lon: number | null;
publicKey: string | null;
};
totalDistances: number[] | null; // Single-element array with sum of unambiguous distances
/** True if path has any gaps (unknown, ambiguous, or missing location hops) */
hasGaps: boolean;
}
export interface SenderInfo {
@@ -101,6 +109,16 @@ export function isValidLocation(lat: number | null, lon: number | null): boolean
return true;
}
/**
* Format distance in human-readable form (m or km)
*/
export function formatDistance(km: number): string {
if (km < 1) {
return `${Math.round(km * 1000)}m`;
}
return `${km.toFixed(1)}km`;
}
/**
* Sort contacts by distance from a reference point
* Contacts without location are placed at the end
@@ -164,6 +182,7 @@ export function resolvePath(
prefix: receiverPrefix,
lat: config?.lat ?? null,
lon: config?.lon ?? null,
publicKey: config?.public_key ?? null,
};
// Build hops
@@ -229,11 +248,20 @@ export function resolvePath(
// Calculate total distances (can be multiple if ambiguous)
const totalDistances = calculateTotalDistances(resolvedSender, hops, resolvedReceiver);
// Determine if path has any gaps (unknown, ambiguous, or missing location)
const hasGaps =
!isValidLocation(resolvedSender.lat, resolvedSender.lon) ||
!isValidLocation(resolvedReceiver.lat, resolvedReceiver.lon) ||
hops.some(
(hop) => hop.matches.length !== 1 || !isValidLocation(hop.matches[0].lat, hop.matches[0].lon)
);
return {
sender: resolvedSender,
hops,
receiver: resolvedReceiver,
totalDistances,
hasGaps,
};
}
+20 -1
View File
@@ -3,9 +3,11 @@ import type { Conversation } from '../types';
export interface ParsedHashConversation {
type: 'channel' | 'contact' | 'raw' | 'map';
name: string;
/** For map view: public key prefix to focus on */
mapFocusKey?: string;
}
// Parse URL hash to get conversation (e.g., #channel/Public or #contact/JohnDoe or #raw)
// Parse URL hash to get conversation (e.g., #channel/Public or #contact/JohnDoe or #raw or #map/focus/ABCD1234)
export function parseHashConversation(): ParsedHashConversation | null {
const hash = window.location.hash.slice(1); // Remove leading #
if (!hash) return null;
@@ -18,6 +20,15 @@ export function parseHashConversation(): ParsedHashConversation | null {
return { type: 'map', name: 'map' };
}
// Check for map with focus: #map/focus/{pubkey_prefix}
if (hash.startsWith('map/focus/')) {
const focusKey = hash.slice('map/focus/'.length);
if (focusKey) {
return { type: 'map', name: 'map', mapFocusKey: decodeURIComponent(focusKey) };
}
return { type: 'map', name: 'map' };
}
const slashIndex = hash.indexOf('/');
if (slashIndex === -1) return null;
@@ -30,6 +41,14 @@ export function parseHashConversation(): ParsedHashConversation | null {
return null;
}
/**
* Generate a URL hash for focusing on a contact in the map view
* @param publicKeyPrefix - The public key or prefix to focus on
*/
export function getMapFocusHash(publicKeyPrefix: string): string {
return `#map/focus/${encodeURIComponent(publicKeyPrefix)}`;
}
// Generate URL hash from conversation
export function getConversationHash(conv: Conversation | null): string {
if (!conv) return '';