diff --git a/plans/switch from auto docking to assisted manual docking.md b/plans/switch from auto docking to assisted manual docking.md new file mode 100644 index 00000000..166dd330 --- /dev/null +++ b/plans/switch from auto docking to assisted manual docking.md @@ -0,0 +1,11 @@ +- roombas are worn out, cant dock themselves anymore using seek dock +- completely redesign the user facing docking process + - get rid of the auto dock instructions + - replace it with a flow for manual docking mode: + - does a little explanation + - line up your round front sensor with the sensor on the dock + - maybe show a video or an image in the HUD to assist + - plays a song on the roomba to indicate that "docking mode" has been entered even though its all client side. + - forces the camera to look all the way down so people can see their round front sensor + - limits movement speed to be very slow to help people be more precise +- MAYBE try some computer vision stuff that runs server-side and guides people? sounds hard and slow and not worth it. \ No newline at end of file diff --git a/server/public/assets/index-BGI3M6ER.js b/server/public/assets/index-BGI3M6ER.js deleted file mode 100644 index 27d15374..00000000 --- a/server/public/assets/index-BGI3M6ER.js +++ /dev/null @@ -1,131 +0,0 @@ -(function(){const a=document.createElement("link").relList;if(a&&a.supports&&a.supports("modulepreload"))return;for(const u of document.querySelectorAll('link[rel="modulepreload"]'))o(u);new MutationObserver(u=>{for(const f of u)if(f.type==="childList")for(const p of f.addedNodes)p.tagName==="LINK"&&p.rel==="modulepreload"&&o(p)}).observe(document,{childList:!0,subtree:!0});function r(u){const f={};return u.integrity&&(f.integrity=u.integrity),u.referrerPolicy&&(f.referrerPolicy=u.referrerPolicy),u.crossOrigin==="use-credentials"?f.credentials="include":u.crossOrigin==="anonymous"?f.credentials="omit":f.credentials="same-origin",f}function o(u){if(u.ep)return;u.ep=!0;const f=r(u);fetch(u.href,f)}})();function Ny(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}var Vu={exports:{}},Kl={};var p0;function wy(){if(p0)return Kl;p0=1;var n=Symbol.for("react.transitional.element"),a=Symbol.for("react.fragment");function r(o,u,f){var p=null;if(f!==void 0&&(p=""+f),u.key!==void 0&&(p=""+u.key),"key"in u){f={};for(var h in u)h!=="key"&&(f[h]=u[h])}else f=u;return u=f.ref,{$$typeof:n,type:o,key:p,ref:u!==void 0?u:null,props:f}}return Kl.Fragment=a,Kl.jsx=r,Kl.jsxs=r,Kl}var x0;function Ay(){return x0||(x0=1,Vu.exports=wy()),Vu.exports}var l=Ay(),$u={exports:{}},Ee={};var g0;function Cy(){if(g0)return Ee;g0=1;var n=Symbol.for("react.transitional.element"),a=Symbol.for("react.portal"),r=Symbol.for("react.fragment"),o=Symbol.for("react.strict_mode"),u=Symbol.for("react.profiler"),f=Symbol.for("react.consumer"),p=Symbol.for("react.context"),h=Symbol.for("react.forward_ref"),g=Symbol.for("react.suspense"),x=Symbol.for("react.memo"),v=Symbol.for("react.lazy"),b=Symbol.for("react.activity"),S=Symbol.iterator;function E(T){return T===null||typeof T!="object"?null:(T=S&&T[S]||T["@@iterator"],typeof T=="function"?T:null)}var R={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},N=Object.assign,w={};function j(T,D,X){this.props=T,this.context=D,this.refs=w,this.updater=X||R}j.prototype.isReactComponent={},j.prototype.setState=function(T,D){if(typeof T!="object"&&typeof T!="function"&&T!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,T,D,"setState")},j.prototype.forceUpdate=function(T){this.updater.enqueueForceUpdate(this,T,"forceUpdate")};function M(){}M.prototype=j.prototype;function k(T,D,X){this.props=T,this.context=D,this.refs=w,this.updater=X||R}var C=k.prototype=new M;C.constructor=k,N(C,j.prototype),C.isPureReactComponent=!0;var z=Array.isArray;function V(){}var q={H:null,A:null,T:null,S:null},B=Object.prototype.hasOwnProperty;function F(T,D,X){var se=X.ref;return{$$typeof:n,type:T,key:D,ref:se!==void 0?se:null,props:X}}function H(T,D){return F(T.type,D,T.props)}function $(T){return typeof T=="object"&&T!==null&&T.$$typeof===n}function P(T){var D={"=":"=0",":":"=2"};return"$"+T.replace(/[=:]/g,function(X){return D[X]})}var ue=/\/+/g;function ce(T,D){return typeof T=="object"&&T!==null&&T.key!=null?P(""+T.key):D.toString(36)}function ee(T){switch(T.status){case"fulfilled":return T.value;case"rejected":throw T.reason;default:switch(typeof T.status=="string"?T.then(V,V):(T.status="pending",T.then(function(D){T.status==="pending"&&(T.status="fulfilled",T.value=D)},function(D){T.status==="pending"&&(T.status="rejected",T.reason=D)})),T.status){case"fulfilled":return T.value;case"rejected":throw T.reason}}throw T}function O(T,D,X,se,he){var de=typeof T;(de==="undefined"||de==="boolean")&&(T=null);var me=!1;if(T===null)me=!0;else switch(de){case"bigint":case"string":case"number":me=!0;break;case"object":switch(T.$$typeof){case n:case a:me=!0;break;case v:return me=T._init,O(me(T._payload),D,X,se,he)}}if(me)return he=he(T),me=se===""?"."+ce(T,0):se,z(he)?(X="",me!=null&&(X=me.replace(ue,"$&/")+"/"),O(he,D,X,"",function(xe){return xe})):he!=null&&($(he)&&(he=H(he,X+(he.key==null||T&&T.key===he.key?"":(""+he.key).replace(ue,"$&/")+"/")+me)),D.push(he)),1;me=0;var je=se===""?".":se+":";if(z(T))for(var ye=0;ye>>1,ie=O[J];if(0>>1;Ju(X,Q))seu(he,X)?(O[J]=he,O[se]=Q,J=se):(O[J]=X,O[D]=Q,J=D);else if(seu(he,Q))O[J]=he,O[se]=Q,J=se;else break e}}return K}function u(O,K){var Q=O.sortIndex-K.sortIndex;return Q!==0?Q:O.id-K.id}if(n.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var f=performance;n.unstable_now=function(){return f.now()}}else{var p=Date,h=p.now();n.unstable_now=function(){return p.now()-h}}var g=[],x=[],v=1,b=null,S=3,E=!1,R=!1,N=!1,w=!1,j=typeof setTimeout=="function"?setTimeout:null,M=typeof clearTimeout=="function"?clearTimeout:null,k=typeof setImmediate<"u"?setImmediate:null;function C(O){for(var K=r(x);K!==null;){if(K.callback===null)o(x);else if(K.startTime<=O)o(x),K.sortIndex=K.expirationTime,a(g,K);else break;K=r(x)}}function z(O){if(N=!1,C(O),!R)if(r(g)!==null)R=!0,V||(V=!0,P());else{var K=r(x);K!==null&&ee(z,K.startTime-O)}}var V=!1,q=-1,B=5,F=-1;function H(){return w?!0:!(n.unstable_now()-FO&&H());){var J=b.callback;if(typeof J=="function"){b.callback=null,S=b.priorityLevel;var ie=J(b.expirationTime<=O);if(O=n.unstable_now(),typeof ie=="function"){b.callback=ie,C(O),K=!0;break t}b===r(g)&&o(g),C(O)}else o(g);b=r(g)}if(b!==null)K=!0;else{var T=r(x);T!==null&&ee(z,T.startTime-O),K=!1}}break e}finally{b=null,S=Q,E=!1}K=void 0}}finally{K?P():V=!1}}}var P;if(typeof k=="function")P=function(){k($)};else if(typeof MessageChannel<"u"){var ue=new MessageChannel,ce=ue.port2;ue.port1.onmessage=$,P=function(){ce.postMessage(null)}}else P=function(){j($,0)};function ee(O,K){q=j(function(){O(n.unstable_now())},K)}n.unstable_IdlePriority=5,n.unstable_ImmediatePriority=1,n.unstable_LowPriority=4,n.unstable_NormalPriority=3,n.unstable_Profiling=null,n.unstable_UserBlockingPriority=2,n.unstable_cancelCallback=function(O){O.callback=null},n.unstable_forceFrameRate=function(O){0>O||125J?(O.sortIndex=Q,a(x,O),r(g)===null&&O===r(x)&&(N?(M(q),q=-1):N=!0,ee(z,Q-J))):(O.sortIndex=ie,a(g,O),R||E||(R=!0,V||(V=!0,P()))),O},n.unstable_shouldYield=H,n.unstable_wrapCallback=function(O){var K=S;return function(){var Q=S;S=K;try{return O.apply(this,arguments)}finally{S=Q}}}})(Fu)),Fu}var y0;function Ey(){return y0||(y0=1,Yu.exports=ky()),Yu.exports}var Iu={exports:{}},qt={};var S0;function Ry(){if(S0)return qt;S0=1;var n=Ld();function a(g){var x="https://react.dev/errors/"+g;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(a){console.error(a)}}return n(),Iu.exports=Ry(),Iu.exports}var N0;function Ty(){if(N0)return Zl;N0=1;var n=Ey(),a=Ld(),r=My();function o(e){var t="https://react.dev/errors/"+e;if(1ie||(e.current=J[ie],J[ie]=null,ie--)}function X(e,t){ie++,J[ie]=e.current,e.current=t}var se=T(null),he=T(null),de=T(null),me=T(null);function je(e,t){switch(X(de,t),X(he,e),X(se,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?zp(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=zp(t),e=Up(t,e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}D(se),X(se,e)}function ye(){D(se),D(he),D(de)}function xe(e){e.memoizedState!==null&&X(me,e);var t=se.current,s=Up(t,e.type);t!==s&&(X(he,e),X(se,s))}function De(e){he.current===e&&(D(se),D(he)),me.current===e&&(D(me),Fl._currentValue=Q)}var $e,Te;function Ie(e){if($e===void 0)try{throw Error()}catch(s){var t=s.stack.trim().match(/\n( *(at )?)/);$e=t&&t[1]||"",Te=-1)":-1c||_[i]!==Y[c]){var W=` -`+_[i].replace(" at new "," at ");return e.displayName&&W.includes("")&&(W=W.replace("",e.displayName)),W}while(1<=i&&0<=c);break}}}finally{Ge=!1,Error.prepareStackTrace=s}return(s=e?e.displayName||e.name:"")?Ie(s):""}function re(e,t){switch(e.tag){case 26:case 27:case 5:return Ie(e.type);case 16:return Ie("Lazy");case 13:return e.child!==t&&t!==null?Ie("Suspense Fallback"):Ie("Suspense");case 19:return Ie("SuspenseList");case 0:case 15:return jt(e.type,!1);case 11:return jt(e.type.render,!1);case 1:return jt(e.type,!0);case 31:return Ie("Activity");default:return""}}function ae(e){try{var t="",s=null;do t+=re(e,s),s=e,e=e.return;while(e);return t}catch(i){return` -Error generating stack: `+i.message+` -`+i.stack}}var be=Object.prototype.hasOwnProperty,pe=n.unstable_scheduleCallback,Ne=n.unstable_cancelCallback,ge=n.unstable_shouldYield,et=n.unstable_requestPaint,le=n.unstable_now,fe=n.unstable_getCurrentPriorityLevel,qe=n.unstable_ImmediatePriority,Dt=n.unstable_UserBlockingPriority,Tt=n.unstable_NormalPriority,na=n.unstable_LowPriority,en=n.unstable_IdlePriority,Ae=n.log,nt=n.unstable_setDisableYieldValue,Xe=null,ke=null;function Be(e){if(typeof Ae=="function"&&nt(e),ke&&typeof ke.setStrictMode=="function")try{ke.setStrictMode(Xe,e)}catch{}}var rt=Math.clz32?Math.clz32:bt,Rs=Math.log,sa=Math.LN2;function bt(e){return e>>>=0,e===0?32:31-(Rs(e)/sa|0)|0}var jn=256,Nr=262144,wr=4194304;function Ms(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function Ar(e,t,s){var i=e.pendingLanes;if(i===0)return 0;var c=0,d=e.suspendedLanes,y=e.pingedLanes;e=e.warmLanes;var A=i&134217727;return A!==0?(i=A&~d,i!==0?c=Ms(i):(y&=A,y!==0?c=Ms(y):s||(s=A&~e,s!==0&&(c=Ms(s))))):(A=i&~d,A!==0?c=Ms(A):y!==0?c=Ms(y):s||(s=i&~e,s!==0&&(c=Ms(s)))),c===0?0:t!==0&&t!==c&&(t&d)===0&&(d=c&-c,s=t&-t,d>=s||d===32&&(s&4194048)!==0)?t:c}function al(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function uv(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function bf(){var e=wr;return wr<<=1,(wr&62914560)===0&&(wr=4194304),e}function Ro(e){for(var t=[],s=0;31>s;s++)t.push(e);return t}function ll(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function dv(e,t,s,i,c,d){var y=e.pendingLanes;e.pendingLanes=s,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=s,e.entangledLanes&=s,e.errorRecoveryDisabledLanes&=s,e.shellSuspendCounter=0;var A=e.entanglements,_=e.expirationTimes,Y=e.hiddenUpdates;for(s=y&~s;0"u")return null;try{return e.activeElement||e.body}catch{return e.body}}var gv=/[\n"\\]/g;function nn(e){return e.replace(gv,function(t){return"\\"+t.charCodeAt(0).toString(16)+" "})}function Oo(e,t,s,i,c,d,y,A){e.name="",y!=null&&typeof y!="function"&&typeof y!="symbol"&&typeof y!="boolean"?e.type=y:e.removeAttribute("type"),t!=null?y==="number"?(t===0&&e.value===""||e.value!=t)&&(e.value=""+tn(t)):e.value!==""+tn(t)&&(e.value=""+tn(t)):y!=="submit"&&y!=="reset"||e.removeAttribute("value"),t!=null?Bo(e,y,tn(t)):s!=null?Bo(e,y,tn(s)):i!=null&&e.removeAttribute("value"),c==null&&d!=null&&(e.defaultChecked=!!d),c!=null&&(e.checked=c&&typeof c!="function"&&typeof c!="symbol"),A!=null&&typeof A!="function"&&typeof A!="symbol"&&typeof A!="boolean"?e.name=""+tn(A):e.removeAttribute("name")}function qf(e,t,s,i,c,d,y,A){if(d!=null&&typeof d!="function"&&typeof d!="symbol"&&typeof d!="boolean"&&(e.type=d),t!=null||s!=null){if(!(d!=="submit"&&d!=="reset"||t!=null)){_o(e);return}s=s!=null?""+tn(s):"",t=t!=null?""+tn(t):s,A||t===e.value||(e.value=t),e.defaultValue=t}i=i??c,i=typeof i!="function"&&typeof i!="symbol"&&!!i,e.checked=A?e.checked:!!i,e.defaultChecked=!!i,y!=null&&typeof y!="function"&&typeof y!="symbol"&&typeof y!="boolean"&&(e.name=y),_o(e)}function Bo(e,t,s){t==="number"&&Er(e.ownerDocument)===e||e.defaultValue===""+s||(e.defaultValue=""+s)}function ca(e,t,s,i){if(e=e.options,t){t={};for(var c=0;c"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Vo=!1;if(Dn)try{var cl={};Object.defineProperty(cl,"passive",{get:function(){Vo=!0}}),window.addEventListener("test",cl,cl),window.removeEventListener("test",cl,cl)}catch{Vo=!1}var as=null,$o=null,Mr=null;function Uf(){if(Mr)return Mr;var e,t=$o,s=t.length,i,c="value"in as?as.value:as.textContent,d=c.length;for(e=0;e=fl),Ff=" ",If=!1;function Qf(e,t){switch(e){case"keyup":return Fv.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Xf(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var ma=!1;function Qv(e,t){switch(e){case"compositionend":return Xf(t);case"keypress":return t.which!==32?null:(If=!0,Ff);case"textInput":return e=t.data,e===Ff&&If?null:e;default:return null}}function Xv(e,t){if(ma)return e==="compositionend"||!Qo&&Qf(e,t)?(e=Uf(),Mr=$o=as=null,ma=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:s,offset:t-e};e=i}e:{for(;s;){if(s.nextSibling){s=s.nextSibling;break e}s=s.parentNode}s=void 0}s=nm(s)}}function am(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?am(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function lm(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Er(e.document);t instanceof e.HTMLIFrameElement;){try{var s=typeof t.contentWindow.location.href=="string"}catch{s=!1}if(s)e=t.contentWindow;else break;t=Er(e.document)}return t}function Zo(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}var nb=Dn&&"documentMode"in document&&11>=document.documentMode,ha=null,Jo=null,xl=null,Po=!1;function rm(e,t,s){var i=s.window===s?s.document:s.nodeType===9?s:s.ownerDocument;Po||ha==null||ha!==Er(i)||(i=ha,"selectionStart"in i&&Zo(i)?i={start:i.selectionStart,end:i.selectionEnd}:(i=(i.ownerDocument&&i.ownerDocument.defaultView||window).getSelection(),i={anchorNode:i.anchorNode,anchorOffset:i.anchorOffset,focusNode:i.focusNode,focusOffset:i.focusOffset}),xl&&pl(xl,i)||(xl=i,i=Ni(Jo,"onSelect"),0>=y,c-=y,Nn=1<<32-rt(t)+c|s<Me?(ze=Se,Se=null):ze=Se.sibling;var Fe=I(U,Se,G[Me],te);if(Fe===null){Se===null&&(Se=ze);break}e&&Se&&Fe.alternate===null&&t(U,Se),L=d(Fe,L,Me),Ye===null?we=Fe:Ye.sibling=Fe,Ye=Fe,Se=ze}if(Me===G.length)return s(U,Se),Ue&&On(U,Me),we;if(Se===null){for(;MeMe?(ze=Se,Se=null):ze=Se.sibling;var Cs=I(U,Se,Fe.value,te);if(Cs===null){Se===null&&(Se=ze);break}e&&Se&&Cs.alternate===null&&t(U,Se),L=d(Cs,L,Me),Ye===null?we=Cs:Ye.sibling=Cs,Ye=Cs,Se=ze}if(Fe.done)return s(U,Se),Ue&&On(U,Me),we;if(Se===null){for(;!Fe.done;Me++,Fe=G.next())Fe=ne(U,Fe.value,te),Fe!==null&&(L=d(Fe,L,Me),Ye===null?we=Fe:Ye.sibling=Fe,Ye=Fe);return Ue&&On(U,Me),we}for(Se=i(Se);!Fe.done;Me++,Fe=G.next())Fe=Z(Se,U,Me,Fe.value,te),Fe!==null&&(e&&Fe.alternate!==null&&Se.delete(Fe.key===null?Me:Fe.key),L=d(Fe,L,Me),Ye===null?we=Fe:Ye.sibling=Fe,Ye=Fe);return e&&Se.forEach(function(jy){return t(U,jy)}),Ue&&On(U,Me),we}function We(U,L,G,te){if(typeof G=="object"&&G!==null&&G.type===N&&G.key===null&&(G=G.props.children),typeof G=="object"&&G!==null){switch(G.$$typeof){case E:e:{for(var we=G.key;L!==null;){if(L.key===we){if(we=G.type,we===N){if(L.tag===7){s(U,L.sibling),te=c(L,G.props.children),te.return=U,U=te;break e}}else if(L.elementType===we||typeof we=="object"&&we!==null&&we.$$typeof===B&&Vs(we)===L.type){s(U,L.sibling),te=c(L,G.props),jl(te,G),te.return=U,U=te;break e}s(U,L);break}else t(U,L);L=L.sibling}G.type===N?(te=Bs(G.props.children,U.mode,te,G.key),te.return=U,U=te):(te=Hr(G.type,G.key,G.props,null,U.mode,te),jl(te,G),te.return=U,U=te)}return y(U);case R:e:{for(we=G.key;L!==null;){if(L.key===we)if(L.tag===4&&L.stateNode.containerInfo===G.containerInfo&&L.stateNode.implementation===G.implementation){s(U,L.sibling),te=c(L,G.children||[]),te.return=U,U=te;break e}else{s(U,L);break}else t(U,L);L=L.sibling}te=lc(G,U.mode,te),te.return=U,U=te}return y(U);case B:return G=Vs(G),We(U,L,G,te)}if(ee(G))return ve(U,L,G,te);if(P(G)){if(we=P(G),typeof we!="function")throw Error(o(150));return G=we.call(G),Ce(U,L,G,te)}if(typeof G.then=="function")return We(U,L,Qr(G),te);if(G.$$typeof===k)return We(U,L,Gr(U,G),te);Xr(U,G)}return typeof G=="string"&&G!==""||typeof G=="number"||typeof G=="bigint"?(G=""+G,L!==null&&L.tag===6?(s(U,L.sibling),te=c(L,G),te.return=U,U=te):(s(U,L),te=ac(G,U.mode,te),te.return=U,U=te),y(U)):s(U,L)}return function(U,L,G,te){try{Sl=0;var we=We(U,L,G,te);return Aa=null,we}catch(Se){if(Se===wa||Se===Fr)throw Se;var Ye=Ft(29,Se,null,U.mode);return Ye.lanes=te,Ye.return=U,Ye}finally{}}}var Gs=Rm(!0),Mm=Rm(!1),cs=!1;function gc(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function vc(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function us(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function ds(e,t,s){var i=e.updateQueue;if(i===null)return null;if(i=i.shared,(Qe&2)!==0){var c=i.pending;return c===null?t.next=t:(t.next=c.next,c.next=t),i.pending=t,t=Ur(e),mm(e,null,s),t}return zr(e,i,t,s),Ur(e)}function Nl(e,t,s){if(t=t.updateQueue,t!==null&&(t=t.shared,(s&4194048)!==0)){var i=t.lanes;i&=e.pendingLanes,s|=i,t.lanes=s,Sf(e,s)}}function bc(e,t){var s=e.updateQueue,i=e.alternate;if(i!==null&&(i=i.updateQueue,s===i)){var c=null,d=null;if(s=s.firstBaseUpdate,s!==null){do{var y={lane:s.lane,tag:s.tag,payload:s.payload,callback:null,next:null};d===null?c=d=y:d=d.next=y,s=s.next}while(s!==null);d===null?c=d=t:d=d.next=t}else c=d=t;s={baseState:i.baseState,firstBaseUpdate:c,lastBaseUpdate:d,shared:i.shared,callbacks:i.callbacks},e.updateQueue=s;return}e=s.lastBaseUpdate,e===null?s.firstBaseUpdate=t:e.next=t,s.lastBaseUpdate=t}var yc=!1;function wl(){if(yc){var e=Na;if(e!==null)throw e}}function Al(e,t,s,i){yc=!1;var c=e.updateQueue;cs=!1;var d=c.firstBaseUpdate,y=c.lastBaseUpdate,A=c.shared.pending;if(A!==null){c.shared.pending=null;var _=A,Y=_.next;_.next=null,y===null?d=Y:y.next=Y,y=_;var W=e.alternate;W!==null&&(W=W.updateQueue,A=W.lastBaseUpdate,A!==y&&(A===null?W.firstBaseUpdate=Y:A.next=Y,W.lastBaseUpdate=_))}if(d!==null){var ne=c.baseState;y=0,W=Y=_=null,A=d;do{var I=A.lane&-536870913,Z=I!==A.lane;if(Z?(Le&I)===I:(i&I)===I){I!==0&&I===ja&&(yc=!0),W!==null&&(W=W.next={lane:0,tag:A.tag,payload:A.payload,callback:null,next:null});e:{var ve=e,Ce=A;I=t;var We=s;switch(Ce.tag){case 1:if(ve=Ce.payload,typeof ve=="function"){ne=ve.call(We,ne,I);break e}ne=ve;break e;case 3:ve.flags=ve.flags&-65537|128;case 0:if(ve=Ce.payload,I=typeof ve=="function"?ve.call(We,ne,I):ve,I==null)break e;ne=b({},ne,I);break e;case 2:cs=!0}}I=A.callback,I!==null&&(e.flags|=64,Z&&(e.flags|=8192),Z=c.callbacks,Z===null?c.callbacks=[I]:Z.push(I))}else Z={lane:I,tag:A.tag,payload:A.payload,callback:A.callback,next:null},W===null?(Y=W=Z,_=ne):W=W.next=Z,y|=I;if(A=A.next,A===null){if(A=c.shared.pending,A===null)break;Z=A,A=Z.next,Z.next=null,c.lastBaseUpdate=Z,c.shared.pending=null}}while(!0);W===null&&(_=ne),c.baseState=_,c.firstBaseUpdate=Y,c.lastBaseUpdate=W,d===null&&(c.shared.lanes=0),xs|=y,e.lanes=y,e.memoizedState=ne}}function Tm(e,t){if(typeof e!="function")throw Error(o(191,e));e.call(t)}function qm(e,t){var s=e.callbacks;if(s!==null)for(e.callbacks=null,e=0;ed?d:8;var y=O.T,A={};O.T=A,Uc(e,!1,t,s);try{var _=c(),Y=O.S;if(Y!==null&&Y(A,_),_!==null&&typeof _=="object"&&typeof _.then=="function"){var W=db(_,i);El(e,t,W,Zt(e))}else El(e,t,i,Zt(e))}catch(ne){El(e,t,{then:function(){},status:"rejected",reason:ne},Zt())}finally{K.p=d,y!==null&&A.types!==null&&(y.types=A.types),O.T=y}}function gb(){}function Lc(e,t,s,i){if(e.tag!==5)throw Error(o(476));var c=uh(e).queue;ch(e,c,t,Q,s===null?gb:function(){return dh(e),s(i)})}function uh(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:Q,baseState:Q,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Un,lastRenderedState:Q},next:null};var s={};return t.next={memoizedState:s,baseState:s,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Un,lastRenderedState:s},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function dh(e){var t=uh(e);t.next===null&&(t=e.alternate.memoizedState),El(e,t.next.queue,{},Zt())}function zc(){return kt(Fl)}function fh(){return mt().memoizedState}function mh(){return mt().memoizedState}function vb(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var s=Zt();e=us(s);var i=ds(t,e,s);i!==null&&($t(i,t,s),Nl(i,t,s)),t={cache:mc()},e.payload=t;return}t=t.return}}function bb(e,t,s){var i=Zt();s={lane:i,revertLane:0,gesture:null,action:s,hasEagerState:!1,eagerState:null,next:null},ai(e)?ph(t,s):(s=nc(e,t,s,i),s!==null&&($t(s,e,i),xh(s,t,i)))}function hh(e,t,s){var i=Zt();El(e,t,s,i)}function El(e,t,s,i){var c={lane:i,revertLane:0,gesture:null,action:s,hasEagerState:!1,eagerState:null,next:null};if(ai(e))ph(t,c);else{var d=e.alternate;if(e.lanes===0&&(d===null||d.lanes===0)&&(d=t.lastRenderedReducer,d!==null))try{var y=t.lastRenderedState,A=d(y,s);if(c.hasEagerState=!0,c.eagerState=A,Yt(A,y))return zr(e,t,c,0),tt===null&&Lr(),!1}catch{}finally{}if(s=nc(e,t,c,i),s!==null)return $t(s,e,i),xh(s,t,i),!0}return!1}function Uc(e,t,s,i){if(i={lane:2,revertLane:gu(),gesture:null,action:i,hasEagerState:!1,eagerState:null,next:null},ai(e)){if(t)throw Error(o(479))}else t=nc(e,s,i,2),t!==null&&$t(t,e,2)}function ai(e){var t=e.alternate;return e===Re||t!==null&&t===Re}function ph(e,t){ka=Jr=!0;var s=e.pending;s===null?t.next=t:(t.next=s.next,s.next=t),e.pending=t}function xh(e,t,s){if((s&4194048)!==0){var i=t.lanes;i&=e.pendingLanes,s|=i,t.lanes=s,Sf(e,s)}}var Rl={readContext:kt,use:ei,useCallback:ct,useContext:ct,useEffect:ct,useImperativeHandle:ct,useLayoutEffect:ct,useInsertionEffect:ct,useMemo:ct,useReducer:ct,useRef:ct,useState:ct,useDebugValue:ct,useDeferredValue:ct,useTransition:ct,useSyncExternalStore:ct,useId:ct,useHostTransitionStatus:ct,useFormState:ct,useActionState:ct,useOptimistic:ct,useMemoCache:ct,useCacheRefresh:ct};Rl.useEffectEvent=ct;var gh={readContext:kt,use:ei,useCallback:function(e,t){return _t().memoizedState=[e,t===void 0?null:t],e},useContext:kt,useEffect:eh,useImperativeHandle:function(e,t,s){s=s!=null?s.concat([e]):null,ni(4194308,4,ah.bind(null,t,e),s)},useLayoutEffect:function(e,t){return ni(4194308,4,e,t)},useInsertionEffect:function(e,t){ni(4,2,e,t)},useMemo:function(e,t){var s=_t();t=t===void 0?null:t;var i=e();if(Ys){Be(!0);try{e()}finally{Be(!1)}}return s.memoizedState=[i,t],i},useReducer:function(e,t,s){var i=_t();if(s!==void 0){var c=s(t);if(Ys){Be(!0);try{s(t)}finally{Be(!1)}}}else c=t;return i.memoizedState=i.baseState=c,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:c},i.queue=e,e=e.dispatch=bb.bind(null,Re,e),[i.memoizedState,e]},useRef:function(e){var t=_t();return e={current:e},t.memoizedState=e},useState:function(e){e=qc(e);var t=e.queue,s=hh.bind(null,Re,t);return t.dispatch=s,[e.memoizedState,s]},useDebugValue:Oc,useDeferredValue:function(e,t){var s=_t();return Bc(s,e,t)},useTransition:function(){var e=qc(!1);return e=ch.bind(null,Re,e.queue,!0,!1),_t().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,s){var i=Re,c=_t();if(Ue){if(s===void 0)throw Error(o(407));s=s()}else{if(s=t(),tt===null)throw Error(o(349));(Le&127)!==0||zm(i,t,s)}c.memoizedState=s;var d={value:s,getSnapshot:t};return c.queue=d,eh(Hm.bind(null,i,d,e),[e]),i.flags|=2048,Ra(9,{destroy:void 0},Um.bind(null,i,d,s,t),null),s},useId:function(){var e=_t(),t=tt.identifierPrefix;if(Ue){var s=wn,i=Nn;s=(i&~(1<<32-rt(i)-1)).toString(32)+s,t="_"+t+"R_"+s,s=Pr++,0<\/script>",d=d.removeChild(d.firstChild);break;case"select":d=typeof i.is=="string"?y.createElement("select",{is:i.is}):y.createElement("select"),i.multiple?d.multiple=!0:i.size&&(d.size=i.size);break;default:d=typeof i.is=="string"?y.createElement(c,{is:i.is}):y.createElement(c)}}d[At]=t,d[Bt]=i;e:for(y=t.child;y!==null;){if(y.tag===5||y.tag===6)d.appendChild(y.stateNode);else if(y.tag!==4&&y.tag!==27&&y.child!==null){y.child.return=y,y=y.child;continue}if(y===t)break e;for(;y.sibling===null;){if(y.return===null||y.return===t)break e;y=y.return}y.sibling.return=y.return,y=y.sibling}t.stateNode=d;e:switch(Rt(d,c,i),c){case"button":case"input":case"select":case"textarea":i=!!i.autoFocus;break e;case"img":i=!0;break e;default:i=!1}i&&Vn(t)}}return at(t),Wc(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,s),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==i&&Vn(t);else{if(typeof i!="string"&&t.stateNode===null)throw Error(o(166));if(e=de.current,ya(t)){if(e=t.stateNode,s=t.memoizedProps,i=null,c=Ct,c!==null)switch(c.tag){case 27:case 5:i=c.memoizedProps}e[At]=t,e=!!(e.nodeValue===s||i!==null&&i.suppressHydrationWarning===!0||Bp(e.nodeValue,s)),e||is(t,!0)}else e=wi(e).createTextNode(i),e[At]=t,t.stateNode=e}return at(t),null;case 31:if(s=t.memoizedState,e===null||e.memoizedState!==null){if(i=ya(t),s!==null){if(e===null){if(!i)throw Error(o(318));if(e=t.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(o(557));e[At]=t}else Ls(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;at(t),e=!1}else s=cc(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=s),e=!0;if(!e)return t.flags&256?(Qt(t),t):(Qt(t),null);if((t.flags&128)!==0)throw Error(o(558))}return at(t),null;case 13:if(i=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(c=ya(t),i!==null&&i.dehydrated!==null){if(e===null){if(!c)throw Error(o(318));if(c=t.memoizedState,c=c!==null?c.dehydrated:null,!c)throw Error(o(317));c[At]=t}else Ls(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;at(t),c=!1}else c=cc(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=c),c=!0;if(!c)return t.flags&256?(Qt(t),t):(Qt(t),null)}return Qt(t),(t.flags&128)!==0?(t.lanes=s,t):(s=i!==null,e=e!==null&&e.memoizedState!==null,s&&(i=t.child,c=null,i.alternate!==null&&i.alternate.memoizedState!==null&&i.alternate.memoizedState.cachePool!==null&&(c=i.alternate.memoizedState.cachePool.pool),d=null,i.memoizedState!==null&&i.memoizedState.cachePool!==null&&(d=i.memoizedState.cachePool.pool),d!==c&&(i.flags|=2048)),s!==e&&s&&(t.child.flags|=8192),ci(t,t.updateQueue),at(t),null);case 4:return ye(),e===null&&Su(t.stateNode.containerInfo),at(t),null;case 10:return Ln(t.type),at(t),null;case 19:if(D(ft),i=t.memoizedState,i===null)return at(t),null;if(c=(t.flags&128)!==0,d=i.rendering,d===null)if(c)Tl(i,!1);else{if(ut!==0||e!==null&&(e.flags&128)!==0)for(e=t.child;e!==null;){if(d=Zr(e),d!==null){for(t.flags|=128,Tl(i,!1),e=d.updateQueue,t.updateQueue=e,ci(t,e),t.subtreeFlags=0,e=s,s=t.child;s!==null;)hm(s,e),s=s.sibling;return X(ft,ft.current&1|2),Ue&&On(t,i.treeForkCount),t.child}e=e.sibling}i.tail!==null&&le()>hi&&(t.flags|=128,c=!0,Tl(i,!1),t.lanes=4194304)}else{if(!c)if(e=Zr(d),e!==null){if(t.flags|=128,c=!0,e=e.updateQueue,t.updateQueue=e,ci(t,e),Tl(i,!0),i.tail===null&&i.tailMode==="hidden"&&!d.alternate&&!Ue)return at(t),null}else 2*le()-i.renderingStartTime>hi&&s!==536870912&&(t.flags|=128,c=!0,Tl(i,!1),t.lanes=4194304);i.isBackwards?(d.sibling=t.child,t.child=d):(e=i.last,e!==null?e.sibling=d:t.child=d,i.last=d)}return i.tail!==null?(e=i.tail,i.rendering=e,i.tail=e.sibling,i.renderingStartTime=le(),e.sibling=null,s=ft.current,X(ft,c?s&1|2:s&1),Ue&&On(t,i.treeForkCount),e):(at(t),null);case 22:case 23:return Qt(t),jc(),i=t.memoizedState!==null,e!==null?e.memoizedState!==null!==i&&(t.flags|=8192):i&&(t.flags|=8192),i?(s&536870912)!==0&&(t.flags&128)===0&&(at(t),t.subtreeFlags&6&&(t.flags|=8192)):at(t),s=t.updateQueue,s!==null&&ci(t,s.retryQueue),s=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(s=e.memoizedState.cachePool.pool),i=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(i=t.memoizedState.cachePool.pool),i!==s&&(t.flags|=2048),e!==null&&D(Hs),null;case 24:return s=null,e!==null&&(s=e.memoizedState.cache),t.memoizedState.cache!==s&&(t.flags|=2048),Ln(ht),at(t),null;case 25:return null;case 30:return null}throw Error(o(156,t.tag))}function wb(e,t){switch(ic(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Ln(ht),ye(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return De(t),null;case 31:if(t.memoizedState!==null){if(Qt(t),t.alternate===null)throw Error(o(340));Ls()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(Qt(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(o(340));Ls()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return D(ft),null;case 4:return ye(),null;case 10:return Ln(t.type),null;case 22:case 23:return Qt(t),jc(),e!==null&&D(Hs),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Ln(ht),null;case 25:return null;default:return null}}function Vh(e,t){switch(ic(t),t.tag){case 3:Ln(ht),ye();break;case 26:case 27:case 5:De(t);break;case 4:ye();break;case 31:t.memoizedState!==null&&Qt(t);break;case 13:Qt(t);break;case 19:D(ft);break;case 10:Ln(t.type);break;case 22:case 23:Qt(t),jc(),e!==null&&D(Hs);break;case 24:Ln(ht)}}function ql(e,t){try{var s=t.updateQueue,i=s!==null?s.lastEffect:null;if(i!==null){var c=i.next;s=c;do{if((s.tag&e)===e){i=void 0;var d=s.create,y=s.inst;i=d(),y.destroy=i}s=s.next}while(s!==c)}}catch(A){Ze(t,t.return,A)}}function hs(e,t,s){try{var i=t.updateQueue,c=i!==null?i.lastEffect:null;if(c!==null){var d=c.next;i=d;do{if((i.tag&e)===e){var y=i.inst,A=y.destroy;if(A!==void 0){y.destroy=void 0,c=t;var _=s,Y=A;try{Y()}catch(W){Ze(c,_,W)}}}i=i.next}while(i!==d)}}catch(W){Ze(t,t.return,W)}}function $h(e){var t=e.updateQueue;if(t!==null){var s=e.stateNode;try{qm(t,s)}catch(i){Ze(e,e.return,i)}}}function Gh(e,t,s){s.props=Fs(e.type,e.memoizedProps),s.state=e.memoizedState;try{s.componentWillUnmount()}catch(i){Ze(e,t,i)}}function Dl(e,t){try{var s=e.ref;if(s!==null){switch(e.tag){case 26:case 27:case 5:var i=e.stateNode;break;case 30:i=e.stateNode;break;default:i=e.stateNode}typeof s=="function"?e.refCleanup=s(i):s.current=i}}catch(c){Ze(e,t,c)}}function An(e,t){var s=e.ref,i=e.refCleanup;if(s!==null)if(typeof i=="function")try{i()}catch(c){Ze(e,t,c)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof s=="function")try{s(null)}catch(c){Ze(e,t,c)}else s.current=null}function Yh(e){var t=e.type,s=e.memoizedProps,i=e.stateNode;try{e:switch(t){case"button":case"input":case"select":case"textarea":s.autoFocus&&i.focus();break e;case"img":s.src?i.src=s.src:s.srcSet&&(i.srcset=s.srcSet)}}catch(c){Ze(e,e.return,c)}}function eu(e,t,s){try{var i=e.stateNode;Ib(i,e.type,s,t),i[Bt]=t}catch(c){Ze(e,e.return,c)}}function Fh(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Ss(e.type)||e.tag===4}function tu(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Fh(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&Ss(e.type)||e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function nu(e,t,s){var i=e.tag;if(i===5||i===6)e=e.stateNode,t?(s.nodeType===9?s.body:s.nodeName==="HTML"?s.ownerDocument.body:s).insertBefore(e,t):(t=s.nodeType===9?s.body:s.nodeName==="HTML"?s.ownerDocument.body:s,t.appendChild(e),s=s._reactRootContainer,s!=null||t.onclick!==null||(t.onclick=qn));else if(i!==4&&(i===27&&Ss(e.type)&&(s=e.stateNode,t=null),e=e.child,e!==null))for(nu(e,t,s),e=e.sibling;e!==null;)nu(e,t,s),e=e.sibling}function ui(e,t,s){var i=e.tag;if(i===5||i===6)e=e.stateNode,t?s.insertBefore(e,t):s.appendChild(e);else if(i!==4&&(i===27&&Ss(e.type)&&(s=e.stateNode),e=e.child,e!==null))for(ui(e,t,s),e=e.sibling;e!==null;)ui(e,t,s),e=e.sibling}function Ih(e){var t=e.stateNode,s=e.memoizedProps;try{for(var i=e.type,c=t.attributes;c.length;)t.removeAttributeNode(c[0]);Rt(t,i,s),t[At]=e,t[Bt]=s}catch(d){Ze(e,e.return,d)}}var $n=!1,gt=!1,su=!1,Qh=typeof WeakSet=="function"?WeakSet:Set,wt=null;function Ab(e,t){if(e=e.containerInfo,wu=Ti,e=lm(e),Zo(e)){if("selectionStart"in e)var s={start:e.selectionStart,end:e.selectionEnd};else e:{s=(s=e.ownerDocument)&&s.defaultView||window;var i=s.getSelection&&s.getSelection();if(i&&i.rangeCount!==0){s=i.anchorNode;var c=i.anchorOffset,d=i.focusNode;i=i.focusOffset;try{s.nodeType,d.nodeType}catch{s=null;break e}var y=0,A=-1,_=-1,Y=0,W=0,ne=e,I=null;t:for(;;){for(var Z;ne!==s||c!==0&&ne.nodeType!==3||(A=y+c),ne!==d||i!==0&&ne.nodeType!==3||(_=y+i),ne.nodeType===3&&(y+=ne.nodeValue.length),(Z=ne.firstChild)!==null;)I=ne,ne=Z;for(;;){if(ne===e)break t;if(I===s&&++Y===c&&(A=y),I===d&&++W===i&&(_=y),(Z=ne.nextSibling)!==null)break;ne=I,I=ne.parentNode}ne=Z}s=A===-1||_===-1?null:{start:A,end:_}}else s=null}s=s||{start:0,end:0}}else s=null;for(Au={focusedElem:e,selectionRange:s},Ti=!1,wt=t;wt!==null;)if(t=wt,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,wt=e;else for(;wt!==null;){switch(t=wt,d=t.alternate,e=t.flags,t.tag){case 0:if((e&4)!==0&&(e=t.updateQueue,e=e!==null?e.events:null,e!==null))for(s=0;s title"))),Rt(d,i,s),d[At]=e,Nt(d),i=d;break e;case"link":var y=Wp("link","href",c).get(i+(s.href||""));if(y){for(var A=0;AWe&&(y=We,We=Ce,Ce=y);var U=sm(A,Ce),L=sm(A,We);if(U&&L&&(Z.rangeCount!==1||Z.anchorNode!==U.node||Z.anchorOffset!==U.offset||Z.focusNode!==L.node||Z.focusOffset!==L.offset)){var G=ne.createRange();G.setStart(U.node,U.offset),Z.removeAllRanges(),Ce>We?(Z.addRange(G),Z.extend(L.node,L.offset)):(G.setEnd(L.node,L.offset),Z.addRange(G))}}}}for(ne=[],Z=A;Z=Z.parentNode;)Z.nodeType===1&&ne.push({element:Z,left:Z.scrollLeft,top:Z.scrollTop});for(typeof A.focus=="function"&&A.focus(),A=0;As?32:s,O.T=null,s=uu,uu=null;var d=vs,y=Qn;if(yt=0,_a=vs=null,Qn=0,(Qe&6)!==0)throw Error(o(331));var A=Qe;if(Qe|=4,ap(d.current),tp(d,d.current,y,s),Qe=A,Ul(0,!1),ke&&typeof ke.onPostCommitFiberRoot=="function")try{ke.onPostCommitFiberRoot(Xe,d)}catch{}return!0}finally{K.p=c,O.T=i,jp(e,t)}}function wp(e,t,s){t=an(s,t),t=Gc(e.stateNode,t,2),e=ds(e,t,2),e!==null&&(ll(e,2),Cn(e))}function Ze(e,t,s){if(e.tag===3)wp(e,e,s);else for(;t!==null;){if(t.tag===3){wp(t,e,s);break}else if(t.tag===1){var i=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof i.componentDidCatch=="function"&&(gs===null||!gs.has(i))){e=an(s,e),s=Ah(2),i=ds(t,s,2),i!==null&&(Ch(s,i,t,e),ll(i,2),Cn(i));break}}t=t.return}}function hu(e,t,s){var i=e.pingCache;if(i===null){i=e.pingCache=new Eb;var c=new Set;i.set(t,c)}else c=i.get(t),c===void 0&&(c=new Set,i.set(t,c));c.has(s)||(ru=!0,c.add(s),e=Db.bind(null,e,t,s),t.then(e,e))}function Db(e,t,s){var i=e.pingCache;i!==null&&i.delete(t),e.pingedLanes|=e.suspendedLanes&s,e.warmLanes&=~s,tt===e&&(Le&s)===s&&(ut===4||ut===3&&(Le&62914560)===Le&&300>le()-mi?(Qe&2)===0&&Oa(e,0):iu|=s,Da===Le&&(Da=0)),Cn(e)}function Ap(e,t){t===0&&(t=bf()),e=Os(e,t),e!==null&&(ll(e,t),Cn(e))}function _b(e){var t=e.memoizedState,s=0;t!==null&&(s=t.retryLane),Ap(e,s)}function Ob(e,t){var s=0;switch(e.tag){case 31:case 13:var i=e.stateNode,c=e.memoizedState;c!==null&&(s=c.retryLane);break;case 19:i=e.stateNode;break;case 22:i=e.stateNode._retryCache;break;default:throw Error(o(314))}i!==null&&i.delete(t),Ap(e,s)}function Bb(e,t){return pe(e,t)}var yi=null,La=null,pu=!1,Si=!1,xu=!1,ys=0;function Cn(e){e!==La&&e.next===null&&(La===null?yi=La=e:La=La.next=e),Si=!0,pu||(pu=!0,zb())}function Ul(e,t){if(!xu&&Si){xu=!0;do for(var s=!1,i=yi;i!==null;){if(e!==0){var c=i.pendingLanes;if(c===0)var d=0;else{var y=i.suspendedLanes,A=i.pingedLanes;d=(1<<31-rt(42|e)+1)-1,d&=c&~(y&~A),d=d&201326741?d&201326741|1:d?d|2:0}d!==0&&(s=!0,Rp(i,d))}else d=Le,d=Ar(i,i===tt?d:0,i.cancelPendingCommit!==null||i.timeoutHandle!==-1),(d&3)===0||al(i,d)||(s=!0,Rp(i,d));i=i.next}while(s);xu=!1}}function Lb(){Cp()}function Cp(){Si=pu=!1;var e=0;ys!==0&&Xb()&&(e=ys);for(var t=le(),s=null,i=yi;i!==null;){var c=i.next,d=kp(i,t);d===0?(i.next=null,s===null?yi=c:s.next=c,c===null&&(La=s)):(s=i,(e!==0||(d&3)!==0)&&(Si=!0)),i=c}yt!==0&&yt!==5||Ul(e),ys!==0&&(ys=0)}function kp(e,t){for(var s=e.suspendedLanes,i=e.pingedLanes,c=e.expirationTimes,d=e.pendingLanes&-62914561;0A)break;var W=_.transferSize,ne=_.initiatorType;W&&Lp(ne)&&(_=_.responseEnd,y+=W*(_"u"?null:document;function Kp(e,t,s){var i=za;if(i&&typeof t=="string"&&t){var c=nn(t);c='link[rel="'+e+'"][href="'+c+'"]',typeof s=="string"&&(c+='[crossorigin="'+s+'"]'),Xp.has(c)||(Xp.add(c),e={rel:e,crossOrigin:s,href:t},i.querySelector(c)===null&&(t=i.createElement("link"),Rt(t,"link",e),Nt(t),i.head.appendChild(t)))}}function sy(e){Xn.D(e),Kp("dns-prefetch",e,null)}function ay(e,t){Xn.C(e,t),Kp("preconnect",e,t)}function ly(e,t,s){Xn.L(e,t,s);var i=za;if(i&&e&&t){var c='link[rel="preload"][as="'+nn(t)+'"]';t==="image"&&s&&s.imageSrcSet?(c+='[imagesrcset="'+nn(s.imageSrcSet)+'"]',typeof s.imageSizes=="string"&&(c+='[imagesizes="'+nn(s.imageSizes)+'"]')):c+='[href="'+nn(e)+'"]';var d=c;switch(t){case"style":d=Ua(e);break;case"script":d=Ha(e)}dn.has(d)||(e=b({rel:"preload",href:t==="image"&&s&&s.imageSrcSet?void 0:e,as:t},s),dn.set(d,e),i.querySelector(c)!==null||t==="style"&&i.querySelector(Gl(d))||t==="script"&&i.querySelector(Yl(d))||(t=i.createElement("link"),Rt(t,"link",e),Nt(t),i.head.appendChild(t)))}}function ry(e,t){Xn.m(e,t);var s=za;if(s&&e){var i=t&&typeof t.as=="string"?t.as:"script",c='link[rel="modulepreload"][as="'+nn(i)+'"][href="'+nn(e)+'"]',d=c;switch(i){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":d=Ha(e)}if(!dn.has(d)&&(e=b({rel:"modulepreload",href:e},t),dn.set(d,e),s.querySelector(c)===null)){switch(i){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(s.querySelector(Yl(d)))return}i=s.createElement("link"),Rt(i,"link",e),Nt(i),s.head.appendChild(i)}}}function iy(e,t,s){Xn.S(e,t,s);var i=za;if(i&&e){var c=ia(i).hoistableStyles,d=Ua(e);t=t||"default";var y=c.get(d);if(!y){var A={loading:0,preload:null};if(y=i.querySelector(Gl(d)))A.loading=5;else{e=b({rel:"stylesheet",href:e,"data-precedence":t},s),(s=dn.get(d))&&qu(e,s);var _=y=i.createElement("link");Nt(_),Rt(_,"link",e),_._p=new Promise(function(Y,W){_.onload=Y,_.onerror=W}),_.addEventListener("load",function(){A.loading|=1}),_.addEventListener("error",function(){A.loading|=2}),A.loading|=4,Ci(y,t,i)}y={type:"stylesheet",instance:y,count:1,state:A},c.set(d,y)}}}function oy(e,t){Xn.X(e,t);var s=za;if(s&&e){var i=ia(s).hoistableScripts,c=Ha(e),d=i.get(c);d||(d=s.querySelector(Yl(c)),d||(e=b({src:e,async:!0},t),(t=dn.get(c))&&Du(e,t),d=s.createElement("script"),Nt(d),Rt(d,"link",e),s.head.appendChild(d)),d={type:"script",instance:d,count:1,state:null},i.set(c,d))}}function cy(e,t){Xn.M(e,t);var s=za;if(s&&e){var i=ia(s).hoistableScripts,c=Ha(e),d=i.get(c);d||(d=s.querySelector(Yl(c)),d||(e=b({src:e,async:!0,type:"module"},t),(t=dn.get(c))&&Du(e,t),d=s.createElement("script"),Nt(d),Rt(d,"link",e),s.head.appendChild(d)),d={type:"script",instance:d,count:1,state:null},i.set(c,d))}}function Zp(e,t,s,i){var c=(c=de.current)?Ai(c):null;if(!c)throw Error(o(446));switch(e){case"meta":case"title":return null;case"style":return typeof s.precedence=="string"&&typeof s.href=="string"?(t=Ua(s.href),s=ia(c).hoistableStyles,i=s.get(t),i||(i={type:"style",instance:null,count:0,state:null},s.set(t,i)),i):{type:"void",instance:null,count:0,state:null};case"link":if(s.rel==="stylesheet"&&typeof s.href=="string"&&typeof s.precedence=="string"){e=Ua(s.href);var d=ia(c).hoistableStyles,y=d.get(e);if(y||(c=c.ownerDocument||c,y={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},d.set(e,y),(d=c.querySelector(Gl(e)))&&!d._p&&(y.instance=d,y.state.loading=5),dn.has(e)||(s={rel:"preload",as:"style",href:s.href,crossOrigin:s.crossOrigin,integrity:s.integrity,media:s.media,hrefLang:s.hrefLang,referrerPolicy:s.referrerPolicy},dn.set(e,s),d||uy(c,e,s,y.state))),t&&i===null)throw Error(o(528,""));return y}if(t&&i!==null)throw Error(o(529,""));return null;case"script":return t=s.async,s=s.src,typeof s=="string"&&t&&typeof t!="function"&&typeof t!="symbol"?(t=Ha(s),s=ia(c).hoistableScripts,i=s.get(t),i||(i={type:"script",instance:null,count:0,state:null},s.set(t,i)),i):{type:"void",instance:null,count:0,state:null};default:throw Error(o(444,e))}}function Ua(e){return'href="'+nn(e)+'"'}function Gl(e){return'link[rel="stylesheet"]['+e+"]"}function Jp(e){return b({},e,{"data-precedence":e.precedence,precedence:null})}function uy(e,t,s,i){e.querySelector('link[rel="preload"][as="style"]['+t+"]")?i.loading=1:(t=e.createElement("link"),i.preload=t,t.addEventListener("load",function(){return i.loading|=1}),t.addEventListener("error",function(){return i.loading|=2}),Rt(t,"link",s),Nt(t),e.head.appendChild(t))}function Ha(e){return'[src="'+nn(e)+'"]'}function Yl(e){return"script[async]"+e}function Pp(e,t,s){if(t.count++,t.instance===null)switch(t.type){case"style":var i=e.querySelector('style[data-href~="'+nn(s.href)+'"]');if(i)return t.instance=i,Nt(i),i;var c=b({},s,{"data-href":s.href,"data-precedence":s.precedence,href:null,precedence:null});return i=(e.ownerDocument||e).createElement("style"),Nt(i),Rt(i,"style",c),Ci(i,s.precedence,e),t.instance=i;case"stylesheet":c=Ua(s.href);var d=e.querySelector(Gl(c));if(d)return t.state.loading|=4,t.instance=d,Nt(d),d;i=Jp(s),(c=dn.get(c))&&qu(i,c),d=(e.ownerDocument||e).createElement("link"),Nt(d);var y=d;return y._p=new Promise(function(A,_){y.onload=A,y.onerror=_}),Rt(d,"link",i),t.state.loading|=4,Ci(d,s.precedence,e),t.instance=d;case"script":return d=Ha(s.src),(c=e.querySelector(Yl(d)))?(t.instance=c,Nt(c),c):(i=s,(c=dn.get(d))&&(i=b({},s),Du(i,c)),e=e.ownerDocument||e,c=e.createElement("script"),Nt(c),Rt(c,"link",i),e.head.appendChild(c),t.instance=c);case"void":return null;default:throw Error(o(443,t.type))}else t.type==="stylesheet"&&(t.state.loading&4)===0&&(i=t.instance,t.state.loading|=4,Ci(i,s.precedence,e));return t.instance}function Ci(e,t,s){for(var i=s.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),c=i.length?i[i.length-1]:null,d=c,y=0;y title"):null)}function dy(e,t,s){if(s===1||t.itemProp!=null)return!1;switch(e){case"meta":case"title":return!0;case"style":if(typeof t.precedence!="string"||typeof t.href!="string"||t.href==="")break;return!0;case"link":if(typeof t.rel!="string"||typeof t.href!="string"||t.href===""||t.onLoad||t.onError)break;switch(t.rel){case"stylesheet":return e=t.disabled,typeof t.precedence=="string"&&e==null;default:return!0}case"script":if(t.async&&typeof t.async!="function"&&typeof t.async!="symbol"&&!t.onLoad&&!t.onError&&t.src&&typeof t.src=="string")return!0}return!1}function t0(e){return!(e.type==="stylesheet"&&(e.state.loading&3)===0)}function fy(e,t,s,i){if(s.type==="stylesheet"&&(typeof i.media!="string"||matchMedia(i.media).matches!==!1)&&(s.state.loading&4)===0){if(s.instance===null){var c=Ua(i.href),d=t.querySelector(Gl(c));if(d){t=d._p,t!==null&&typeof t=="object"&&typeof t.then=="function"&&(e.count++,e=Ei.bind(e),t.then(e,e)),s.state.loading|=4,s.instance=d,Nt(d);return}d=t.ownerDocument||t,i=Jp(i),(c=dn.get(c))&&qu(i,c),d=d.createElement("link"),Nt(d);var y=d;y._p=new Promise(function(A,_){y.onload=A,y.onerror=_}),Rt(d,"link",i),s.instance=d}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(s,t),(t=s.state.preload)&&(s.state.loading&3)===0&&(e.count++,s=Ei.bind(e),t.addEventListener("load",s),t.addEventListener("error",s))}}var _u=0;function my(e,t){return e.stylesheets&&e.count===0&&Mi(e,e.stylesheets),0_u?50:800)+t);return e.unsuspend=s,function(){e.unsuspend=null,clearTimeout(i),clearTimeout(c)}}:null}function Ei(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Mi(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Ri=null;function Mi(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Ri=new Map,t.forEach(hy,e),Ri=null,Ei.call(e))}function hy(e,t){if(!(t.state.loading&4)){var s=Ri.get(e);if(s)var i=s.get(null);else{s=new Map,Ri.set(e,s);for(var c=e.querySelectorAll("link[data-precedence],style[data-precedence]"),d=0;d"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(a){console.error(a)}}return n(),Gu.exports=Ty(),Gu.exports}var Dy=qy();var A0="popstate";function _y(n={}){function a(o,u){let{pathname:f,search:p,hash:h}=o.location;return vd("",{pathname:f,search:p,hash:h},u.state&&u.state.usr||null,u.state&&u.state.key||"default")}function r(o,u){return typeof u=="string"?u:or(u)}return By(a,r,null,n)}function ot(n,a){if(n===!1||n===null||typeof n>"u")throw new Error(a)}function Sn(n,a){if(!n){typeof console<"u"&&console.warn(a);try{throw new Error(a)}catch{}}}function Oy(){return Math.random().toString(36).substring(2,10)}function C0(n,a){return{usr:n.state,key:n.key,idx:a}}function vd(n,a,r=null,o){return{pathname:typeof n=="string"?n:n.pathname,search:"",hash:"",...typeof a=="string"?tl(a):a,state:r,key:a&&a.key||o||Oy()}}function or({pathname:n="/",search:a="",hash:r=""}){return a&&a!=="?"&&(n+=a.charAt(0)==="?"?a:"?"+a),r&&r!=="#"&&(n+=r.charAt(0)==="#"?r:"#"+r),n}function tl(n){let a={};if(n){let r=n.indexOf("#");r>=0&&(a.hash=n.substring(r),n=n.substring(0,r));let o=n.indexOf("?");o>=0&&(a.search=n.substring(o),n=n.substring(0,o)),n&&(a.pathname=n)}return a}function By(n,a,r,o={}){let{window:u=document.defaultView,v5Compat:f=!1}=o,p=u.history,h="POP",g=null,x=v();x==null&&(x=0,p.replaceState({...p.state,idx:x},""));function v(){return(p.state||{idx:null}).idx}function b(){h="POP";let w=v(),j=w==null?null:w-x;x=w,g&&g({action:h,location:N.location,delta:j})}function S(w,j){h="PUSH";let M=vd(N.location,w,j);x=v()+1;let k=C0(M,x),C=N.createHref(M);try{p.pushState(k,"",C)}catch(z){if(z instanceof DOMException&&z.name==="DataCloneError")throw z;u.location.assign(C)}f&&g&&g({action:h,location:N.location,delta:1})}function E(w,j){h="REPLACE";let M=vd(N.location,w,j);x=v();let k=C0(M,x),C=N.createHref(M);p.replaceState(k,"",C),f&&g&&g({action:h,location:N.location,delta:0})}function R(w){return Ly(w)}let N={get action(){return h},get location(){return n(u,p)},listen(w){if(g)throw new Error("A history only accepts one active listener");return u.addEventListener(A0,b),g=w,()=>{u.removeEventListener(A0,b),g=null}},createHref(w){return a(u,w)},createURL:R,encodeLocation(w){let j=R(w);return{pathname:j.pathname,search:j.search,hash:j.hash}},push:S,replace:E,go(w){return p.go(w)}};return N}function Ly(n,a=!1){let r="http://localhost";typeof window<"u"&&(r=window.location.origin!=="null"?window.location.origin:window.location.href),ot(r,"No window.location.(origin|href) available to create URL");let o=typeof n=="string"?n:or(n);return o=o.replace(/ $/,"%20"),!a&&o.startsWith("//")&&(o=r+o),new URL(o,r)}function Mx(n,a,r="/"){return zy(n,a,r,!1)}function zy(n,a,r,o){let u=typeof a=="string"?tl(a):a,f=es(u.pathname||"/",r);if(f==null)return null;let p=Tx(n);Uy(p);let h=null;for(let g=0;h==null&&g{let v={relativePath:x===void 0?p.path||"":x,caseSensitive:p.caseSensitive===!0,childrenIndex:h,route:p};if(v.relativePath.startsWith("/")){if(!v.relativePath.startsWith(o)&&g)return;ot(v.relativePath.startsWith(o),`Absolute route path "${v.relativePath}" nested under path "${o}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),v.relativePath=v.relativePath.slice(o.length)}let b=Wn([o,v.relativePath]),S=r.concat(v);p.children&&p.children.length>0&&(ot(p.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${b}".`),Tx(p.children,a,S,b,g)),!(p.path==null&&!p.index)&&a.push({path:b,score:Iy(b,p.index),routesMeta:S})};return n.forEach((p,h)=>{if(p.path===""||!p.path?.includes("?"))f(p,h);else for(let g of qx(p.path))f(p,h,!0,g)}),a}function qx(n){let a=n.split("/");if(a.length===0)return[];let[r,...o]=a,u=r.endsWith("?"),f=r.replace(/\?$/,"");if(o.length===0)return u?[f,""]:[f];let p=qx(o.join("/")),h=[];return h.push(...p.map(g=>g===""?f:[f,g].join("/"))),u&&h.push(...p),h.map(g=>n.startsWith("/")&&g===""?"/":g)}function Uy(n){n.sort((a,r)=>a.score!==r.score?r.score-a.score:Qy(a.routesMeta.map(o=>o.childrenIndex),r.routesMeta.map(o=>o.childrenIndex)))}var Hy=/^:[\w-]+$/,Vy=3,$y=2,Gy=1,Yy=10,Fy=-2,k0=n=>n==="*";function Iy(n,a){let r=n.split("/"),o=r.length;return r.some(k0)&&(o+=Fy),a&&(o+=$y),r.filter(u=>!k0(u)).reduce((u,f)=>u+(Hy.test(f)?Vy:f===""?Gy:Yy),o)}function Qy(n,a){return n.length===a.length&&n.slice(0,-1).every((o,u)=>o===a[u])?n[n.length-1]-a[a.length-1]:0}function Xy(n,a,r=!1){let{routesMeta:o}=n,u={},f="/",p=[];for(let h=0;h{if(v==="*"){let R=h[S]||"";p=f.slice(0,f.length-R.length).replace(/(.)\/+$/,"$1")}const E=h[S];return b&&!E?x[v]=void 0:x[v]=(E||"").replace(/%2F/g,"/"),x},{}),pathname:f,pathnameBase:p,pattern:n}}function Ky(n,a=!1,r=!0){Sn(n==="*"||!n.endsWith("*")||n.endsWith("/*"),`Route path "${n}" will be treated as if it were "${n.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${n.replace(/\*$/,"/*")}".`);let o=[],u="^"+n.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(p,h,g)=>(o.push({paramName:h,isOptional:g!=null}),g?"/?([^\\/]+)?":"/([^\\/]+)")).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return n.endsWith("*")?(o.push({paramName:"*"}),u+=n==="*"||n==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):r?u+="\\/*$":n!==""&&n!=="/"&&(u+="(?:(?=\\/|$))"),[new RegExp(u,a?void 0:"i"),o]}function Zy(n){try{return n.split("/").map(a=>decodeURIComponent(a).replace(/\//g,"%2F")).join("/")}catch(a){return Sn(!1,`The URL path "${n}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${a}).`),n}}function es(n,a){if(a==="/")return n;if(!n.toLowerCase().startsWith(a.toLowerCase()))return null;let r=a.endsWith("/")?a.length-1:a.length,o=n.charAt(r);return o&&o!=="/"?null:n.slice(r)||"/"}var Jy=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Py=n=>Jy.test(n);function Wy(n,a="/"){let{pathname:r,search:o="",hash:u=""}=typeof n=="string"?tl(n):n,f;if(r)if(Py(r))f=r;else{if(r.includes("//")){let p=r;r=r.replace(/\/\/+/g,"/"),Sn(!1,`Pathnames cannot have embedded double slashes - normalizing ${p} -> ${r}`)}r.startsWith("/")?f=E0(r.substring(1),"/"):f=E0(r,a)}else f=a;return{pathname:f,search:n1(o),hash:s1(u)}}function E0(n,a){let r=a.replace(/\/+$/,"").split("/");return n.split("/").forEach(u=>{u===".."?r.length>1&&r.pop():u!=="."&&r.push(u)}),r.length>1?r.join("/"):"/"}function Qu(n,a,r,o){return`Cannot include a '${n}' character in a manually specified \`to.${a}\` field [${JSON.stringify(o)}]. Please separate it out to the \`to.${r}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function e1(n){return n.filter((a,r)=>r===0||a.route.path&&a.route.path.length>0)}function Dx(n){let a=e1(n);return a.map((r,o)=>o===a.length-1?r.pathname:r.pathnameBase)}function _x(n,a,r,o=!1){let u;typeof n=="string"?u=tl(n):(u={...n},ot(!u.pathname||!u.pathname.includes("?"),Qu("?","pathname","search",u)),ot(!u.pathname||!u.pathname.includes("#"),Qu("#","pathname","hash",u)),ot(!u.search||!u.search.includes("#"),Qu("#","search","hash",u)));let f=n===""||u.pathname==="",p=f?"/":u.pathname,h;if(p==null)h=r;else{let b=a.length-1;if(!o&&p.startsWith("..")){let S=p.split("/");for(;S[0]==="..";)S.shift(),b-=1;u.pathname=S.join("/")}h=b>=0?a[b]:"/"}let g=Wy(u,h),x=p&&p!=="/"&&p.endsWith("/"),v=(f||p===".")&&r.endsWith("/");return!g.pathname.endsWith("/")&&(x||v)&&(g.pathname+="/"),g}var Wn=n=>n.join("/").replace(/\/\/+/g,"/"),t1=n=>n.replace(/\/+$/,"").replace(/^\/*/,"/"),n1=n=>!n||n==="?"?"":n.startsWith("?")?n:"?"+n,s1=n=>!n||n==="#"?"":n.startsWith("#")?n:"#"+n;function a1(n){return n!=null&&typeof n.status=="number"&&typeof n.statusText=="string"&&typeof n.internal=="boolean"&&"data"in n}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var Ox=["POST","PUT","PATCH","DELETE"];new Set(Ox);var l1=["GET",...Ox];new Set(l1);var nl=m.createContext(null);nl.displayName="DataRouter";var vo=m.createContext(null);vo.displayName="DataRouterState";m.createContext(!1);var Bx=m.createContext({isTransitioning:!1});Bx.displayName="ViewTransition";var r1=m.createContext(new Map);r1.displayName="Fetchers";var i1=m.createContext(null);i1.displayName="Await";var Mn=m.createContext(null);Mn.displayName="Navigation";var pr=m.createContext(null);pr.displayName="Location";var ns=m.createContext({outlet:null,matches:[],isDataRoute:!1});ns.displayName="Route";var zd=m.createContext(null);zd.displayName="RouteError";function o1(n,{relative:a}={}){ot(xr(),"useHref() may be used only in the context of a component.");let{basename:r,navigator:o}=m.useContext(Mn),{hash:u,pathname:f,search:p}=gr(n,{relative:a}),h=f;return r!=="/"&&(h=f==="/"?r:Wn([r,f])),o.createHref({pathname:h,search:p,hash:u})}function xr(){return m.useContext(pr)!=null}function ta(){return ot(xr(),"useLocation() may be used only in the context of a component."),m.useContext(pr).location}var Lx="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function zx(n){m.useContext(Mn).static||m.useLayoutEffect(n)}function c1(){let{isDataRoute:n}=m.useContext(ns);return n?j1():u1()}function u1(){ot(xr(),"useNavigate() may be used only in the context of a component.");let n=m.useContext(nl),{basename:a,navigator:r}=m.useContext(Mn),{matches:o}=m.useContext(ns),{pathname:u}=ta(),f=JSON.stringify(Dx(o)),p=m.useRef(!1);return zx(()=>{p.current=!0}),m.useCallback((g,x={})=>{if(Sn(p.current,Lx),!p.current)return;if(typeof g=="number"){r.go(g);return}let v=_x(g,JSON.parse(f),u,x.relative==="path");n==null&&a!=="/"&&(v.pathname=v.pathname==="/"?a:Wn([a,v.pathname])),(x.replace?r.replace:r.push)(v,x.state,x)},[a,r,f,u,n])}m.createContext(null);function gr(n,{relative:a}={}){let{matches:r}=m.useContext(ns),{pathname:o}=ta(),u=JSON.stringify(Dx(r));return m.useMemo(()=>_x(n,JSON.parse(u),o,a==="path"),[n,u,o,a])}function d1(n,a){return Ux(n,a)}function Ux(n,a,r,o,u){ot(xr(),"useRoutes() may be used only in the context of a component.");let{navigator:f}=m.useContext(Mn),{matches:p}=m.useContext(ns),h=p[p.length-1],g=h?h.params:{},x=h?h.pathname:"/",v=h?h.pathnameBase:"/",b=h&&h.route;{let M=b&&b.path||"";Hx(x,!b||M.endsWith("*")||M.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${x}" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. - -Please change the parent to .`)}let S=ta(),E;if(a){let M=typeof a=="string"?tl(a):a;ot(v==="/"||M.pathname?.startsWith(v),`When overriding the location using \`\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${v}" but pathname "${M.pathname}" was given in the \`location\` prop.`),E=M}else E=S;let R=E.pathname||"/",N=R;if(v!=="/"){let M=v.replace(/^\//,"").split("/");N="/"+R.replace(/^\//,"").split("/").slice(M.length).join("/")}let w=Mx(n,{pathname:N});Sn(b||w!=null,`No routes matched location "${E.pathname}${E.search}${E.hash}" `),Sn(w==null||w[w.length-1].route.element!==void 0||w[w.length-1].route.Component!==void 0||w[w.length-1].route.lazy!==void 0,`Matched leaf route at location "${E.pathname}${E.search}${E.hash}" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.`);let j=x1(w&&w.map(M=>Object.assign({},M,{params:Object.assign({},g,M.params),pathname:Wn([v,f.encodeLocation?f.encodeLocation(M.pathname.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:M.pathname]),pathnameBase:M.pathnameBase==="/"?v:Wn([v,f.encodeLocation?f.encodeLocation(M.pathnameBase.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:M.pathnameBase])})),p,r,o,u);return a&&j?m.createElement(pr.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",...E},navigationType:"POP"}},j):j}function f1(){let n=S1(),a=a1(n)?`${n.status} ${n.statusText}`:n instanceof Error?n.message:JSON.stringify(n),r=n instanceof Error?n.stack:null,o="rgba(200,200,200, 0.5)",u={padding:"0.5rem",backgroundColor:o},f={padding:"2px 4px",backgroundColor:o},p=null;return console.error("Error handled by React Router default ErrorBoundary:",n),p=m.createElement(m.Fragment,null,m.createElement("p",null,"đź’ż Hey developer đź‘‹"),m.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",m.createElement("code",{style:f},"ErrorBoundary")," or"," ",m.createElement("code",{style:f},"errorElement")," prop on your route.")),m.createElement(m.Fragment,null,m.createElement("h2",null,"Unexpected Application Error!"),m.createElement("h3",{style:{fontStyle:"italic"}},a),r?m.createElement("pre",{style:u},r):null,p)}var m1=m.createElement(f1,null),h1=class extends m.Component{constructor(n){super(n),this.state={location:n.location,revalidation:n.revalidation,error:n.error}}static getDerivedStateFromError(n){return{error:n}}static getDerivedStateFromProps(n,a){return a.location!==n.location||a.revalidation!=="idle"&&n.revalidation==="idle"?{error:n.error,location:n.location,revalidation:n.revalidation}:{error:n.error!==void 0?n.error:a.error,location:a.location,revalidation:n.revalidation||a.revalidation}}componentDidCatch(n,a){this.props.onError?this.props.onError(n,a):console.error("React Router caught the following error during render",n)}render(){return this.state.error!==void 0?m.createElement(ns.Provider,{value:this.props.routeContext},m.createElement(zd.Provider,{value:this.state.error,children:this.props.component})):this.props.children}};function p1({routeContext:n,match:a,children:r}){let o=m.useContext(nl);return o&&o.static&&o.staticContext&&(a.route.errorElement||a.route.ErrorBoundary)&&(o.staticContext._deepestRenderedBoundaryId=a.route.id),m.createElement(ns.Provider,{value:n},r)}function x1(n,a=[],r=null,o=null,u=null){if(n==null){if(!r)return null;if(r.errors)n=r.matches;else if(a.length===0&&!r.initialized&&r.matches.length>0)n=r.matches;else return null}let f=n,p=r?.errors;if(p!=null){let v=f.findIndex(b=>b.route.id&&p?.[b.route.id]!==void 0);ot(v>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(p).join(",")}`),f=f.slice(0,Math.min(f.length,v+1))}let h=!1,g=-1;if(r)for(let v=0;v=0?f=f.slice(0,g+1):f=[f[0]];break}}}let x=r&&o?(v,b)=>{o(v,{location:r.location,params:r.matches?.[0]?.params??{},errorInfo:b})}:void 0;return f.reduceRight((v,b,S)=>{let E,R=!1,N=null,w=null;r&&(E=p&&b.route.id?p[b.route.id]:void 0,N=b.route.errorElement||m1,h&&(g<0&&S===0?(Hx("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),R=!0,w=null):g===S&&(R=!0,w=b.route.hydrateFallbackElement||null)));let j=a.concat(f.slice(0,S+1)),M=()=>{let k;return E?k=N:R?k=w:b.route.Component?k=m.createElement(b.route.Component,null):b.route.element?k=b.route.element:k=v,m.createElement(p1,{match:b,routeContext:{outlet:v,matches:j,isDataRoute:r!=null},children:k})};return r&&(b.route.ErrorBoundary||b.route.errorElement||S===0)?m.createElement(h1,{location:r.location,revalidation:r.revalidation,component:N,error:E,children:M(),routeContext:{outlet:null,matches:j,isDataRoute:!0},onError:x}):M()},null)}function Ud(n){return`${n} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function g1(n){let a=m.useContext(nl);return ot(a,Ud(n)),a}function v1(n){let a=m.useContext(vo);return ot(a,Ud(n)),a}function b1(n){let a=m.useContext(ns);return ot(a,Ud(n)),a}function Hd(n){let a=b1(n),r=a.matches[a.matches.length-1];return ot(r.route.id,`${n} can only be used on routes that contain a unique "id"`),r.route.id}function y1(){return Hd("useRouteId")}function S1(){let n=m.useContext(zd),a=v1("useRouteError"),r=Hd("useRouteError");return n!==void 0?n:a.errors?.[r]}function j1(){let{router:n}=g1("useNavigate"),a=Hd("useNavigate"),r=m.useRef(!1);return zx(()=>{r.current=!0}),m.useCallback(async(u,f={})=>{Sn(r.current,Lx),r.current&&(typeof u=="number"?n.navigate(u):await n.navigate(u,{fromRouteId:a,...f}))},[n,a])}var R0={};function Hx(n,a,r){!a&&!R0[n]&&(R0[n]=!0,Sn(!1,r))}m.memo(N1);function N1({routes:n,future:a,state:r,unstable_onError:o}){return Ux(n,void 0,r,o,a)}function Ki(n){ot(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function w1({basename:n="/",children:a=null,location:r,navigationType:o="POP",navigator:u,static:f=!1}){ot(!xr(),"You cannot render a inside another . You should never have more than one in your app.");let p=n.replace(/^\/*/,"/"),h=m.useMemo(()=>({basename:p,navigator:u,static:f,future:{}}),[p,u,f]);typeof r=="string"&&(r=tl(r));let{pathname:g="/",search:x="",hash:v="",state:b=null,key:S="default"}=r,E=m.useMemo(()=>{let R=es(g,p);return R==null?null:{location:{pathname:R,search:x,hash:v,state:b,key:S},navigationType:o}},[p,g,x,v,b,S,o]);return Sn(E!=null,` is not able to match the URL "${g}${x}${v}" because it does not start with the basename, so the won't render anything.`),E==null?null:m.createElement(Mn.Provider,{value:h},m.createElement(pr.Provider,{children:a,value:E}))}function A1({children:n,location:a}){return d1(bd(n),a)}function bd(n,a=[]){let r=[];return m.Children.forEach(n,(o,u)=>{if(!m.isValidElement(o))return;let f=[...a,u];if(o.type===m.Fragment){r.push.apply(r,bd(o.props.children,f));return}ot(o.type===Ki,`[${typeof o.type=="string"?o.type:o.type.name}] is not a component. All component children of must be a or `),ot(!o.props.index||!o.props.children,"An index route cannot have child routes.");let p={id:o.props.id||f.join("-"),caseSensitive:o.props.caseSensitive,element:o.props.element,Component:o.props.Component,index:o.props.index,path:o.props.path,middleware:o.props.middleware,loader:o.props.loader,action:o.props.action,hydrateFallbackElement:o.props.hydrateFallbackElement,HydrateFallback:o.props.HydrateFallback,errorElement:o.props.errorElement,ErrorBoundary:o.props.ErrorBoundary,hasErrorBoundary:o.props.hasErrorBoundary===!0||o.props.ErrorBoundary!=null||o.props.errorElement!=null,shouldRevalidate:o.props.shouldRevalidate,handle:o.props.handle,lazy:o.props.lazy};o.props.children&&(p.children=bd(o.props.children,f)),r.push(p)}),r}var Zi="get",Ji="application/x-www-form-urlencoded";function bo(n){return n!=null&&typeof n.tagName=="string"}function C1(n){return bo(n)&&n.tagName.toLowerCase()==="button"}function k1(n){return bo(n)&&n.tagName.toLowerCase()==="form"}function E1(n){return bo(n)&&n.tagName.toLowerCase()==="input"}function R1(n){return!!(n.metaKey||n.altKey||n.ctrlKey||n.shiftKey)}function M1(n,a){return n.button===0&&(!a||a==="_self")&&!R1(n)}var zi=null;function T1(){if(zi===null)try{new FormData(document.createElement("form"),0),zi=!1}catch{zi=!0}return zi}var q1=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Xu(n){return n!=null&&!q1.has(n)?(Sn(!1,`"${n}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${Ji}"`),null):n}function D1(n,a){let r,o,u,f,p;if(k1(n)){let h=n.getAttribute("action");o=h?es(h,a):null,r=n.getAttribute("method")||Zi,u=Xu(n.getAttribute("enctype"))||Ji,f=new FormData(n)}else if(C1(n)||E1(n)&&(n.type==="submit"||n.type==="image")){let h=n.form;if(h==null)throw new Error('Cannot submit a @@ -103,7 +103,7 @@ export default function DriveDockAction({ }) { const isMobile = layout === 'mobile'; const { - state: { roverId, keymap }, + state: { roverId, keymap, manualDockAssist }, actions, } = useControlSystem(); const frame = useTelemetryFrame(roverId); @@ -112,6 +112,7 @@ export default function DriveDockAction({ const [pending, setPending] = useState(null); const [confirmOpen, setConfirmOpen] = useState(false); const [showModal, setShowModal] = useState(false); + const manualAssistActive = Boolean(manualDockAssist?.active); const driveDisabled = !roverId || pending !== null; const dockDisabled = !roverId || pending !== null; @@ -120,10 +121,16 @@ export default function DriveDockAction({ const dockKeyLabel = formatKeyLabel(keymap?.dockMacro?.[0]); const dockInstructions = { - summary: 'You are about to trigger an automatic docking attempt! To have a successful dock:', - steps: ['Line up the rover straight in front of the dock', 'Make sure the rover is about one foot or half a meter away from the dock', 'Press Confirm Dock to begin the docking process'], + summary: 'This enables precision manual docking assist in the web UI.', + steps: [ + 'Line up the round front sensor on the rover with the sensor on the dock', + 'Camera will tilt all the way down so you can see the front sensor', + 'Drive speed will be limited for precise alignment', + ], }; - const dockButtonCaption = 'Click this button to initate auto-dock.'; + const dockButtonCaption = manualAssistActive + ? 'Manual docking assist is active: slow speed limit + camera down.' + : 'Click to enter manual docking assist.'; const startDriveInstructions = { summary: 'You must enable driving mode before you can move the rover.', @@ -138,6 +145,7 @@ export default function DriveDockAction({ if (!roverId || pending) return; setPending('drive'); try { + actions.setManualDockAssistActive(false); actions.setMode('drive'); await actions.runMacro('drive-sequence'); } catch (err) { @@ -153,6 +161,7 @@ export default function DriveDockAction({ setShowModal(false); setPending('drive'); try { + actions.setManualDockAssistActive(false); actions.setMode('drive'); await actions.runMacro('drive-sequence'); } catch (err) { @@ -166,8 +175,7 @@ export default function DriveDockAction({ if (!roverId || pending) return; setPending('dock'); try { - actions.setMode('dock'); - await actions.runMacro('seek-dock'); + actions.setManualDockAssistActive(true); } catch (err) { alert(err.message); } finally { @@ -179,6 +187,10 @@ export default function DriveDockAction({ const handleOpenDock = () => { if (dockDisabled) return; + if (manualAssistActive) { + actions.setManualDockAssistActive(false); + return; + } setShowModal(true); setConfirmOpen(true); }; @@ -299,12 +311,12 @@ export default function DriveDockAction({ >
- {compactDockedDriving ? 'Docked!' : 'Dock and Charge'} + {compactDockedDriving ? 'Docked!' : manualAssistActive ? 'Exit Docking Assist' : 'Enter Docking Assist'} {!isMobile && expanded ? (
{dockKeyLabel ? : null} - +
) : null}
@@ -316,7 +328,7 @@ export default function DriveDockAction({
- Line up straight, about 1 foot away, before docking. + Align front sensor to dock sensor; use tiny movements.
)} diff --git a/webui/src/components/QuickstartOverlay/index.jsx b/webui/src/components/QuickstartOverlay/index.jsx index c12d25d1..a10c2e2e 100644 --- a/webui/src/components/QuickstartOverlay/index.jsx +++ b/webui/src/components/QuickstartOverlay/index.jsx @@ -30,7 +30,7 @@ function DesktopQuickstart({ keymap }) { -

3. When done, please dock your rover! Line up with the dock and press "Dock and Charge".

+

3. When done, enter "Docking Assist" and line up the front sensor with the dock sensor.

); } @@ -41,7 +41,7 @@ function MobileQuickstart() {

1. Press "Start Driving" put your rover into driving mode.

2. Touch and hold in Joystick area to move.

3. Use the other column for motor, horn, and camera controls.

-

4. When done, please dock your rover! Line up with the dock and press "Dock and Charge".

+

4. When done, enter "Docking Assist" and line up the front sensor with the dock sensor.

); } diff --git a/webui/src/controls/ControlContext.jsx b/webui/src/controls/ControlContext.jsx index ad1aeb0d..22f7e652 100644 --- a/webui/src/controls/ControlContext.jsx +++ b/webui/src/controls/ControlContext.jsx @@ -11,6 +11,7 @@ import { HORN_HEAT_RESUME_THRESHOLD, HORN_HEAT_UP_PER_SEC, HORN_MAX_MS, + MANUAL_DOCK_ASSIST_MAX_SPEED, SONG_DEFAULT_NOTE, } from './constants.js'; import { canonicalizeKeyInput } from './keymapUtils.js'; @@ -212,7 +213,23 @@ export function ControlSystemProvider({ children }) { const setDriveVector = useCallback( (vector, meta = {}) => { - const computed = computeDifferentialSpeeds(vector, meta.speedOptions); + const speedOptions = { ...(meta.speedOptions || {}) }; + if (state.manualDockAssist?.active) { + const capped = Math.max(1, Math.min(MANUAL_DOCK_ASSIST_MAX_SPEED, 500)); + speedOptions.maxSpeed = Math.min( + typeof speedOptions.maxSpeed === 'number' ? speedOptions.maxSpeed : capped, + capped, + ); + speedOptions.baseSpeed = Math.min( + typeof speedOptions.baseSpeed === 'number' ? speedOptions.baseSpeed : capped, + capped, + ); + speedOptions.boostSpeed = Math.min( + typeof speedOptions.boostSpeed === 'number' ? speedOptions.boostSpeed : capped, + capped, + ); + } + const computed = computeDifferentialSpeeds(vector, speedOptions); dispatch({ type: 'control/update-drive', payload: { ...computed, source: meta.source ?? null }, @@ -220,7 +237,7 @@ export function ControlSystemProvider({ children }) { recordControlIntent(); pipeline.sendDriveDirect(computed.speeds); }, - [pipeline, recordControlIntent], + [pipeline, recordControlIntent, state.manualDockAssist?.active], ); const setAuxMotors = useCallback( @@ -318,8 +335,6 @@ export function ControlSystemProvider({ children }) { steps: removeDriveSequenceBackoff(macro.steps), }; } - } else if (macroId === 'seek-dock') { - recordControlIntent(); } await pipeline.runMacroSteps(macroToRun); }, @@ -509,6 +524,28 @@ export function ControlSystemProvider({ children }) { return () => clearInterval(interval); }, [dispatch, hornNeedsTick, HORN_HEAT_COOL_PER_SEC, HORN_HEAT_RESUME_THRESHOLD, HORN_HEAT_UP_PER_SEC]); + const setManualDockAssistActive = useCallback( + (active) => { + const nextActive = Boolean(active); + const prevActive = Boolean(state.manualDockAssist?.active); + if (prevActive === nextActive) return; + dispatch({ type: 'control/set-manual-dock-assist', payload: nextActive }); + if (!nextActive) return; + const minAngle = + typeof pipeline.servoConfig?.minAngle === 'number' + ? pipeline.servoConfig.minAngle + : -45; + setServoAngle(minAngle); + pipeline.sendSong([{ note: 76, duration: 10 }, { note: 83, duration: 10 }], { slot: 0 }); + recordControlIntent(); + }, + [pipeline, recordControlIntent, setServoAngle, state.manualDockAssist?.active], + ); + + const toggleManualDockAssist = useCallback(() => { + setManualDockAssistActive(!state.manualDockAssist?.active); + }, [setManualDockAssistActive, state.manualDockAssist?.active]); + const registerInputState = useCallback((source, data) => { dispatch({ type: 'control/register-input-state', payload: { source, state: data } }); }, []); @@ -539,6 +576,8 @@ export function ControlSystemProvider({ children }) { updateKeyBinding, resetKeyBindings, registerInputState, + setManualDockAssistActive, + toggleManualDockAssist, setSongNote, sendSong, startHorn, @@ -565,6 +604,8 @@ export function ControlSystemProvider({ children }) { updateKeyBinding, resetKeyBindings, registerInputState, + setManualDockAssistActive, + toggleManualDockAssist, setSongNote, sendSong, startHorn, diff --git a/webui/src/controls/constants.js b/webui/src/controls/constants.js index 57ae90f4..5f5e817c 100644 --- a/webui/src/controls/constants.js +++ b/webui/src/controls/constants.js @@ -12,6 +12,8 @@ export const DRIVE_LIMITS = { boostSpeed: 400, }; +export const MANUAL_DOCK_ASSIST_MAX_SPEED = 110; + export const COMMAND_DELAY_MS = 100; export const SONG_NOTE_RANGE = [31, 127]; @@ -78,12 +80,4 @@ export const DEFAULT_MACROS = [ { type: 'drive', speeds: { left: 0, right: 0 } }, ], }, - { - id: 'seek-dock', - label: 'Dock', - description: 'Send the seek dock command.', - steps: [ - { type: 'oi', command: 'dock' } - ], - }, ]; diff --git a/webui/src/controls/controlReducer.js b/webui/src/controls/controlReducer.js index 1b2275f9..e2dd251f 100644 --- a/webui/src/controls/controlReducer.js +++ b/webui/src/controls/controlReducer.js @@ -43,6 +43,12 @@ function createMicState() { }; } +function createManualDockAssistState() { + return { + active: false, + }; +} + export const initialControlState = { roverId: null, mode: 'drive', @@ -52,6 +58,7 @@ export const initialControlState = { song: createSongState(), horn: createHornState(), mic: createMicState(), + manualDockAssist: createManualDockAssistState(), lastControlIntentAt: 0, macros: DEFAULT_MACROS, keymap: DEFAULT_KEYMAP, @@ -69,6 +76,7 @@ export function controlReducer(state, action) { song: action.payload ? state.song : createSongState(), horn: action.payload ? state.horn : createHornState(), mic: action.payload ? state.mic : createMicState(), + manualDockAssist: action.payload ? state.manualDockAssist : createManualDockAssistState(), lastControlIntentAt: action.payload ? state.lastControlIntentAt : 0, }; case 'control/set-mode': @@ -187,6 +195,14 @@ export function controlReducer(state, action) { pttActive: Boolean(action.payload), }, }; + case 'control/set-manual-dock-assist': + return { + ...state, + manualDockAssist: { + ...(state.manualDockAssist || createManualDockAssistState()), + active: Boolean(action.payload), + }, + }; default: return state; } diff --git a/webui/src/controls/inputs/GamepadInputManager.jsx b/webui/src/controls/inputs/GamepadInputManager.jsx index a9eaf509..44d0e13f 100644 --- a/webui/src/controls/inputs/GamepadInputManager.jsx +++ b/webui/src/controls/inputs/GamepadInputManager.jsx @@ -50,6 +50,8 @@ export default function GamepadInputManager() { state, actions: { setMode, + setManualDockAssistActive, + toggleManualDockAssist, setDriveVector, setAuxMotors, setServoAngle, @@ -243,6 +245,7 @@ export default function GamepadInputManager() { } if (outputs.buttons.driveMacro && handleButtonEdge('driveMacro', true)) { + setManualDockAssistActive(false); setMode('drive'); runMacro('drive-sequence'); } else if (!outputs.buttons.driveMacro) { @@ -250,8 +253,7 @@ export default function GamepadInputManager() { } if (outputs.buttons.dockMacro && handleButtonEdge('dockMacro', true)) { - setMode('dock'); - runMacro('seek-dock'); + toggleManualDockAssist(); } else if (!outputs.buttons.dockMacro) { handleButtonEdge('dockMacro', false); } @@ -288,9 +290,11 @@ export default function GamepadInputManager() { handleCameraAxis, registerInputState, runMacro, + setManualDockAssistActive, setAuxMotors, setDriveVector, setMode, + toggleManualDockAssist, toggleNightVision, ]); diff --git a/webui/src/controls/inputs/KeyboardInputManager.jsx b/webui/src/controls/inputs/KeyboardInputManager.jsx index 1961e232..7a930ba9 100644 --- a/webui/src/controls/inputs/KeyboardInputManager.jsx +++ b/webui/src/controls/inputs/KeyboardInputManager.jsx @@ -122,6 +122,8 @@ export default function KeyboardInputManager() { state, actions: { setMode, + setManualDockAssistActive, + toggleManualDockAssist, setDriveVector, setAuxMotors, nudgeServo, @@ -372,11 +374,11 @@ export default function KeyboardInputManager() { if (newlyPressed.length > 0) { if (newlyPressed.some((token) => keymap.driveMacro?.has(token))) { + setManualDockAssistActive(false); setMode('drive'); runMacro('drive-sequence'); } else if (newlyPressed.some((token) => keymap.dockMacro?.has(token))) { - setMode('dock'); - runMacro('seek-dock'); + toggleManualDockAssist(); } else if (newlyPressed.some((token) => keymap.nightVisionToggle?.has(token))) { toggleNightVision(); } else if (newlyPressed.some((token) => keymap.hornHonk?.has(token))) { @@ -441,12 +443,14 @@ export default function KeyboardInputManager() { keymap.micPtt, resetAll, runMacro, + setManualDockAssistActive, setMicPttActive, setMode, stopAllMotion, stopSongLoop, startHorn, stopHorn, + toggleManualDockAssist, triggerHomeAssistantCycle, ]); diff --git a/webui/src/help/content.js b/webui/src/help/content.js index f49585f7..72e1f4c3 100644 --- a/webui/src/help/content.js +++ b/webui/src/help/content.js @@ -27,9 +27,10 @@ export const HELP_CONTENT = { type: 'list', title: 'Docking the rover', items: [ - 'Line up the rover to the dock, about a foot away, then:', - { segments: ['Press the "Dock and Charge" button onscreen, or press ', { action: 'dockMacro' }, ' on your keyboard to start docking.'] }, - 'Wait for the rover to confirm it is docked and charging before leaving it unattended.', + 'If the rover shows "Docking in Progress", it is already auto-seeking the dock.', + 'To dock manually, enter Docking Assist from the drive panel.', + { segments: ['Press "Enter Docking Assist", or press ', { action: 'dockMacro' }, '.'] }, + 'In assist mode, camera tilts down and driving speed is limited for precise alignment.', ], }, ], @@ -56,7 +57,7 @@ export const HELP_CONTENT = { title: 'Rover modes & chat', items: [ { action: 'driveMacro', label: 'Drive macro' }, - { action: 'dockMacro', label: 'Dock macro' }, + { action: 'dockMacro', label: 'Docking assist toggle' }, { action: 'chatFocus', label: 'Chat focus' }, ], }, @@ -133,9 +134,9 @@ export const HELP_CONTENT = { type: 'list', title: 'Docking the rover', items: [ - 'Line up the rover to the dock, about a foot away, then:', - { segments: ['Press the "Dock and Charge" button onscreen to start docking.'] }, - 'Wait for the rover to confirm it is docked and charging before leaving it unattended.', + 'If you see "Docking in Progress", the rover is currently auto-seeking the dock.', + { segments: ['For manual docking, press "Enter Docking Assist".'] }, + 'Assist mode tilts camera down and limits speed for precise alignment.', ], } ], @@ -163,9 +164,9 @@ export const HELP_CONTENT = { type: 'list', title: 'Docking the rover', items: [ - 'Line up the rover to the dock, about a foot away, then:', - { segments: ['Press the "Dock and Charge" or the "Dock" button onscreen to start docking.'] }, - 'Wait for the rover to confirm it is docked and charging before leaving it unattended.', + 'If you see "Docking in Progress", the rover is currently auto-seeking the dock.', + { segments: ['For manual docking, press "Enter Docking Assist" (or "Dock" button).'] }, + 'Assist mode tilts camera down and limits speed for precise alignment.', ], } ],