From ccdd3e234fb20c209bec70254f7c9969c2bb235e Mon Sep 17 00:00:00 2001 From: Arshita Jaryal Date: Thu, 14 May 2026 19:10:01 +0530 Subject: [PATCH 1/3] Complete TypeScript migration --- app/dist/assets/index-CLOIsP4q.js | 7504 ----------------- app/dist/assets/index-DHFWRlXl.js | 7504 +++++++++++++++++ ...{index-hdzOkq2r.css => index-Y4Qzsb0-.css} | 2 +- app/dist/index.html | 4 +- app/{eslint.config.js => eslint.config.ts} | 2 +- app/index.html | 2 +- app/package-lock.json | 45 +- app/package.json | 5 +- app/src/{App.jsx => App.tsx} | 0 .../common/{Badge.jsx => Badge.tsx} | 9 +- .../common/{ErrorState.jsx => ErrorState.tsx} | 6 +- .../{GapScoreBar.jsx => GapScoreBar.tsx} | 9 +- .../{LoadingState.jsx => LoadingState.tsx} | 6 +- .../{ThemeToggle.jsx => ThemeToggle.tsx} | 7 +- ...ngSitesPanel.jsx => BindingSitesPanel.tsx} | 27 +- app/src/components/complex/ComparisonTab.jsx | 626 -- app/src/components/complex/ComparisonTab.tsx | 305 + .../{ComplexHeader.jsx => ComplexHeader.tsx} | 11 +- ...ionBrowser.jsx => ConformationBrowser.tsx} | 9 +- ...Leaderboard.jsx => DockingLeaderboard.tsx} | 17 +- .../{DockingPanel.jsx => DockingPanel.tsx} | 26 +- .../{FragmentList.jsx => FragmentList.tsx} | 7 +- .../{MetricsPanel.jsx => MetricsPanel.tsx} | 7 +- ...{MoleculePicker.jsx => MoleculePicker.tsx} | 16 +- ...{PocketTableRow.jsx => PocketTableRow.tsx} | 17 +- ...rPlaceholder.jsx => ViewerPlaceholder.tsx} | 11 +- ...orderDeltaBar.jsx => DisorderDeltaBar.tsx} | 7 +- .../{MolstarPanel.jsx => MolstarPanel.tsx} | 22 +- .../{ProteinViewer.jsx => ProteinViewer.tsx} | 41 +- .../{RevealButton.jsx => RevealButton.tsx} | 8 +- .../{ViewerFooter.jsx => ViewerFooter.tsx} | 7 +- .../{ViewerHeader.jsx => ViewerHeader.tsx} | 7 +- .../viewer/{useMolstar.js => useMolstar.ts} | 128 +- .../{TargetTable.jsx => TargetTable.tsx} | 11 +- .../layout/{Footer.jsx => Footer.tsx} | 0 .../layout/{Navbar.jsx => Navbar.tsx} | 0 .../search/{ResultCard.jsx => ResultCard.tsx} | 11 +- .../search/{SearchBar.jsx => SearchBar.tsx} | 18 +- app/src/{config.js => config.ts} | 4 +- ...{useBindingSites.js => useBindingSites.ts} | 25 +- ...emblFragments.js => useChemblFragments.ts} | 34 +- .../hooks/{useComplex.js => useComplex.ts} | 22 +- .../{useDockingJob.js => useDockingJob.ts} | 64 +- app/src/hooks/{useSearch.js => useSearch.ts} | 31 +- app/src/hooks/{useTheme.js => useTheme.ts} | 2 +- .../{useUndrugged.js => useUndrugged.ts} | 18 +- app/src/{main.jsx => main.tsx} | 4 +- app/src/pages/ComplexDetailPage.jsx | 247 - app/src/pages/ComplexDetailPage.tsx | 137 + .../{DashboardPage.jsx => DashboardPage.tsx} | 21 +- app/src/pages/{HomePage.jsx => HomePage.tsx} | 98 +- .../pages/{SearchPage.jsx => SearchPage.tsx} | 25 +- app/src/scss.d.ts | 4 + app/src/types.ts | 157 + app/src/utils/safeFetch.ts | 14 + app/tsconfig.json | 29 + app/vite-env.d.ts | 1 + app/{vite.config.js => vite.config.ts} | 0 58 files changed, 8672 insertions(+), 8709 deletions(-) delete mode 100644 app/dist/assets/index-CLOIsP4q.js create mode 100644 app/dist/assets/index-DHFWRlXl.js rename app/dist/assets/{index-hdzOkq2r.css => index-Y4Qzsb0-.css} (76%) rename app/{eslint.config.js => eslint.config.ts} (95%) rename app/src/{App.jsx => App.tsx} (100%) rename app/src/components/common/{Badge.jsx => Badge.tsx} (73%) rename app/src/components/common/{ErrorState.jsx => ErrorState.tsx} (78%) rename app/src/components/common/{GapScoreBar.jsx => GapScoreBar.tsx} (84%) rename app/src/components/common/{LoadingState.jsx => LoadingState.tsx} (73%) rename app/src/components/common/{ThemeToggle.jsx => ThemeToggle.tsx} (93%) rename app/src/components/complex/{BindingSitesPanel.jsx => BindingSitesPanel.tsx} (90%) delete mode 100644 app/src/components/complex/ComparisonTab.jsx create mode 100644 app/src/components/complex/ComparisonTab.tsx rename app/src/components/complex/{ComplexHeader.jsx => ComplexHeader.tsx} (89%) rename app/src/components/complex/{ConformationBrowser.jsx => ConformationBrowser.tsx} (90%) rename app/src/components/complex/{DockingLeaderboard.jsx => DockingLeaderboard.tsx} (96%) rename app/src/components/complex/{DockingPanel.jsx => DockingPanel.tsx} (90%) rename app/src/components/complex/{FragmentList.jsx => FragmentList.tsx} (95%) rename app/src/components/complex/{MetricsPanel.jsx => MetricsPanel.tsx} (95%) rename app/src/components/complex/{MoleculePicker.jsx => MoleculePicker.tsx} (93%) rename app/src/components/complex/{PocketTableRow.jsx => PocketTableRow.tsx} (89%) rename app/src/components/complex/{ViewerPlaceholder.jsx => ViewerPlaceholder.tsx} (87%) rename app/src/components/complex/viewer/{DisorderDeltaBar.jsx => DisorderDeltaBar.tsx} (88%) rename app/src/components/complex/viewer/{MolstarPanel.jsx => MolstarPanel.tsx} (83%) rename app/src/components/complex/viewer/{ProteinViewer.jsx => ProteinViewer.tsx} (87%) rename app/src/components/complex/viewer/{RevealButton.jsx => RevealButton.tsx} (81%) rename app/src/components/complex/viewer/{ViewerFooter.jsx => ViewerFooter.tsx} (83%) rename app/src/components/complex/viewer/{ViewerHeader.jsx => ViewerHeader.tsx} (74%) rename app/src/components/complex/viewer/{useMolstar.js => useMolstar.ts} (82%) rename app/src/components/dashboard/{TargetTable.jsx => TargetTable.tsx} (95%) rename app/src/components/layout/{Footer.jsx => Footer.tsx} (100%) rename app/src/components/layout/{Navbar.jsx => Navbar.tsx} (100%) rename app/src/components/search/{ResultCard.jsx => ResultCard.tsx} (91%) rename app/src/components/search/{SearchBar.jsx => SearchBar.tsx} (82%) rename app/src/{config.js => config.ts} (78%) rename app/src/hooks/{useBindingSites.js => useBindingSites.ts} (61%) rename app/src/hooks/{useChemblFragments.js => useChemblFragments.ts} (67%) rename app/src/hooks/{useComplex.js => useComplex.ts} (59%) rename app/src/hooks/{useDockingJob.js => useDockingJob.ts} (69%) rename app/src/hooks/{useSearch.js => useSearch.ts} (62%) rename app/src/hooks/{useTheme.js => useTheme.ts} (92%) rename app/src/hooks/{useUndrugged.js => useUndrugged.ts} (61%) rename app/src/{main.jsx => main.tsx} (62%) delete mode 100644 app/src/pages/ComplexDetailPage.jsx create mode 100644 app/src/pages/ComplexDetailPage.tsx rename app/src/pages/{DashboardPage.jsx => DashboardPage.tsx} (67%) rename app/src/pages/{HomePage.jsx => HomePage.tsx} (63%) rename app/src/pages/{SearchPage.jsx => SearchPage.tsx} (77%) create mode 100644 app/src/scss.d.ts create mode 100644 app/src/types.ts create mode 100644 app/src/utils/safeFetch.ts create mode 100644 app/tsconfig.json create mode 100644 app/vite-env.d.ts rename app/{vite.config.js => vite.config.ts} (100%) diff --git a/app/dist/assets/index-CLOIsP4q.js b/app/dist/assets/index-CLOIsP4q.js deleted file mode 100644 index 1effb64..0000000 --- a/app/dist/assets/index-CLOIsP4q.js +++ /dev/null @@ -1,7504 +0,0 @@ -var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(e&&(t=e(e=0)),t),s=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),c=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},l=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},u=(n,r,a)=>(a=n==null?{}:e(i(n)),l(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n)),d=e=>a.call(e,`module.exports`)?e[`module.exports`]:l(t({},`__esModule`,{value:!0}),e);(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var f=s((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=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,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var S=Array.isArray;function C(){}var w={H:null,A:null,T:null,S:null},T=Object.prototype.hasOwnProperty;function E(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function D(e,t){return E(e.type,t,e.props)}function O(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function k(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var A=/\/+/g;function ee(e,t){return typeof e==`object`&&e&&e.key!=null?k(``+e.key):t.toString(36)}function te(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(C,C):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function j(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,j(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+ee(e,0):a,S(o)?(i=``,c!=null&&(i=c.replace(A,`$&/`)+`/`),j(o,r,i,``,function(e){return e})):o!=null&&(O(o)&&(o=D(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(A,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(S(e))for(var u=0;u{t.exports=f()})),m=s((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,S||(S=!0,O());else{var t=n(l);t!==null&&ee(x,t.startTime-e)}}var S=!1,C=-1,w=5,T=-1;function E(){return g?!0:!(e.unstable_now()-Tt&&E());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&ee(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?O():S=!1}}}var O;if(typeof y==`function`)O=function(){y(D)};else if(typeof MessageChannel<`u`){var k=new MessageChannel,A=k.port2;k.port1.onmessage=D,O=function(){A.postMessage(null)}}else O=function(){_(D,0)};function ee(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,ee(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,O()))),r},e.unstable_shouldYield=E,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),h=s(((e,t)=>{t.exports=m()})),g=s((e=>{var t=p();function n(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=g()})),v=s((e=>{var t=h(),n=p(),r=_();function i(e){var t=`https://react.dev/errors/`+e;if(1se||(e.current=oe[se],oe[se]=null,se--)}function ue(e,t){se++,oe[se]=e.current,e.current=t}var de=ce(null),fe=ce(null),pe=ce(null),me=ce(null);function he(e,t){switch(ue(pe,t),ue(fe,e),ue(de,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}le(de),ue(de,e)}function ge(){le(de),le(fe),le(pe)}function _e(e){e.memoizedState!==null&&ue(me,e);var t=de.current,n=Hd(t,e.type);t!==n&&(ue(fe,e),ue(de,n))}function ve(e){fe.current===e&&(le(de),le(fe)),me.current===e&&(le(me),Gf._currentValue=ae)}var ye,be;function xe(e){if(ye===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);ye=t&&t[1]||``,be=-1)`:-1i||c[r]!==l[i]){var u=` -`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{Se=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?xe(n):``}function we(e,t){switch(e.tag){case 26:case 27:case 5:return xe(e.type);case 16:return xe(`Lazy`);case 13:return e.child!==t&&t!==null?xe(`Suspense Fallback`):xe(`Suspense`);case 19:return xe(`SuspenseList`);case 0:case 15:return Ce(e.type,!1);case 11:return Ce(e.type.render,!1);case 1:return Ce(e.type,!0);case 31:return xe(`Activity`);default:return``}}function Te(e){try{var t=``,n=null;do t+=we(e,n),n=e,e=e.return;while(e);return t}catch(e){return` -Error generating stack: `+e.message+` -`+e.stack}}var Ee=Object.prototype.hasOwnProperty,De=t.unstable_scheduleCallback,Oe=t.unstable_cancelCallback,ke=t.unstable_shouldYield,Ae=t.unstable_requestPaint,je=t.unstable_now,Me=t.unstable_getCurrentPriorityLevel,Ne=t.unstable_ImmediatePriority,Pe=t.unstable_UserBlockingPriority,Fe=t.unstable_NormalPriority,Ie=t.unstable_LowPriority,Le=t.unstable_IdlePriority,Re=t.log,ze=t.unstable_setDisableYieldValue,Be=null,Ve=null;function He(e){if(typeof Re==`function`&&ze(e),Ve&&typeof Ve.setStrictMode==`function`)try{Ve.setStrictMode(Be,e)}catch{}}var Ue=Math.clz32?Math.clz32:Ke,We=Math.log,Ge=Math.LN2;function Ke(e){return e>>>=0,e===0?32:31-(We(e)/Ge|0)|0}var qe=256,Je=262144,Ye=4194304;function Xe(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 Ze(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=Xe(n))):i=Xe(o):i=Xe(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=Xe(n))):i=Xe(o)):i=Xe(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function Qe(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function $e(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 et(){var e=Ye;return Ye<<=1,!(Ye&62914560)&&(Ye=4194304),e}function tt(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function nt(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function rt(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),fn=!1;if(dn)try{var pn={};Object.defineProperty(pn,`passive`,{get:function(){fn=!0}}),window.addEventListener(`test`,pn,pn),window.removeEventListener(`test`,pn,pn)}catch{fn=!1}var mn=null,hn=null,gn=null;function _n(){if(gn)return gn;var e,t=hn,n=t.length,r,i=`value`in mn?mn.value:mn.textContent,a=i.length;for(e=0;e=Kn),Yn=` `,Xn=!1;function Zn(e,t){switch(e){case`keyup`:return aee.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function Qn(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var $n=!1;function er(e,t){switch(e){case`compositionend`:return Qn(t);case`keypress`:return t.which===32?(Xn=!0,Yn):null;case`textInput`:return e=t.data,e===Yn&&Xn?null:e;default:return null}}function tr(e,t){if($n)return e===`compositionend`||!Gn&&Zn(e,t)?(e=_n(),gn=hn=mn=null,$n=!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:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=xr(n)}}function Cr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Cr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function wr(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Bt(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=Bt(e.document)}return t}function Tr(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 Er=dn&&`documentMode`in document&&11>=document.documentMode,Dr=null,Or=null,kr=null,Ar=!1;function jr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Ar||Dr==null||Dr!==Bt(r)||(r=Dr,`selectionStart`in r&&Tr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),kr&&br(kr,r)||(kr=r,r=Ed(Or,`onSelect`),0>=o,i-=o,Ci=1<<32-Ue(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),Mi&&Ti(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),Mi&&Ti(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return Mi&&Ti(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),Mi&&Ti(a,g),u}function b(e,r,o,c){if(typeof o==`object`&&o&&o.type===y&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case g:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===y){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===O&&Ta(l)===r.type){n(e,r.sibling),c=a(r,o.props),Ma(c,o),c.return=e,e=c;break a}n(e,r);break}else t(e,r);r=r.sibling}o.type===y?(c=ui(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=li(o.type,o.key,o.props,null,e.mode,c),Ma(c,o),c.return=e,e=c)}return s(e);case v:a:{for(l=o.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}else{n(e,r);break}else t(e,r);r=r.sibling}c=pi(o,e.mode,c),c.return=e,e=c}return s(e);case O:return o=Ta(o),b(e,r,o,c)}if(re(o))return h(e,r,o,c);if(te(o)){if(l=te(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),_(e,r,o,c)}if(typeof o.then==`function`)return b(e,r,ja(o),c);if(o.$$typeof===C)return b(e,r,ea(e,o),c);Na(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=di(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{Aa=0;var i=b(e,t,n,r);return ka=null,i}catch(t){if(t===ya||t===xa)throw t;var a=ai(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var Fa=Pa(!0),Ia=Pa(!1),La=!1;function Ra(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function za(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 Ba(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Va(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,Fl&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=ni(e),ti(e,null,n),t}return Qr(e,r,t,n),ni(e)}function Ha(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,at(e,n)}}function Ua(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Wa=!1;function Ga(){if(Wa){var e=ua;if(e!==null)throw e}}function Ka(e,t,n,r){Wa=!1;var i=e.updateQueue;La=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var p=s.lane&-536870913,m=p!==s.lane;if(m?(Rl&p)===p:(r&p)===p){p!==0&&p===la&&(Wa=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var h=e,g=s;p=t;var _=n;switch(g.tag){case 1:if(h=g.payload,typeof h==`function`){d=h.call(_,d,p);break a}d=h;break a;case 3:h.flags=h.flags&-65537|128;case 0:if(h=g.payload,p=typeof h==`function`?h.call(_,d,p):h,p==null)break a;d=f({},d,p);break a;case 2:La=!0}}p=s.callback,p!==null&&(e.flags|=64,m&&(e.flags|=8192),m=i.callbacks,m===null?i.callbacks=[p]:m.push(p))}else m={lane:p,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=m,c=d):u=u.next=m,o|=p;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;m=s,s=m.next,m.next=null,i.lastBaseUpdate=m,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Kl|=o,e.lanes=o,e.memoizedState=d}}function qa(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function Ja(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=M.T,s={};M.T=s,js(e,!1,t,n);try{var c=i(),l=M.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?As(e,t,pa(c,r),mu(e)):As(e,t,r,mu(e))}catch(n){As(e,t,{then:function(){},status:`rejected`,reason:n},mu())}finally{ie.p=a,o!==null&&s.types!==null&&(o.types=s.types),M.T=o}}function dee(){}function Ss(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=Cs(e).queue;xs(e,a,t,ae,n===null?dee:function(){return ws(e),n(r)})}function Cs(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:ae,baseState:ae,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Io,lastRenderedState:ae},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Io,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function ws(e){var t=Cs(e);t.next===null&&(t=e.alternate.memoizedState),As(e,t.next.queue,{},mu())}function Ts(){return $i(Gf)}function Es(){return jo().memoizedState}function Ds(){return jo().memoizedState}function fee(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=mu();e=Ba(n);var r=Va(t,e,n);r!==null&&(gu(r,t,n),Ha(r,t,n)),t={cache:aa()},e.payload=t;return}t=t.return}}function Os(e,t,n){var r=mu();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Ms(e)?Ns(t,n):(n=$r(e,t,n,r),n!==null&&(gu(n,e,r),Ps(n,t,r)))}function ks(e,t,n){As(e,t,n,mu())}function As(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Ms(e))Ns(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,yr(s,o))return Qr(e,t,i,0),Il===null&&Zr(),!1}catch{}if(n=$r(e,t,i,r),n!==null)return gu(n,e,r),Ps(n,t,r),!0}return!1}function js(e,t,n,r){if(r={lane:2,revertLane:ud(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Ms(e)){if(t)throw Error(i(479))}else t=$r(e,n,r,2),t!==null&&gu(t,e,2)}function Ms(e){var t=e.alternate;return e===uo||t!==null&&t===uo}function Ns(e,t){ho=mo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Ps(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,at(e,n)}}var Fs={readContext:$i,use:Po,useCallback:xo,useContext:xo,useEffect:xo,useImperativeHandle:xo,useLayoutEffect:xo,useInsertionEffect:xo,useMemo:xo,useReducer:xo,useRef:xo,useState:xo,useDebugValue:xo,useDeferredValue:xo,useTransition:xo,useSyncExternalStore:xo,useId:xo,useHostTransitionStatus:xo,useFormState:xo,useActionState:xo,useOptimistic:xo,useMemoCache:xo,useCacheRefresh:xo};Fs.useEffectEvent=xo;var Is={readContext:$i,use:Po,useCallback:function(e,t){return Ao().memoizedState=[e,t===void 0?null:t],e},useContext:$i,useEffect:ls,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),ss(4194308,4,ms.bind(null,t,e),n)},useLayoutEffect:function(e,t){return ss(4194308,4,e,t)},useInsertionEffect:function(e,t){ss(4,2,e,t)},useMemo:function(e,t){var n=Ao();t=t===void 0?null:t;var r=e();if(go){He(!0);try{e()}finally{He(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=Ao();if(n!==void 0){var i=n(t);if(go){He(!0);try{n(t)}finally{He(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=Os.bind(null,uo,e),[r.memoizedState,e]},useRef:function(e){var t=Ao();return e={current:e},t.memoizedState=e},useState:function(e){e=Ko(e);var t=e.queue,n=ks.bind(null,uo,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:gs,useDeferredValue:function(e,t){return ys(Ao(),e,t)},useTransition:function(){var e=Ko(!1);return e=xs.bind(null,uo,e.queue,!0,!1),Ao().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=uo,a=Ao();if(Mi){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),Il===null)throw Error(i(349));Rl&127||Vo(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,ls(Uo.bind(null,r,o,e),[e]),r.flags|=2048,as(9,{destroy:void 0},Ho.bind(null,r,o,n,t),null),n},useId:function(){var e=Ao(),t=Il.identifierPrefix;if(Mi){var n=wi,r=Ci;n=(r&~(1<<32-Ue(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=_o++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[ft]=t,o[pt]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(Fd(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&Oc(t)}}return Nc(t),kc(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&Oc(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=pe.current,zi(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=Ai,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[ft]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||Md(e.nodeValue,n)),e||Ii(t,!0)}else e=Bd(e).createTextNode(r),e[ft]=t,t.stateNode=e}return Nc(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=zi(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[ft]=t}else Bi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Nc(t),e=!1}else n=Vi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(oo(t),t):(oo(t),null);if(t.flags&128)throw Error(i(558))}return Nc(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=zi(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[ft]=t}else Bi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Nc(t),a=!1}else a=Vi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(oo(t),t):(oo(t),null)}return oo(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),jc(t,t.updateQueue),Nc(t),null);case 4:return ge(),e===null&&Sd(t.stateNode.containerInfo),Nc(t),null;case 10:return qi(t.type),Nc(t),null;case 19:if(le(so),r=t.memoizedState,r===null)return Nc(t),null;if(a=(t.flags&128)!=0,o=r.rendering,o===null)if(a)Mc(r,!1);else{if(Gl!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=co(e),o!==null){for(t.flags|=128,Mc(r,!1),e=o.updateQueue,t.updateQueue=e,jc(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)ci(n,e),n=n.sibling;return ue(so,so.current&1|2),Mi&&Ti(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&je()>nu&&(t.flags|=128,a=!0,Mc(r,!1),t.lanes=4194304)}else{if(!a)if(e=co(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,jc(t,e),Mc(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!Mi)return Nc(t),null}else 2*je()-r.renderingStartTime>nu&&n!==536870912&&(t.flags|=128,a=!0,Mc(r,!1),t.lanes=4194304);r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(Nc(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=je(),e.sibling=null,n=so.current,ue(so,a?n&1|2:n&1),Mi&&Ti(t,r.treeForkCount),e);case 22:case 23:return oo(t),$a(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(Nc(t),t.subtreeFlags&6&&(t.flags|=8192)):Nc(t),n=t.updateQueue,n!==null&&jc(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&le(ha),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),qi(ia),Nc(t),null;case 25:return null;case 30:return null}throw Error(i(156,t.tag))}function Fc(e,t){switch(Oi(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return qi(ia),ge(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return ve(t),null;case 31:if(t.memoizedState!==null){if(oo(t),t.alternate===null)throw Error(i(340));Bi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(oo(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));Bi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return le(so),null;case 4:return ge(),null;case 10:return qi(t.type),null;case 22:case 23:return oo(t),$a(),e!==null&&le(ha),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return qi(ia),null;case 25:return null;default:return null}}function Ic(e,t){switch(Oi(t),t.tag){case 3:qi(ia),ge();break;case 26:case 27:case 5:ve(t);break;case 4:ge();break;case 31:t.memoizedState!==null&&oo(t);break;case 13:oo(t);break;case 19:le(so);break;case 10:qi(t.type);break;case 22:case 23:oo(t),$a(),e!==null&&le(ha);break;case 24:qi(ia)}}function Lc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Wu(t,t.return,e)}}function Rc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Wu(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Wu(t,t.return,e)}}function zc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Ja(t,n)}catch(t){Wu(e,e.return,t)}}}function Bc(e,t,n){n.props=Us(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Wu(e,t,n)}}function Vc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Wu(e,t,n)}}function Hc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null)if(typeof r==`function`)try{r()}catch(n){Wu(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Wu(e,t,n)}else n.current=null}function Uc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Wu(e,e.return,t)}}function Wc(e,t,n){try{var r=e.stateNode;yee(r,e.type,n,t),r[pt]=t}catch(t){Wu(e,e.return,t)}}function Gc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Jd(e.type)||e.tag===4}function Kc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Gc(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&&Jd(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function qc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=tn));else if(r!==4&&(r===27&&Jd(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(qc(e,t,n),e=e.sibling;e!==null;)qc(e,t,n),e=e.sibling}function Jc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&Jd(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Jc(e,t,n),e=e.sibling;e!==null;)Jc(e,t,n),e=e.sibling}function Yc(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Fd(t,r,n),t[ft]=e,t[pt]=n}catch(t){Wu(e,e.return,t)}}var Xc=!1,Zc=!1,Qc=!1,$c=typeof WeakSet==`function`?WeakSet:Set,el=null;function tl(e,t){if(e=e.containerInfo,Rd=ep,e=wr(e),Tr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var a=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||a!==0&&f.nodeType!==3||(c=s+a),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===a&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(zd={focusedElem:e,selectionRange:n},ep=!1,el=t;el!==null;)if(t=el,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,el=e;else for(;el!==null;){switch(t=el,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),Fd(o,r,n),o[ft]=e,Tt(o),r=o;break a;case`link`:var s=If(`link`,`href`,a).get(r+(n.href||``));if(s){for(var c=0;cg&&(o=g,g=h,h=o);var _=Sr(s,h),v=Sr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,M.T=null,n=uu,uu=null;var o=ou,s=cu;if(au=0,su=ou=null,cu=0,Fl&6)throw Error(i(331));var c=Fl;if(Fl|=4,jl(o.current),Cl(o,o.current,s,n),Fl=c,id(0,!1),Ve&&typeof Ve.onPostCommitFiberRoot==`function`)try{Ve.onPostCommitFiberRoot(Be,o)}catch{}return!0}finally{ie.p=a,M.T=r,Bu(e,t)}}function Uu(e,t,n){t=hi(n,t),t=Js(e.stateNode,t,2),e=Va(e,t,2),e!==null&&(nt(e,2),rd(e))}function Wu(e,t,n){if(e.tag===3)Uu(e,e,n);else for(;t!==null;){if(t.tag===3){Uu(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(iu===null||!iu.has(r))){e=hi(n,e),n=Ys(2),r=Va(t,n,2),r!==null&&(Xs(n,r,t,e),nt(r,2),rd(r));break}}t=t.return}}function Gu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new hee;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(Ul=!0,i.add(n),e=Ku.bind(null,e,t,n),t.then(e,e))}function Ku(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,Il===e&&(Rl&n)===n&&(Gl===4||Gl===3&&(Rl&62914560)===Rl&&300>je()-eu?!(Fl&2)&&Cu(e,0):Jl|=n,Xl===Rl&&(Xl=0)),rd(e)}function qu(e,t){t===0&&(t=et()),e=ei(e,t),e!==null&&(nt(e,t),rd(e))}function Ju(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),qu(e,n)}function Yu(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),qu(e,n)}function Xu(e,t){return De(e,t)}var Zu=null,Qu=null,$u=!1,ed=!1,td=!1,nd=0;function rd(e){e!==Qu&&e.next===null&&(Qu===null?Zu=Qu=e:Qu=Qu.next=e),ed=!0,$u||($u=!0,ld())}function id(e,t){if(!td&&ed){td=!0;do for(var n=!1,r=Zu;r!==null;){if(!t)if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-Ue(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,cd(r,a))}else a=Rl,a=Ze(r,r===Il?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||Qe(r,a)||(n=!0,cd(r,a));r=r.next}while(n);td=!1}}function vee(){ad()}function ad(){ed=$u=!1;var e=0;nd!==0&&bee()&&(e=nd);for(var t=je(),n=null,r=Zu;r!==null;){var i=r.next,a=od(r,t);a===0?(r.next=null,n===null?Zu=i:n.next=i,i===null&&(Qu=n)):(n=r,(e!==0||a&3)&&(ed=!0)),r=i}au!==0&&au!==5||id(e,!1),nd!==0&&(nd=0)}function od(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function vf(e,t,n){var r=_f;if(r&&typeof t==`string`&&t){var i=Vt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),ff.has(i)||(ff.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Fd(t,`link`,e),Tt(t),r.head.appendChild(t)))}}function yf(e){mf.D(e),vf(`dns-prefetch`,e,null)}function bf(e,t){mf.C(e,t),vf(`preconnect`,e,t)}function Cee(e,t,n){mf.L(e,t,n);var r=_f;if(r&&e&&t){var i=`link[rel="preload"][as="`+Vt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Vt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Vt(n.imageSizes)+`"]`)):i+=`[href="`+Vt(e)+`"]`;var a=i;switch(t){case`style`:a=Ef(e);break;case`script`:a=kf(e)}df.has(a)||(e=f({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),df.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(Df(a))||t===`script`&&r.querySelector(Af(a))||(t=r.createElement(`link`),Fd(t,`link`,e),Tt(t),r.head.appendChild(t)))}}function xf(e,t){mf.m(e,t);var n=_f;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Vt(r)+`"][href="`+Vt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=kf(e)}if(!df.has(a)&&(e=f({rel:`modulepreload`,href:e},t),df.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Af(a)))return}r=n.createElement(`link`),Fd(r,`link`,e),Tt(r),n.head.appendChild(r)}}}function Sf(e,t,n){mf.S(e,t,n);var r=_f;if(r&&e){var i=wt(r).hoistableStyles,a=Ef(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(Df(a)))s.loading=5;else{e=f({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=df.get(a))&&Nf(e,n);var c=o=r.createElement(`link`);Tt(c),Fd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Mf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Cf(e,t){mf.X(e,t);var n=_f;if(n&&e){var r=wt(n).hoistableScripts,i=kf(e),a=r.get(i);a||(a=n.querySelector(Af(i)),a||(e=f({src:e,async:!0},t),(t=df.get(i))&&Pf(e,t),a=n.createElement(`script`),Tt(a),Fd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function wf(e,t){mf.M(e,t);var n=_f;if(n&&e){var r=wt(n).hoistableScripts,i=kf(e),a=r.get(i);a||(a=n.querySelector(Af(i)),a||(e=f({src:e,async:!0,type:`module`},t),(t=df.get(i))&&Pf(e,t),a=n.createElement(`script`),Tt(a),Fd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Tf(e,t,n,r){var a=(a=pe.current)?pf(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Ef(n.href),n=wt(a).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Ef(n.href);var o=wt(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(Df(e)))&&!o._p&&(s.instance=o,s.state.loading=5),df.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},df.set(e,n),o||wee(a,e,n,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=kf(n),n=wt(a).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Ef(e){return`href="`+Vt(e)+`"`}function Df(e){return`link[rel="stylesheet"][`+e+`]`}function Of(e){return f({},e,{"data-precedence":e.precedence,precedence:null})}function wee(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Fd(t,`link`,n),Tt(t),e.head.appendChild(t))}function kf(e){return`[src="`+Vt(e)+`"]`}function Af(e){return`script[async]`+e}function jf(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Vt(n.href)+`"]`);if(r)return t.instance=r,Tt(r),r;var a=f({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),Tt(r),Fd(r,`style`,a),Mf(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Ef(n.href);var o=e.querySelector(Df(a));if(o)return t.state.loading|=4,t.instance=o,Tt(o),o;r=Of(n),(a=df.get(a))&&Nf(r,a),o=(e.ownerDocument||e).createElement(`link`),Tt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Fd(o,`link`,r),t.state.loading|=4,Mf(o,n.precedence,e),t.instance=o;case`script`:return o=kf(n.src),(a=e.querySelector(Af(o)))?(t.instance=a,Tt(a),a):(r=n,(a=df.get(o))&&(r=f({},n),Pf(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),Tt(a),Fd(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Mf(r,n.precedence,e));return t.instance}function Mf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Rf(e,t,n){if(n===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 zf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Tee(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Ef(r.href),a=t.querySelector(Df(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Vf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,Tt(a);return}a=t.ownerDocument||t,r=Of(r),(i=df.get(i))&&Nf(r,i),a=a.createElement(`link`),Tt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Fd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Vf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Bf=0;function Eee(e,t){return e.stylesheets&&e.count===0&&Uf(e,e.stylesheets),0Bf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Vf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Uf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Hf=null;function Uf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Hf=new Map,t.forEach(Wf,e),Hf=null,Vf.call(e))}function Wf(e,t){if(!(t.state.loading&4)){var n=Hf.get(e);if(n)var r=n.get(null);else{n=new Map,Hf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=v()})),b=`modulepreload`,x=function(e){return`/`+e},S={},C=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}r=o(t.map(t=>{if(t=x(t,n),t in S)return;S[t]=!0;let r=t.endsWith(`.css`),i=r?`[rel="stylesheet"]`:``;if(n)for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;let o=document.createElement(`link`);if(o.rel=r?`stylesheet`:b,r||(o.as=`script`),o.crossOrigin=``,o.href=t,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),r)return new Promise((e,n)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},w=u(p(),1),T=`popstate`;function E(e){return typeof e==`object`&&!!e&&`pathname`in e&&`search`in e&&`hash`in e&&`state`in e&&`key`in e}function D(e={}){function t(e,t){let n=t.state?.masked,{pathname:r,search:i,hash:a}=n||e.location;return te(``,{pathname:r,search:i,hash:a},t.state&&t.state.usr||null,t.state&&t.state.key||`default`,n?{pathname:e.location.pathname,search:e.location.search,hash:e.location.hash}:void 0)}function n(e,t){return typeof t==`string`?t:j(t)}return re(t,n,null,e)}function O(e,t){if(e===!1||e==null)throw Error(t)}function k(e,t){if(!e){typeof console<`u`&&console.warn(t);try{throw Error(t)}catch{}}}function A(){return Math.random().toString(36).substring(2,10)}function ee(e,t){return{usr:e.state,key:e.key,idx:t,masked:e.unstable_mask?{pathname:e.pathname,search:e.search,hash:e.hash}:void 0}}function te(e,t,n=null,r,i){return{pathname:typeof e==`string`?e:e.pathname,search:``,hash:``,...typeof t==`string`?ne(t):t,state:n,key:t&&t.key||r||A(),unstable_mask:i}}function j({pathname:e=`/`,search:t=``,hash:n=``}){return t&&t!==`?`&&(e+=t.charAt(0)===`?`?t:`?`+t),n&&n!==`#`&&(e+=n.charAt(0)===`#`?n:`#`+n),e}function ne(e){let t={};if(e){let n=e.indexOf(`#`);n>=0&&(t.hash=e.substring(n),e=e.substring(0,n));let r=e.indexOf(`?`);r>=0&&(t.search=e.substring(r),e=e.substring(0,r)),e&&(t.pathname=e)}return t}function re(e,t,n,r={}){let{window:i=document.defaultView,v5Compat:a=!1}=r,o=i.history,s=`POP`,c=null,l=u();l??(l=0,o.replaceState({...o.state,idx:l},``));function u(){return(o.state||{idx:null}).idx}function d(){s=`POP`;let e=u(),t=e==null?null:e-l;l=e,c&&c({action:s,location:h.location,delta:t})}function f(e,t){s=`PUSH`;let r=E(e)?e:te(h.location,e,t);n&&n(r,e),l=u()+1;let d=ee(r,l),f=h.createHref(r.unstable_mask||r);try{o.pushState(d,``,f)}catch(e){if(e instanceof DOMException&&e.name===`DataCloneError`)throw e;i.location.assign(f)}a&&c&&c({action:s,location:h.location,delta:1})}function p(e,t){s=`REPLACE`;let r=E(e)?e:te(h.location,e,t);n&&n(r,e),l=u();let i=ee(r,l),d=h.createHref(r.unstable_mask||r);o.replaceState(i,``,d),a&&c&&c({action:s,location:h.location,delta:0})}function m(e){return M(e)}let h={get action(){return s},get location(){return e(i,o)},listen(e){if(c)throw Error(`A history only accepts one active listener`);return i.addEventListener(T,d),c=e,()=>{i.removeEventListener(T,d),c=null}},createHref(e){return t(i,e)},createURL:m,encodeLocation(e){let t=m(e);return{pathname:t.pathname,search:t.search,hash:t.hash}},push:f,replace:p,go(e){return o.go(e)}};return h}function M(e,t=!1){let n=`http://localhost`;typeof window<`u`&&(n=window.location.origin===`null`?window.location.href:window.location.origin),O(n,`No window.location.(origin|href) available to create URL`);let r=typeof e==`string`?e:j(e);return r=r.replace(/ $/,`%20`),!t&&r.startsWith(`//`)&&(r=n+r),new URL(r,n)}function ie(e,t,n=`/`){return ae(e,t,n,!1)}function ae(e,t,n,r){let i=Ce((typeof t==`string`?ne(t):t).pathname||`/`,n);if(i==null)return null;let a=se(e);le(a);let o=null;for(let e=0;o==null&&e{let c={relativePath:s===void 0?e.path||``:s,caseSensitive:e.caseSensitive===!0,childrenIndex:a,route:e};if(c.relativePath.startsWith(`/`)){if(!c.relativePath.startsWith(r)&&o)return;O(c.relativePath.startsWith(r),`Absolute route path "${c.relativePath}" nested under path "${r}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),c.relativePath=c.relativePath.slice(r.length)}let l=je([r,c.relativePath]),u=n.concat(c);e.children&&e.children.length>0&&(O(e.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${l}".`),se(e.children,t,u,l,o)),!(e.path==null&&!e.index)&&t.push({path:l,score:_e(l,e.index),routesMeta:u})};return e.forEach((e,t)=>{if(e.path===``||!e.path?.includes(`?`))a(e,t);else for(let n of ce(e.path))a(e,t,!0,n)}),t}function ce(e){let t=e.split(`/`);if(t.length===0)return[];let[n,...r]=t,i=n.endsWith(`?`),a=n.replace(/\?$/,``);if(r.length===0)return i?[a,``]:[a];let o=ce(r.join(`/`)),s=[];return s.push(...o.map(e=>e===``?a:[a,e].join(`/`))),i&&s.push(...o),s.map(t=>e.startsWith(`/`)&&t===``?`/`:t)}function le(e){e.sort((e,t)=>e.score===t.score?ve(e.routesMeta.map(e=>e.childrenIndex),t.routesMeta.map(e=>e.childrenIndex)):t.score-e.score)}var ue=/^:[\w-]+$/,de=3,fe=2,pe=1,me=10,he=-2,ge=e=>e===`*`;function _e(e,t){let n=e.split(`/`),r=n.length;return n.some(ge)&&(r+=he),t&&(r+=fe),n.filter(e=>!ge(e)).reduce((e,t)=>e+(ue.test(t)?de:t===``?pe:me),r)}function ve(e,t){return e.length===t.length&&e.slice(0,-1).every((e,n)=>e===t[n])?e[e.length-1]-t[t.length-1]:0}function ye(e,t,n=!1){let{routesMeta:r}=e,i={},a=`/`,o=[];for(let e=0;e{if(t===`*`){let e=s[r]||``;o=a.slice(0,a.length-e.length).replace(/(.)\/+$/,`$1`)}let i=s[r];return n&&!i?e[t]=void 0:e[t]=(i||``).replace(/%2F/g,`/`),e},{}),pathname:a,pathnameBase:o,pattern:e}}function xe(e,t=!1,n=!0){k(e===`*`||!e.endsWith(`*`)||e.endsWith(`/*`),`Route path "${e}" will be treated as if it were "${e.replace(/\*$/,`/*`)}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${e.replace(/\*$/,`/*`)}".`);let r=[],i=`^`+e.replace(/\/*\*?$/,``).replace(/^\/*/,`/`).replace(/[\\.*+^${}|()[\]]/g,`\\$&`).replace(/\/:([\w-]+)(\?)?/g,(e,t,n,i,a)=>{if(r.push({paramName:t,isOptional:n!=null}),n){let t=a.charAt(i+e.length);return t&&t!==`/`?`/([^\\/]*)`:`(?:/([^\\/]*))?`}return`/([^\\/]+)`}).replace(/\/([\w-]+)\?(\/|$)/g,`(/$1)?$2`);return e.endsWith(`*`)?(r.push({paramName:`*`}),i+=e===`*`||e===`/*`?`(.*)$`:`(?:\\/(.+)|\\/*)$`):n?i+=`\\/*$`:e!==``&&e!==`/`&&(i+=`(?:(?=\\/|$))`),[new RegExp(i,t?void 0:`i`),r]}function Se(e){try{return e.split(`/`).map(e=>decodeURIComponent(e).replace(/\//g,`%2F`)).join(`/`)}catch(t){return k(!1,`The URL path "${e}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${t}).`),e}}function Ce(e,t){if(t===`/`)return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith(`/`)?t.length-1:t.length,r=e.charAt(n);return r&&r!==`/`?null:e.slice(n)||`/`}var we=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function Te(e,t=`/`){let{pathname:n,search:r=``,hash:i=``}=typeof e==`string`?ne(e):e,a;return n?(n=n.replace(/\/\/+/g,`/`),a=n.startsWith(`/`)?Ee(n.substring(1),`/`):Ee(n,t)):a=t,{pathname:a,search:Ne(r),hash:Pe(i)}}function Ee(e,t){let n=t.replace(/\/+$/,``).split(`/`);return e.split(`/`).forEach(e=>{e===`..`?n.length>1&&n.pop():e!==`.`&&n.push(e)}),n.length>1?n.join(`/`):`/`}function De(e,t,n,r){return`Cannot include a '${e}' character in a manually specified \`to.${t}\` field [${JSON.stringify(r)}]. Please separate it out to the \`to.${n}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function Oe(e){return e.filter((e,t)=>t===0||e.route.path&&e.route.path.length>0)}function ke(e){let t=Oe(e);return t.map((e,n)=>n===t.length-1?e.pathname:e.pathnameBase)}function Ae(e,t,n,r=!1){let i;typeof e==`string`?i=ne(e):(i={...e},O(!i.pathname||!i.pathname.includes(`?`),De(`?`,`pathname`,`search`,i)),O(!i.pathname||!i.pathname.includes(`#`),De(`#`,`pathname`,`hash`,i)),O(!i.search||!i.search.includes(`#`),De(`#`,`search`,`hash`,i)));let a=e===``||i.pathname===``,o=a?`/`:i.pathname,s;if(o==null)s=n;else{let e=t.length-1;if(!r&&o.startsWith(`..`)){let t=o.split(`/`);for(;t[0]===`..`;)t.shift(),--e;i.pathname=t.join(`/`)}s=e>=0?t[e]:`/`}let c=Te(i,s),l=o&&o!==`/`&&o.endsWith(`/`),u=(a||o===`.`)&&n.endsWith(`/`);return!c.pathname.endsWith(`/`)&&(l||u)&&(c.pathname+=`/`),c}var je=e=>e.join(`/`).replace(/\/\/+/g,`/`),Me=e=>e.replace(/\/+$/,``).replace(/^\/*/,`/`),Ne=e=>!e||e===`?`?``:e.startsWith(`?`)?e:`?`+e,Pe=e=>!e||e===`#`?``:e.startsWith(`#`)?e:`#`+e,Fe=class{constructor(e,t,n,r=!1){this.status=e,this.statusText=t||``,this.internal=r,n instanceof Error?(this.data=n.toString(),this.error=n):this.data=n}};function Ie(e){return e!=null&&typeof e.status==`number`&&typeof e.statusText==`string`&&typeof e.internal==`boolean`&&`data`in e}function Le(e){return e.map(e=>e.route.path).filter(Boolean).join(`/`).replace(/\/\/*/g,`/`)||`/`}var Re=typeof window<`u`&&window.document!==void 0&&window.document.createElement!==void 0;function ze(e,t){let n=e;if(typeof n!=`string`||!we.test(n))return{absoluteURL:void 0,isExternal:!1,to:n};let r=n,i=!1;if(Re)try{let e=new URL(window.location.href),r=n.startsWith(`//`)?new URL(e.protocol+n):new URL(n),a=Ce(r.pathname,t);r.origin===e.origin&&a!=null?n=a+r.search+r.hash:i=!0}catch{k(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:r,isExternal:i,to:n}}Object.getOwnPropertyNames(Object.prototype).sort().join(`\0`);var Be=[`POST`,`PUT`,`PATCH`,`DELETE`];new Set(Be);var Ve=[`GET`,...Be];new Set(Ve);var He=w.createContext(null);He.displayName=`DataRouter`;var Ue=w.createContext(null);Ue.displayName=`DataRouterState`;var We=w.createContext(!1),Ge=w.createContext({isTransitioning:!1});Ge.displayName=`ViewTransition`;var Ke=w.createContext(new Map);Ke.displayName=`Fetchers`;var qe=w.createContext(null);qe.displayName=`Await`;var Je=w.createContext(null);Je.displayName=`Navigation`;var Ye=w.createContext(null);Ye.displayName=`Location`;var Xe=w.createContext({outlet:null,matches:[],isDataRoute:!1});Xe.displayName=`Route`;var Ze=w.createContext(null);Ze.displayName=`RouteError`;var Qe=`REACT_ROUTER_ERROR`,$e=`REDIRECT`,et=`ROUTE_ERROR_RESPONSE`;function tt(e){if(e.startsWith(`${Qe}:${$e}:{`))try{let t=JSON.parse(e.slice(28));if(typeof t==`object`&&t&&typeof t.status==`number`&&typeof t.statusText==`string`&&typeof t.location==`string`&&typeof t.reloadDocument==`boolean`&&typeof t.replace==`boolean`)return t}catch{}}function nt(e){if(e.startsWith(`${Qe}:${et}:{`))try{let t=JSON.parse(e.slice(40));if(typeof t==`object`&&t&&typeof t.status==`number`&&typeof t.statusText==`string`)return new Fe(t.status,t.statusText,t.data)}catch{}}function rt(e,{relative:t}={}){O(it(),`useHref() may be used only in the context of a component.`);let{basename:n,navigator:r}=w.useContext(Je),{hash:i,pathname:a,search:o}=dt(e,{relative:t}),s=a;return n!==`/`&&(s=a===`/`?n:je([n,a])),r.createHref({pathname:s,search:o,hash:i})}function it(){return w.useContext(Ye)!=null}function at(){return O(it(),`useLocation() may be used only in the context of a component.`),w.useContext(Ye).location}var ot=`You should call navigate() in a React.useEffect(), not when your component is first rendered.`;function st(e){w.useContext(Je).static||w.useLayoutEffect(e)}function ct(){let{isDataRoute:e}=w.useContext(Xe);return e?eee():lt()}function lt(){O(it(),`useNavigate() may be used only in the context of a component.`);let e=w.useContext(He),{basename:t,navigator:n}=w.useContext(Je),{matches:r}=w.useContext(Xe),{pathname:i}=at(),a=JSON.stringify(ke(r)),o=w.useRef(!1);return st(()=>{o.current=!0}),w.useCallback((r,s={})=>{if(k(o.current,ot),!o.current)return;if(typeof r==`number`){n.go(r);return}let c=Ae(r,JSON.parse(a),i,s.relative===`path`);e==null&&t!==`/`&&(c.pathname=c.pathname===`/`?t:je([t,c.pathname])),(s.replace?n.replace:n.push)(c,s.state,s)},[t,n,a,i,e])}w.createContext(null);function ut(){let{matches:e}=w.useContext(Xe),t=e[e.length-1];return t?t.params:{}}function dt(e,{relative:t}={}){let{matches:n}=w.useContext(Xe),{pathname:r}=at(),i=JSON.stringify(ke(n));return w.useMemo(()=>Ae(e,JSON.parse(i),r,t===`path`),[e,i,r,t])}function ft(e,t){return pt(e,t)}function pt(e,t,n){O(it(),`useRoutes() may be used only in the context of a component.`);let{navigator:r}=w.useContext(Je),{matches:i}=w.useContext(Xe),a=i[i.length-1],o=a?a.params:{},s=a?a.pathname:`/`,c=a?a.pathnameBase:`/`,l=a&&a.route;{let e=l&&l.path||``;jt(s,!l||e.endsWith(`*`)||e.endsWith(`*?`),`You rendered descendant (or called \`useRoutes()\`) at "${s}" (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 u=at(),d;if(t){let e=typeof t==`string`?ne(t):t;O(c===`/`||e.pathname?.startsWith(c),`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 "${c}" but pathname "${e.pathname}" was given in the \`location\` prop.`),d=e}else d=u;let f=d.pathname||`/`,p=f;if(c!==`/`){let e=c.replace(/^\//,``).split(`/`);p=`/`+f.replace(/^\//,``).split(`/`).slice(e.length).join(`/`)}let m=ie(e,{pathname:p});k(l||m!=null,`No routes matched location "${d.pathname}${d.search}${d.hash}" `),k(m==null||m[m.length-1].route.element!==void 0||m[m.length-1].route.Component!==void 0||m[m.length-1].route.lazy!==void 0,`Matched leaf route at location "${d.pathname}${d.search}${d.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 h=bt(m&&m.map(e=>Object.assign({},e,{params:Object.assign({},o,e.params),pathname:je([c,r.encodeLocation?r.encodeLocation(e.pathname.replace(/\?/g,`%3F`).replace(/#/g,`%23`)).pathname:e.pathname]),pathnameBase:e.pathnameBase===`/`?c:je([c,r.encodeLocation?r.encodeLocation(e.pathnameBase.replace(/\?/g,`%3F`).replace(/#/g,`%23`)).pathname:e.pathnameBase])})),i,n);return t&&h?w.createElement(Ye.Provider,{value:{location:{pathname:`/`,search:``,hash:``,state:null,key:`default`,unstable_mask:void 0,...d},navigationType:`POP`}},h):h}function mt(){let e=kt(),t=Ie(e)?`${e.status} ${e.statusText}`:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,r=`rgba(200,200,200, 0.5)`,i={padding:`0.5rem`,backgroundColor:r},a={padding:`2px 4px`,backgroundColor:r},o=null;return console.error(`Error handled by React Router default ErrorBoundary:`,e),o=w.createElement(w.Fragment,null,w.createElement(`p`,null,`💿 Hey developer 👋`),w.createElement(`p`,null,`You can provide a way better UX than this when your app throws errors by providing your own `,w.createElement(`code`,{style:a},`ErrorBoundary`),` or`,` `,w.createElement(`code`,{style:a},`errorElement`),` prop on your route.`)),w.createElement(w.Fragment,null,w.createElement(`h2`,null,`Unexpected Application Error!`),w.createElement(`h3`,{style:{fontStyle:`italic`}},t),n?w.createElement(`pre`,{style:i},n):null,o)}var ht=w.createElement(mt,null),gt=class extends w.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||t.revalidation!==`idle`&&e.revalidation===`idle`?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error===void 0?t.error:e.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){this.props.onError?this.props.onError(e,t):console.error(`React Router caught the following error during render`,e)}render(){let e=this.state.error;if(this.context&&typeof e==`object`&&e&&`digest`in e&&typeof e.digest==`string`){let t=nt(e.digest);t&&(e=t)}let t=e===void 0?this.props.children:w.createElement(Xe.Provider,{value:this.props.routeContext},w.createElement(Ze.Provider,{value:e,children:this.props.component}));return this.context?w.createElement(vt,{error:e},t):t}};gt.contextType=We;var _t=new WeakMap;function vt({children:e,error:t}){let{basename:n}=w.useContext(Je);if(typeof t==`object`&&t&&`digest`in t&&typeof t.digest==`string`){let e=tt(t.digest);if(e){let r=_t.get(t);if(r)throw r;let i=ze(e.location,n);if(Re&&!_t.get(t))if(i.isExternal||e.reloadDocument)window.location.href=i.absoluteURL||i.to;else{let n=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(i.to,{replace:e.replace}));throw _t.set(t,n),n}return w.createElement(`meta`,{httpEquiv:`refresh`,content:`0;url=${i.absoluteURL||i.to}`})}}return e}function yt({routeContext:e,match:t,children:n}){let r=w.useContext(He);return r&&r.static&&r.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=t.route.id),w.createElement(Xe.Provider,{value:e},n)}function bt(e,t=[],n){let r=n?.state;if(e==null){if(!r)return null;if(r.errors)e=r.matches;else if(t.length===0&&!r.initialized&&r.matches.length>0)e=r.matches;else return null}let i=e,a=r?.errors;if(a!=null){let e=i.findIndex(e=>e.route.id&&a?.[e.route.id]!==void 0);O(e>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(a).join(`,`)}`),i=i.slice(0,Math.min(i.length,e+1))}let o=!1,s=-1;if(n&&r){o=r.renderFallback;for(let e=0;e=0?i.slice(0,s+1):[i[0]];break}}}}let c=n?.onError,l=r&&c?(e,t)=>{c(e,{location:r.location,params:r.matches?.[0]?.params??{},unstable_pattern:Le(r.matches),errorInfo:t})}:void 0;return i.reduceRight((e,n,c)=>{let u,d=!1,f=null,p=null;r&&(u=a&&n.route.id?a[n.route.id]:void 0,f=n.route.errorElement||ht,o&&(s<0&&c===0?(jt(`route-fallback`,!1,"No `HydrateFallback` element provided to render during initial hydration"),d=!0,p=null):s===c&&(d=!0,p=n.route.hydrateFallbackElement||null)));let m=t.concat(i.slice(0,c+1)),h=()=>{let t;return t=u?f:d?p:n.route.Component?w.createElement(n.route.Component,null):n.route.element?n.route.element:e,w.createElement(yt,{match:n,routeContext:{outlet:e,matches:m,isDataRoute:r!=null},children:t})};return r&&(n.route.ErrorBoundary||n.route.errorElement||c===0)?w.createElement(gt,{location:r.location,revalidation:r.revalidation,component:f,error:u,children:h(),routeContext:{outlet:null,matches:m,isDataRoute:!0},onError:l}):h()},null)}function xt(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function St(e){let t=w.useContext(He);return O(t,xt(e)),t}function Ct(e){let t=w.useContext(Ue);return O(t,xt(e)),t}function wt(e){let t=w.useContext(Xe);return O(t,xt(e)),t}function Tt(e){let t=wt(e),n=t.matches[t.matches.length-1];return O(n.route.id,`${e} can only be used on routes that contain a unique "id"`),n.route.id}function Et(){return Tt(`useRouteId`)}function Dt(){return Ct(`useNavigation`).navigation}function Ot(){let{matches:e,loaderData:t}=Ct(`useMatches`);return w.useMemo(()=>e.map(e=>oe(e,t)),[e,t])}function kt(){let e=w.useContext(Ze),t=Ct(`useRouteError`),n=Tt(`useRouteError`);return e===void 0?t.errors?.[n]:e}function eee(){let{router:e}=St(`useNavigate`),t=Tt(`useNavigate`),n=w.useRef(!1);return st(()=>{n.current=!0}),w.useCallback(async(r,i={})=>{k(n.current,ot),n.current&&(typeof r==`number`?await e.navigate(r):await e.navigate(r,{fromRouteId:t,...i}))},[e,t])}var At={};function jt(e,t,n){!t&&!At[e]&&(At[e]=!0,k(!1,n))}w.useOptimistic,w.memo(tee);function tee({routes:e,future:t,state:n,isStatic:r,onError:i}){return pt(e,void 0,{state:n,isStatic:r,onError:i,future:t})}function Mt(e){O(!1,`A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .`)}function Nt({basename:e=`/`,children:t=null,location:n,navigationType:r=`POP`,navigator:i,static:a=!1,unstable_useTransitions:o}){O(!it(),`You cannot render a inside another . You should never have more than one in your app.`);let s=e.replace(/^\/*/,`/`),c=w.useMemo(()=>({basename:s,navigator:i,static:a,unstable_useTransitions:o,future:{}}),[s,i,a,o]);typeof n==`string`&&(n=ne(n));let{pathname:l=`/`,search:u=``,hash:d=``,state:f=null,key:p=`default`,unstable_mask:m}=n,h=w.useMemo(()=>{let e=Ce(l,s);return e==null?null:{location:{pathname:e,search:u,hash:d,state:f,key:p,unstable_mask:m},navigationType:r}},[s,l,u,d,f,p,r,m]);return k(h!=null,` is not able to match the URL "${l}${u}${d}" because it does not start with the basename, so the won't render anything.`),h==null?null:w.createElement(Je.Provider,{value:c},w.createElement(Ye.Provider,{children:t,value:h}))}function Pt({children:e,location:t}){return ft(Ft(e),t)}function Ft(e,t=[]){let n=[];return w.Children.forEach(e,(e,r)=>{if(!w.isValidElement(e))return;let i=[...t,r];if(e.type===w.Fragment){n.push.apply(n,Ft(e.props.children,i));return}O(e.type===Mt,`[${typeof e.type==`string`?e.type:e.type.name}] is not a component. All component children of must be a or `),O(!e.props.index||!e.props.children,`An index route cannot have child routes.`);let a={id:e.props.id||i.join(`-`),caseSensitive:e.props.caseSensitive,element:e.props.element,Component:e.props.Component,index:e.props.index,path:e.props.path,middleware:e.props.middleware,loader:e.props.loader,action:e.props.action,hydrateFallbackElement:e.props.hydrateFallbackElement,HydrateFallback:e.props.HydrateFallback,errorElement:e.props.errorElement,ErrorBoundary:e.props.ErrorBoundary,hasErrorBoundary:e.props.hasErrorBoundary===!0||e.props.ErrorBoundary!=null||e.props.errorElement!=null,shouldRevalidate:e.props.shouldRevalidate,handle:e.props.handle,lazy:e.props.lazy};e.props.children&&(a.children=Ft(e.props.children,i)),n.push(a)}),n}var It=`get`,Lt=`application/x-www-form-urlencoded`;function Rt(e){return typeof HTMLElement<`u`&&e instanceof HTMLElement}function zt(e){return Rt(e)&&e.tagName.toLowerCase()===`button`}function Bt(e){return Rt(e)&&e.tagName.toLowerCase()===`form`}function nee(e){return Rt(e)&&e.tagName.toLowerCase()===`input`}function Vt(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function Ht(e,t){return e.button===0&&(!t||t===`_self`)&&!Vt(e)}function Ut(e=``){return new URLSearchParams(typeof e==`string`||Array.isArray(e)||e instanceof URLSearchParams?e:Object.keys(e).reduce((t,n)=>{let r=e[n];return t.concat(Array.isArray(r)?r.map(e=>[n,e]):[[n,r]])},[]))}function Wt(e,t){let n=Ut(e);return t&&t.forEach((e,r)=>{n.has(r)||t.getAll(r).forEach(e=>{n.append(r,e)})}),n}var Gt=null;function Kt(){if(Gt===null)try{new FormData(document.createElement(`form`),0),Gt=!1}catch{Gt=!0}return Gt}var qt=new Set([`application/x-www-form-urlencoded`,`multipart/form-data`,`text/plain`]);function Jt(e){return e!=null&&!qt.has(e)?(k(!1,`"${e}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${Lt}"`),null):e}function Yt(e,t){let n,r,i,a,o;if(Bt(e)){let o=e.getAttribute(`action`);r=o?Ce(o,t):null,n=e.getAttribute(`method`)||It,i=Jt(e.getAttribute(`enctype`))||Lt,a=new FormData(e)}else if(zt(e)||nee(e)&&(e.type===`submit`||e.type===`image`)){let o=e.form;if(o==null)throw Error(`Cannot submit a - - - - -
- - - - val.toFixed(3)} - label={{ value: 'Disorder Delta (Δ pLDDT)', position: 'bottom', fill: '#888', fontSize: 10, fontFamily: 'monospace' }} - /> - val.toFixed(3)} - label={{ value: 'Druggability Score', angle: -90, position: 'left', fill: '#888', fontSize: 10, fontFamily: 'monospace' }} - /> - [value.toFixed(3), name]} - /> - a.avg_delta - b.avg_delta)} - line={{ stroke: '#555', strokeWidth: 1.5, strokeDasharray: '4 4' }} - > - {data.map((entry, index) => ( - = 5.0 ? '#10b981' : '#9ca3af'} /> - ))} - - - - {data.every(d => Math.abs(d.avg_delta) < 0.001) && ( -
- - Disorder Delta data not available - -
- )} -
- {!isReset && ( -

- Scroll to zoom · Drag to pan · Click reset to restore -

- )} - - ); -} - -export function ComparisonTab({ - comparison, - activePocketIdx, - handleHighlight, - monomerStructureUrl, - complexStructureUrl, - onConformationChange -}) { - if (!comparison) return ( -
- Comparison data not available. -
- ); - - const { - summary_metrics, - ddgi, - pocket_mapping, - interface_pockets, - conserved_pockets, - emergent_pockets, - graph_datasets, - property_changes, - stabilization_stats, - fragment_comparison - } = comparison; - - const hasScatterData = graph_datasets?.stabilization_scatter && graph_datasets.stabilization_scatter.length > 0; - - return ( -
- {/* 1. Summary Metrics & DDGI */} -
-
- Total Monomer Pockets - {summary_metrics.total_monomer_pockets} -
-
- Total Complex Pockets - {summary_metrics.total_dimer_pockets} -
-
- True Interface Pockets - {pocket_mapping.interface_count} -
-
0 ? 'border-success/50' : 'border-danger/50'}`}> - - DDGI Score -
- Dimerization Druggability Gain Index: Avg Dimer Score - Avg Monomer Score -
-
- 0 ? 'text-success' : 'text-danger'}`}> - {ddgi > 0 ? '+' : ''}{ddgi.toFixed(3)} - -
-
- - {/* 2. Pocket Mapping & Property Changes */} -
- {/* Pocket Mapping */} -
-

Pocket Transition Map

-
-
- Conserved in both states - {pocket_mapping.conserved_count} -
-
- Disappeared upon dimerization - {pocket_mapping.monomer_only_count} -
-
- Newly emerged in dimer - {pocket_mapping.emergent_count} -
-
- -
-
Residue Stabilization Analysis
-
- Interface Residue Enrichment - {stabilization_stats.enrichment_score.toFixed(2)}x -
-
-
- - {/* Changes */} -
-

Average Property Shifts

-
- {/* Vol */} -
-
- Avg Volume - {property_changes.monomer_avg_volume.toFixed(0)} → {property_changes.dimer_avg_volume.toFixed(0)} ų -
-
- {/* Hydrophobicity */} -
-
- Avg Hydrophobicity - {property_changes.monomer_avg_hydrophobicity.toFixed(2)} → {property_changes.dimer_avg_hydrophobicity.toFixed(2)} -
-
- {/* Polarity */} -
-
- Avg Polarity - {property_changes.monomer_avg_polarity.toFixed(2)} → {property_changes.dimer_avg_polarity.toFixed(2)} -
-
- {/* Score */} -
-
- Avg Druggability - 0 ? 'text-success' : 'text-danger'}> - {summary_metrics.avg_monomer_druggability.toFixed(3)} → {summary_metrics.avg_dimer_druggability.toFixed(3)} - -
-
-
-
-
- - {/* 3. Charts */} - {hasScatterData && ( - - )} - - {/* 4. True Interface Pockets */} -
-

-
- True Interface Drug Targets -

-

- Pockets spanning multiple protein chains at the dimer interaction surface. -

- -
- - - - - - - - - - - - - - - - {interface_pockets && interface_pockets.length > 0 ? ( - interface_pockets.map((pocket, idx) => ( - - handleHighlight(residueIndices, `int-${idx}`, comparisonHighlightTarget(pocket)) - } - proteinPdbId={complexStructureUrl} - sourceType="dimer" - onConformationChange={(confs, mode) => - onConformationChange?.(confs, mode, comparisonHighlightTarget(pocket)) - } - /> - )) - ) : ( - - - - )} - -
IDScoreVolHydroPolarΔ pLDDTCenterResiduesActions
- No true interface pockets found. -
-
-
- - {/* 5b. Conserved Pockets */} -
-

-
- Conserved Pockets -

-

- Pockets retained from monomer to dimer — spatially overlapping in both structures. -

- -
- - - - - - - - - - - - - - - - {conserved_pockets && conserved_pockets.length > 0 ? ( - conserved_pockets.map((pocket, idx) => ( - - handleHighlight(residueIndices, `con-${idx}`, comparisonHighlightTarget(pocket)) - } - proteinPdbId={complexStructureUrl} - sourceType="dimer" - onConformationChange={(confs, mode) => - onConformationChange?.(confs, mode, comparisonHighlightTarget(pocket)) - } - /> - )) - ) : ( - - - - )} - -
IDScoreVolHydroPolarΔ pLDDTCenterResiduesActions
- No conserved pockets found — all monomer pockets were restructured. -
-
-
- - {/* 5. Emergent Monomer-Dimer Pockets */} -
-

-
- Emergent Dimer-only Pockets -

-

- Pockets that physically appear in the dimer but belong to a single chain (structural rearrangement). -

- -
- - - - - - - - - - - - - - - - {emergent_pockets && emergent_pockets.length > 0 ? ( - emergent_pockets.map((pocket, idx) => ( - - handleHighlight(residueIndices, `emg-${idx}`, comparisonHighlightTarget(pocket)) - } - proteinPdbId={complexStructureUrl} - sourceType="dimer" - onConformationChange={(confs, mode) => - onConformationChange?.(confs, mode, comparisonHighlightTarget(pocket)) - } - /> - )) - ) : ( - - - - )} - -
IDScoreVolHydroPolarΔ pLDDTCenterResiduesActions
- No emergent structural pockets found. -
-
-
- - {/* 6. Fragment Comparison — ChEMBL novel compounds */} - {fragment_comparison && ( - (fragment_comparison.unique_interface_fragments?.length > 0 || - fragment_comparison.unique_dimer_fragments?.length > 0) && ( -
-
-

- - - - Novel ChEMBL Fragment Suggestions -

-

- Compounds from the ChEMBL database unique to the dimerized state — not suggested for any monomer pocket. -

-
- -
- {/* Interface-specific fragments (highest value) */} -
-
-
- Interface Pocket Fragments -
- - {fragment_comparison.unique_interface_fragments?.length || 0} compounds - -
-

- Fragments targeting pockets at the protein-protein interface — highest value for PPI inhibitor design. -

- -
- - {/* Dimer-unique fragments */} -
-
-
- Dimer-only Fragments -
- - {fragment_comparison.unique_dimer_fragments?.length || 0} compounds - -
-

- Fragments unique to any dimer pocket (including emergent and conserved) not found in monomer analysis. -

- -
-
-
- ) - )} - -
- ); -} diff --git a/app/src/components/complex/ComparisonTab.tsx b/app/src/components/complex/ComparisonTab.tsx new file mode 100644 index 0000000..5c65001 --- /dev/null +++ b/app/src/components/complex/ComparisonTab.tsx @@ -0,0 +1,305 @@ +import React, { useState, useCallback, useRef, useMemo } from 'react'; +import { + BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, + ScatterChart, Scatter, ZAxis, Cell +} from 'recharts'; +import { PocketTableRow } from './PocketTableRow'; +import { FragmentList } from './FragmentList'; +import type { Pocket, ComparisonData, ScatterDataPoint, Conformation } from '../../types'; + +/** Mol* target from comparison tab */ +function comparisonHighlightTarget(pocket: Pocket): string { + return pocket.is_conserved ? 'both' : 'complex'; +} + +const CHART_MARGIN = { top: 10, right: 30, bottom: 20, left: 40 }; +const ZOOM_FACTOR = 1.3; +const MIN_ZOOM = 0.25; +const MAX_ZOOM = 8; + +interface Viewport { xMin: number; xMax: number; yMin: number; yMax: number; } + +function ScatterChartWithZoom({ data }: { data: ScatterDataPoint[] }) { + const fullExtent = useMemo(() => { + const xValues = data.map(d => d.avg_delta); + const yValues = data.map(d => d.druggability_score); + return { + xMin: Math.min(-5, Math.min(...xValues) - 1), + xMax: Math.max(5, Math.max(...xValues) + 1), + yMin: Math.min(...yValues) - 0.05, + yMax: Math.max(...yValues) + 0.05, + }; + }, [data]); + + const [viewport, setViewport] = useState(null); + const vp = viewport || fullExtent; + + const zoomLevel = useMemo(() => { + const fullW = fullExtent.xMax - fullExtent.xMin; + const curW = vp.xMax - vp.xMin; + return curW > 0 ? fullW / curW : 1; + }, [fullExtent, vp]); + + const chartRef = useRef(null); + const dragRef = useRef<{ startX: number; startY: number; vpStart: Viewport } | null>(null); + + const pixelToData = useCallback((px: number, py: number, containerRect: DOMRect) => { + const plotLeft = CHART_MARGIN.left; + const plotTop = CHART_MARGIN.top; + const plotWidth = containerRect.width - CHART_MARGIN.left - CHART_MARGIN.right; + const plotHeight = containerRect.height - CHART_MARGIN.top - CHART_MARGIN.bottom; + const fx = Math.max(0, Math.min(1, (px - plotLeft) / plotWidth)); + const fy = Math.max(0, Math.min(1, 1 - (py - plotTop) / plotHeight)); + return { + dataX: vp.xMin + fx * (vp.xMax - vp.xMin), + dataY: vp.yMin + fy * (vp.yMax - vp.yMin), + }; + }, [vp]); + + React.useEffect(() => { + const chartEl = chartRef.current; + if (!chartEl) return; + const onWheelNative = (e: WheelEvent) => { + e.preventDefault(); + const rect = chartEl.getBoundingClientRect(); + const px = e.clientX - rect.left; + const py = e.clientY - rect.top; + const { dataX, dataY } = pixelToData(px, py, rect); + const isZoomIn = e.deltaY < 0; + const factor = isZoomIn ? 1 / ZOOM_FACTOR : ZOOM_FACTOR; + const newXMin = dataX - (dataX - vp.xMin) * factor; + const newXMax = dataX + (vp.xMax - dataX) * factor; + const newYMin = dataY - (dataY - vp.yMin) * factor; + const newYMax = dataY + (vp.yMax - dataY) * factor; + const newW = newXMax - newXMin; + const fullW = fullExtent.xMax - fullExtent.xMin; + const newZoom = fullW / newW; + if (newZoom < MIN_ZOOM || newZoom > MAX_ZOOM) return; + setViewport({ xMin: newXMin, xMax: newXMax, yMin: newYMin, yMax: newYMax }); + }; + chartEl.addEventListener('wheel', onWheelNative, { passive: false }); + return () => chartEl.removeEventListener('wheel', onWheelNative); + }, [vp, fullExtent, pixelToData]); + + const handleMouseDown = useCallback((e: React.MouseEvent) => { + if (e.button !== 0) return; + e.preventDefault(); + dragRef.current = { startX: e.clientX, startY: e.clientY, vpStart: { ...vp } }; + document.body.style.cursor = 'grabbing'; + const handleMouseMove = (me: MouseEvent) => { + const dr = dragRef.current; + if (!dr) return; + const rect = chartRef.current?.getBoundingClientRect(); + if (!rect) return; + const plotWidth = rect.width - CHART_MARGIN.left - CHART_MARGIN.right; + const plotHeight = rect.height - CHART_MARGIN.top - CHART_MARGIN.bottom; + const dxData = -(( me.clientX - dr.startX) / plotWidth) * (dr.vpStart.xMax - dr.vpStart.xMin); + const dyData = ((me.clientY - dr.startY) / plotHeight) * (dr.vpStart.yMax - dr.vpStart.yMin); + setViewport({ xMin: dr.vpStart.xMin + dxData, xMax: dr.vpStart.xMax + dxData, yMin: dr.vpStart.yMin + dyData, yMax: dr.vpStart.yMax + dyData }); + }; + const handleMouseUp = () => { + dragRef.current = null; + document.body.style.cursor = ''; + window.removeEventListener('mousemove', handleMouseMove); + window.removeEventListener('mouseup', handleMouseUp); + }; + window.addEventListener('mousemove', handleMouseMove); + window.addEventListener('mouseup', handleMouseUp); + }, [vp]); + + const handleZoomIn = useCallback(() => { + const midX = (vp.xMin + vp.xMax) / 2; const midY = (vp.yMin + vp.yMax) / 2; + const factor = 1 / ZOOM_FACTOR; + setViewport({ xMin: midX - (midX - vp.xMin) * factor, xMax: midX + (vp.xMax - midX) * factor, yMin: midY - (midY - vp.yMin) * factor, yMax: midY + (vp.yMax - midY) * factor }); + }, [vp]); + + const handleZoomOut = useCallback(() => { + const midX = (vp.xMin + vp.xMax) / 2; const midY = (vp.yMin + vp.yMax) / 2; + const factor = ZOOM_FACTOR; + setViewport({ xMin: midX - (midX - vp.xMin) * factor, xMax: midX + (vp.xMax - midX) * factor, yMin: midY - (midY - vp.yMin) * factor, yMax: midY + (vp.yMax - midY) * factor }); + }, [vp]); + + const handleReset = () => setViewport(null); + const isReset = !viewport; + + return ( +
+
+

Stabilization vs Druggability (Complex Pockets)

+
+ + + +
+
+
+ + + + val.toFixed(3)} label={{ value: 'Disorder Delta (Δ pLDDT)', position: 'bottom', fill: '#888', fontSize: 10, fontFamily: 'monospace' }} /> + val.toFixed(3)} label={{ value: 'Druggability Score', angle: -90, position: 'left', fill: '#888', fontSize: 10, fontFamily: 'monospace' }} /> + [Number(value).toFixed(3), name]) as any} /> + a.avg_delta - b.avg_delta)} line={{ stroke: '#555', strokeWidth: 1.5, strokeDasharray: '4 4' }}> + {data.map((entry, index) => (= 5.0 ? '#10b981' : '#9ca3af'} />))} + + + + {data.every(d => Math.abs(d.avg_delta) < 0.001) && ( +
+ Disorder Delta data not available +
+ )} +
+ {!isReset && (

Scroll to zoom · Drag to pan · Click reset to restore

)} +
+ ); +} + +interface ComparisonTabProps { + comparison: ComparisonData | null; + activePocketIdx: string | number | null; + handleHighlight: (residueIndices: number[], pocketIdx: string | number, target?: string) => void; + monomerStructureUrl: string; + complexStructureUrl: string; + onConformationChange?: (confs: Conformation[] | null, mode: number | null, target: string) => void; +} + +export function ComparisonTab({ comparison, activePocketIdx, handleHighlight, monomerStructureUrl, complexStructureUrl, onConformationChange }: ComparisonTabProps) { + if (!comparison) return (
Comparison data not available.
); + + const { summary_metrics, ddgi, pocket_mapping, interface_pockets, conserved_pockets, emergent_pockets, graph_datasets, property_changes, stabilization_stats, fragment_comparison } = comparison; + const hasScatterData = graph_datasets?.stabilization_scatter && graph_datasets.stabilization_scatter.length > 0; + + const renderPocketTable = (pockets: Pocket[] | undefined, prefix: string) => ( + + {pockets && pockets.length > 0 ? ( + pockets.map((pocket, idx) => ( + handleHighlight(residueIndices, `${prefix}-${idx}`, comparisonHighlightTarget(pocket))} + proteinPdbId={complexStructureUrl} sourceType="dimer" + onConformationChange={(confs: any, mode: any) => onConformationChange?.(confs, mode, comparisonHighlightTarget(pocket))} /> + )) + ) : ( + No pockets found. + )} + + ); + + const tableHeader = ( + + + {['ID','Score','Vol','Hydro','Polar','Δ pLDDT','Center','Residues'].map(h => ( + {h} + ))} + Actions + + + ); + + return ( +
+ {/* 1. Summary Metrics & DDGI */} +
+
+ Total Monomer Pockets + {summary_metrics.total_monomer_pockets} +
+
+ Total Complex Pockets + {summary_metrics.total_dimer_pockets} +
+
+ True Interface Pockets + {pocket_mapping.interface_count} +
+
0 ? 'border-success/50' : 'border-danger/50'}`}> + + DDGI Score +
Dimerization Druggability Gain Index: Avg Dimer Score - Avg Monomer Score
+
+ 0 ? 'text-success' : 'text-danger'}`}>{ddgi > 0 ? '+' : ''}{ddgi.toFixed(3)} +
+
+ + {/* 2. Pocket Mapping & Property Changes */} +
+
+

Pocket Transition Map

+
+
Conserved in both states{pocket_mapping.conserved_count}
+
Disappeared upon dimerization{pocket_mapping.monomer_only_count}
+
Newly emerged in dimer{pocket_mapping.emergent_count}
+
+
+
Residue Stabilization Analysis
+
Interface Residue Enrichment{stabilization_stats.enrichment_score.toFixed(2)}x
+
+
+
+

Average Property Shifts

+
+
Avg Volume{property_changes.monomer_avg_volume.toFixed(0)} → {property_changes.dimer_avg_volume.toFixed(0)} ų
+
Avg Hydrophobicity{property_changes.monomer_avg_hydrophobicity.toFixed(2)} → {property_changes.dimer_avg_hydrophobicity.toFixed(2)}
+
Avg Polarity{property_changes.monomer_avg_polarity.toFixed(2)} → {property_changes.dimer_avg_polarity.toFixed(2)}
+
Avg Druggability 0 ? 'text-success' : 'text-danger'}>{summary_metrics.avg_monomer_druggability.toFixed(3)} → {summary_metrics.avg_dimer_druggability.toFixed(3)}
+
+
+
+ + {/* 3. Charts */} + {hasScatterData && } + + {/* 4. True Interface Pockets */} +
+

True Interface Drug Targets

+

Pockets spanning multiple protein chains at the dimer interaction surface.

+
{tableHeader}{renderPocketTable(interface_pockets, 'int')}
+
+ + {/* 5b. Conserved Pockets */} +
+

Conserved Pockets

+

Pockets retained from monomer to dimer — spatially overlapping in both structures.

+
{tableHeader}{renderPocketTable(conserved_pockets, 'con')}
+
+ + {/* 5. Emergent Pockets */} +
+

Emergent Dimer-only Pockets

+

Pockets that physically appear in the dimer but belong to a single chain (structural rearrangement).

+
{tableHeader}{renderPocketTable(emergent_pockets, 'emg')}
+
+ + {/* 6. Fragment Comparison */} + {fragment_comparison && (fragment_comparison.unique_interface_fragments?.length > 0 || fragment_comparison.unique_dimer_fragments?.length > 0) && ( +
+
+

+ + Novel ChEMBL Fragment Suggestions +

+

Compounds from the ChEMBL database unique to the dimerized state — not suggested for any monomer pocket.

+
+
+
+
+
Interface Pocket Fragments
+ {fragment_comparison.unique_interface_fragments?.length || 0} compounds +
+

Fragments targeting pockets at the protein-protein interface — highest value for PPI inhibitor design.

+ +
+
+
+
Dimer-only Fragments
+ {fragment_comparison.unique_dimer_fragments?.length || 0} compounds +
+

Fragments unique to any dimer pocket (including emergent and conserved) not found in monomer analysis.

+ +
+
+
+ )} +
+ ); +} diff --git a/app/src/components/complex/ComplexHeader.jsx b/app/src/components/complex/ComplexHeader.tsx similarity index 89% rename from app/src/components/complex/ComplexHeader.jsx rename to app/src/components/complex/ComplexHeader.tsx index 0a57420..14d7257 100644 --- a/app/src/components/complex/ComplexHeader.jsx +++ b/app/src/components/complex/ComplexHeader.tsx @@ -1,7 +1,12 @@ import React from 'react'; +import type { Complex } from '../../types'; import { Badge } from '../common/Badge'; -export function ComplexHeader({ complex }) { +interface ComplexHeaderProps { + complex: Complex; +} + +export function ComplexHeader({ complex }: ComplexHeaderProps) { const { alphafold_id, protein_name, @@ -14,13 +19,13 @@ export function ComplexHeader({ complex }) { review_status } = complex; - const getDrugBadgeVariant = (count) => { + const getDrugBadgeVariant = (count: number): 'unknown' | 'undrugged' | 'drugged' => { if (count === -1) return 'unknown'; if (count === 0) return 'undrugged'; return 'drugged'; }; - const getDrugBadgeText = (count) => { + const getDrugBadgeText = (count: number): string => { if (count === -1) return 'DRUGS UNKNOWN'; if (count === 0) return 'UNDRUGGED'; return `${count} DRUGS`; diff --git a/app/src/components/complex/ConformationBrowser.jsx b/app/src/components/complex/ConformationBrowser.tsx similarity index 90% rename from app/src/components/complex/ConformationBrowser.jsx rename to app/src/components/complex/ConformationBrowser.tsx index b390339..0d675de 100644 --- a/app/src/components/complex/ConformationBrowser.jsx +++ b/app/src/components/complex/ConformationBrowser.tsx @@ -1,6 +1,13 @@ import React from 'react'; +import type { Conformation } from '../../types'; -export function ConformationBrowser({ conformations, activeMode, onSelect }) { +interface ConformationBrowserProps { + conformations: Conformation[]; + activeMode: number | null; + onSelect: (conformation: Conformation) => void; +} + +export function ConformationBrowser({ conformations, activeMode, onSelect }: ConformationBrowserProps) { if (!conformations?.length) return null; return ( diff --git a/app/src/components/complex/DockingLeaderboard.jsx b/app/src/components/complex/DockingLeaderboard.tsx similarity index 96% rename from app/src/components/complex/DockingLeaderboard.jsx rename to app/src/components/complex/DockingLeaderboard.tsx index 7a96708..c0da5ac 100644 --- a/app/src/components/complex/DockingLeaderboard.jsx +++ b/app/src/components/complex/DockingLeaderboard.tsx @@ -1,12 +1,20 @@ import React from 'react'; +import type { LeaderboardEntry, Conformation } from '../../types'; const CHEMBL_BASE_URL = 'https://www.ebi.ac.uk/chembl/compound_report_card/'; +interface DockingLeaderboardProps { + entries: LeaderboardEntry[]; + activeEntryId?: string; + onSelect?: (entry: LeaderboardEntry) => void; + onRemove?: (entryId: string) => void; +} + /** * DockingLeaderboard — Panel showing all completed docking results, sorted by binding affinity. * ChEMBL IDs are clickable links to the ChEMBL database. */ -export function DockingLeaderboard({ entries, activeEntryId, onSelect, onRemove }) { +export function DockingLeaderboard({ entries, activeEntryId, onSelect, onRemove }: DockingLeaderboardProps) { if (!entries || entries.length === 0) { return (
@@ -115,11 +123,16 @@ export function DockingLeaderboard({ entries, activeEntryId, onSelect, onRemove ); } +interface DockingResultDetailProps { + entry: LeaderboardEntry | null; + onConformationSelect?: (entry: LeaderboardEntry, mode: number) => void; +} + /** * DockingResultDetail — Shows details of a selected leaderboard entry with conformations. * Includes a ConformationBrowser so the user can switch poses from the detail panel. */ -export function DockingResultDetail({ entry, onConformationSelect }) { +export function DockingResultDetail({ entry, onConformationSelect }: DockingResultDetailProps) { const [activeMode, setActiveMode] = React.useState(1); React.useEffect(() => { diff --git a/app/src/components/complex/DockingPanel.jsx b/app/src/components/complex/DockingPanel.tsx similarity index 90% rename from app/src/components/complex/DockingPanel.jsx rename to app/src/components/complex/DockingPanel.tsx index 70e62f8..64c41fc 100644 --- a/app/src/components/complex/DockingPanel.jsx +++ b/app/src/components/complex/DockingPanel.tsx @@ -2,8 +2,28 @@ import React, { useEffect } from 'react'; import { useDockingJob } from '../../hooks/useDockingJob'; import { useChemblFragments } from '../../hooks/useChemblFragments'; import { MoleculePicker } from './MoleculePicker'; +import type { Pocket, Conformation } from '../../types'; -export function DockingPanel({ pocket, proteinPdbId, sourceType, onConformationChange, onUndock, onDockingComplete, apiBase = '/api' }) { +interface DockingPanelProps { + pocket: Pocket; + proteinPdbId: string; + sourceType?: string; + onConformationChange?: (confs: Conformation[] | null, mode: number | null) => void; + onUndock?: () => void; + onDockingComplete?: (result: { + pocketId: number; + sourceType: string; + fragmentId: string; + fragmentName: string; + smiles: string; + bindingAffinity: number; + conformations: Conformation[]; + timestamp: number; + }) => void; + apiBase?: string; +} + +export function DockingPanel({ pocket, proteinPdbId, sourceType, onConformationChange, onUndock, onDockingComplete, apiBase = '/api' }: DockingPanelProps) { const { fragments, isLoading: fragmentsLoading, @@ -36,9 +56,9 @@ export function DockingPanel({ pocket, proteinPdbId, sourceType, onConformationC onDockingComplete?.({ pocketId: pocket.pocket_id, sourceType: sourceType || 'dimer', - fragmentId: selectedFragment.chembl_id || selectedFragment.id, + fragmentId: selectedFragment.chembl_id || selectedFragment.id || '', fragmentName: selectedFragment.name || selectedFragment.chembl_id, - smiles: selectedFragment.smiles, + smiles: selectedFragment.smiles || '', bindingAffinity: conformations[0].binding_affinity, conformations, timestamp: Date.now(), diff --git a/app/src/components/complex/FragmentList.jsx b/app/src/components/complex/FragmentList.tsx similarity index 95% rename from app/src/components/complex/FragmentList.jsx rename to app/src/components/complex/FragmentList.tsx index 34ca5f8..952a0f5 100644 --- a/app/src/components/complex/FragmentList.jsx +++ b/app/src/components/complex/FragmentList.tsx @@ -1,9 +1,14 @@ import React from 'react'; +import type { Fragment } from '../../types'; + +interface FragmentListProps { + fragments?: Fragment[]; +} /** * FragmentList — displays suggested fragment molecules from the ChEMBL database for a pocket. */ -export function FragmentList({ fragments }) { +export function FragmentList({ fragments }: FragmentListProps) { if (!fragments || fragments.length === 0) { return (
diff --git a/app/src/components/complex/MetricsPanel.jsx b/app/src/components/complex/MetricsPanel.tsx similarity index 95% rename from app/src/components/complex/MetricsPanel.jsx rename to app/src/components/complex/MetricsPanel.tsx index 4c8f12b..78dd167 100644 --- a/app/src/components/complex/MetricsPanel.jsx +++ b/app/src/components/complex/MetricsPanel.tsx @@ -1,7 +1,12 @@ import React from 'react'; +import type { Complex } from '../../types'; import { toPercent } from '../common/GapScoreBar'; -export function MetricsPanel({ complex }) { +interface MetricsPanelProps { + complex: Complex; +} + +export function MetricsPanel({ complex }: MetricsPanelProps) { const { monomer_plddt_avg, dimer_plddt_avg, disorder_delta, gap_score, known_drug_names } = complex; const m_plddt = monomer_plddt_avg || 0; diff --git a/app/src/components/complex/MoleculePicker.jsx b/app/src/components/complex/MoleculePicker.tsx similarity index 93% rename from app/src/components/complex/MoleculePicker.jsx rename to app/src/components/complex/MoleculePicker.tsx index b06af9d..be7936c 100644 --- a/app/src/components/complex/MoleculePicker.jsx +++ b/app/src/components/complex/MoleculePicker.tsx @@ -1,4 +1,16 @@ import React from 'react'; +import type { Fragment } from '../../types'; + +interface MoleculePickerProps { + fragments: Fragment[]; + isLoading: boolean; + error: string | null; + selectedFragment: Fragment | null; + onSelect: (fragment: Fragment) => void; + onConfirm: () => void; + isDockingRunning: boolean; + onRetry: () => void; +} export function MoleculePicker({ fragments, @@ -9,7 +21,7 @@ export function MoleculePicker({ onConfirm, isDockingRunning, onRetry, -}) { +}: MoleculePickerProps) { return (
@@ -87,7 +99,7 @@ export function MoleculePicker({ className="font-mono text-[10px] text-text-secondary bg-bg-tertiary px-2 py-1 rounded block mb-2 truncate" > {frag.smiles?.slice(0, 60)} - {frag.smiles?.length > 60 ? '…' : ''} + {(frag.smiles?.length ?? 0) > 60 ? '…' : ''}
diff --git a/app/src/components/complex/PocketTableRow.jsx b/app/src/components/complex/PocketTableRow.tsx similarity index 89% rename from app/src/components/complex/PocketTableRow.jsx rename to app/src/components/complex/PocketTableRow.tsx index b2b117c..5907b1c 100644 --- a/app/src/components/complex/PocketTableRow.jsx +++ b/app/src/components/complex/PocketTableRow.tsx @@ -1,10 +1,23 @@ import React from 'react'; +import type { Pocket } from '../../types'; + +interface PocketTableRowProps { + pocket: Pocket; + activeTab: string; + isActive: boolean; + onHighlight: (residueIndices: number[]) => void; + proteinPdbId?: string; + sourceType?: string; + onStartDocking?: (info: { pocket: Pocket; sourceType: string; proteinPdbId: string }) => void; + isDockingActive?: boolean; + onConformationChange?: (confs: unknown, mode: unknown) => void; +} /** * PocketTableRow — displays details for a single predicted binding pocket in a table format. * "Dock Molecule" signals the parent to open the docking UI in the detail panel. */ -export function PocketTableRow({ pocket, activeTab, isActive, onHighlight, proteinPdbId, sourceType, onStartDocking, isDockingActive }) { +export function PocketTableRow({ pocket, activeTab, isActive, onHighlight, proteinPdbId, sourceType, onStartDocking, isDockingActive }: PocketTableRowProps) { const scoreColor = pocket.druggability_score >= 0.5 ? 'text-success' : pocket.druggability_score >= 0.3 @@ -90,7 +103,7 @@ export function PocketTableRow({ pocket, activeTab, isActive, onHighlight, prote disabled={!proteinPdbId} onClick={() => { if (!proteinPdbId) return; - onStartDocking?.({ pocket, sourceType, proteinPdbId }); + onStartDocking?.({ pocket, sourceType: sourceType || 'dimer', proteinPdbId }); }} className={`font-mono text-xs uppercase tracking-wider px-2 py-1 rounded border transition-colors duration-150 ${ !proteinPdbId diff --git a/app/src/components/complex/ViewerPlaceholder.jsx b/app/src/components/complex/ViewerPlaceholder.tsx similarity index 87% rename from app/src/components/complex/ViewerPlaceholder.jsx rename to app/src/components/complex/ViewerPlaceholder.tsx index c4d3851..ae793c2 100644 --- a/app/src/components/complex/ViewerPlaceholder.jsx +++ b/app/src/components/complex/ViewerPlaceholder.tsx @@ -1,7 +1,14 @@ import React from 'react'; -export function ViewerPlaceholder({ monomerUrl, complexUrl, monomerPlddt, dimerPlddt }) { - const renderPanel = (label, url, plddt, desc) => { +interface ViewerPlaceholderProps { + monomerUrl?: string; + complexUrl?: string; + monomerPlddt?: number; + dimerPlddt?: number; +} + +export function ViewerPlaceholder({ monomerUrl, complexUrl, monomerPlddt, dimerPlddt }: ViewerPlaceholderProps) { + const renderPanel = (label: string, url: string | undefined, plddt: number | undefined, desc: string) => { const filename = url ? url.split('/').pop() : 'No structure available'; return ( diff --git a/app/src/components/complex/viewer/DisorderDeltaBar.jsx b/app/src/components/complex/viewer/DisorderDeltaBar.tsx similarity index 88% rename from app/src/components/complex/viewer/DisorderDeltaBar.jsx rename to app/src/components/complex/viewer/DisorderDeltaBar.tsx index f8fe07b..8d6cf5b 100644 --- a/app/src/components/complex/viewer/DisorderDeltaBar.jsx +++ b/app/src/components/complex/viewer/DisorderDeltaBar.tsx @@ -1,6 +1,11 @@ import React from 'react'; -export function DisorderDeltaBar({ disorderDelta, visible }) { +interface DisorderDeltaBarProps { + disorderDelta?: number; + visible: boolean; +} + +export function DisorderDeltaBar({ disorderDelta, visible }: DisorderDeltaBarProps) { if (!visible) return null; const delta = disorderDelta || 0; diff --git a/app/src/components/complex/viewer/MolstarPanel.jsx b/app/src/components/complex/viewer/MolstarPanel.tsx similarity index 83% rename from app/src/components/complex/viewer/MolstarPanel.jsx rename to app/src/components/complex/viewer/MolstarPanel.tsx index de91c34..ca819a0 100644 --- a/app/src/components/complex/viewer/MolstarPanel.jsx +++ b/app/src/components/complex/viewer/MolstarPanel.tsx @@ -4,8 +4,22 @@ import { useTheme } from '../../../hooks/useTheme'; import { useMolstar } from './useMolstar'; import { ViewerHeader } from './ViewerHeader'; import { ViewerFooter } from './ViewerFooter'; +import type { Conformation, MolstarPanelHandle } from '../../../types'; -export const MolstarPanel = React.memo(forwardRef(({ structureUrl, label, plddt, description, visible = true, highlightIndices = null, representation = 'cartoon', conformations = null, activeMode = null, hideControls = false }, ref) => { +interface MolstarPanelProps { + structureUrl?: string; + label: string; + plddt?: number; + description?: string; + visible?: boolean; + highlightIndices?: number[] | null; + representation?: string; + conformations?: Conformation[] | null; + activeMode?: number | null; + hideControls?: boolean; +} + +export const MolstarPanel = React.memo(forwardRef(({ structureUrl, label, plddt, description, visible = true, highlightIndices = null, representation = 'cartoon', conformations = null, activeMode = null, hideControls = false }, ref) => { const [isFullscreen, setIsFullscreen] = useState(false); const { theme } = useTheme(); const { containerRef, isLoading, error, highlightPocket, clearPocketHighlight } = useMolstar({ @@ -41,12 +55,12 @@ export const MolstarPanel = React.memo(forwardRef(({ structureUrl, label, plddt,
{/* Mol* canvas container */}
} className="absolute inset-0" style={{ width: '100%', height: '100%', position: 'absolute' }} /> - {conformations?.length > 0 && !isLoading && !error && ( + {conformations && conformations.length > 0 && !isLoading && !error && (
@@ -102,7 +116,7 @@ export const MolstarPanel = React.memo(forwardRef(({ structureUrl, label, plddt, )}
- + ); })); diff --git a/app/src/components/complex/viewer/ProteinViewer.jsx b/app/src/components/complex/viewer/ProteinViewer.tsx similarity index 87% rename from app/src/components/complex/viewer/ProteinViewer.jsx rename to app/src/components/complex/viewer/ProteinViewer.tsx index 1d1dfdc..e608cc4 100644 --- a/app/src/components/complex/viewer/ProteinViewer.jsx +++ b/app/src/components/complex/viewer/ProteinViewer.tsx @@ -1,12 +1,35 @@ import React, { useState, useRef, useImperativeHandle, forwardRef, useMemo } from 'react'; import { MolstarPanel } from './MolstarPanel'; import { DisorderDeltaBar } from './DisorderDeltaBar'; +import type { Conformation, ProteinViewerHandle, MolstarPanelHandle } from '../../../types'; + +interface ProteinViewerProps { + monomerUrl?: string; + complexUrl?: string; + monomerPlddt?: number; + dimerPlddt?: number; + disorderDelta?: number; + monomerConformations?: Conformation[] | null; + complexConformations?: Conformation[] | null; + activeModeMonomer?: number | null; + activeModeComplex?: number | null; +} + +interface DockingState { + conformations: Conformation[] | null; + activeMode: number | null; +} + +interface ActiveHighlight { + indices: number[]; + target: string; +} /** * ProteinViewer — Displays monomer and dimer Mol* viewers side by side. * Supports synchronized conformations (docking results) for both monomer and dimer. */ -export const ProteinViewer = forwardRef( +export const ProteinViewer = forwardRef( ({ monomerUrl, complexUrl, @@ -19,29 +42,29 @@ export const ProteinViewer = forwardRef( activeModeComplex = null }, ref) => { const [isZoomed, setIsZoomed] = useState(false); - const [activeHighlight, setActiveHighlight] = useState(null); // { indices, target } + const [activeHighlight, setActiveHighlight] = useState(null); const [representation, setRepresentation] = useState('cartoon'); // Internal state for docking results triggered via imperative API - const [monomerDocking, setMonomerDocking] = useState({ conformations: null, activeMode: null }); - const [complexDocking, setComplexDocking] = useState({ conformations: null, activeMode: null }); + const [monomerDocking, setMonomerDocking] = useState({ conformations: null, activeMode: null }); + const [complexDocking, setComplexDocking] = useState({ conformations: null, activeMode: null }); const mConfs = monomerConformations ?? monomerDocking.conformations; const mMode = activeModeMonomer ?? monomerDocking.activeMode; const cConfs = complexConformations ?? complexDocking.conformations; const cMode = activeModeComplex ?? complexDocking.activeMode; - const monomerViewerRef = useRef(null); - const complexViewerRef = useRef(null); + const monomerViewerRef = useRef(null); + const complexViewerRef = useRef(null); useImperativeHandle(ref, () => ({ - highlightPocket: (residueIndices, target = 'complex') => { + highlightPocket: (residueIndices: number[], target = 'complex') => { setActiveHighlight({ indices: residueIndices, target }); }, clearPocketHighlight: () => { setActiveHighlight(null); }, - setConformations: (confs, mode, target = 'complex') => { + setConformations: (confs: Conformation[], mode: number, target = 'complex') => { if (target === 'monomer' || target === 'both') { setMonomerDocking({ conformations: confs, activeMode: mode }); } @@ -62,7 +85,7 @@ export const ProteinViewer = forwardRef( // Close zoom on Escape key React.useEffect(() => { if (!isZoomed) return; - const handleKey = (e) => { + const handleKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setIsZoomed(false); }; window.addEventListener('keydown', handleKey); diff --git a/app/src/components/complex/viewer/RevealButton.jsx b/app/src/components/complex/viewer/RevealButton.tsx similarity index 81% rename from app/src/components/complex/viewer/RevealButton.jsx rename to app/src/components/complex/viewer/RevealButton.tsx index 026a841..4dd15f1 100644 --- a/app/src/components/complex/viewer/RevealButton.jsx +++ b/app/src/components/complex/viewer/RevealButton.tsx @@ -1,7 +1,13 @@ import React from 'react'; import { motion } from 'framer-motion'; -export function RevealButton({ isRevealed, onReveal, disabled }) { +interface RevealButtonProps { + isRevealed: boolean; + onReveal: () => void; + disabled?: boolean; +} + +export function RevealButton({ isRevealed, onReveal, disabled }: RevealButtonProps) { return ( diff --git a/app/src/components/complex/viewer/useMolstar.js b/app/src/components/complex/viewer/useMolstar.ts similarity index 82% rename from app/src/components/complex/viewer/useMolstar.js rename to app/src/components/complex/viewer/useMolstar.ts index 7642566..0aea695 100644 --- a/app/src/components/complex/viewer/useMolstar.js +++ b/app/src/components/complex/viewer/useMolstar.ts @@ -1,29 +1,38 @@ import { useRef, useEffect, useState, useCallback } from 'react'; -import { PluginUIContext } from 'molstar/lib/mol-plugin-ui/context'; import { DefaultPluginUISpec } from 'molstar/lib/mol-plugin-ui/spec'; import { createPluginUI } from 'molstar/lib/mol-plugin-ui'; import { PluginConfig } from 'molstar/lib/mol-plugin/config'; import { Color } from 'molstar/lib/mol-util/color'; import { createRoot } from 'react-dom/client'; -import { StructureSelection, StructureQuery, StructureProperties } from 'molstar/lib/mol-model/structure'; +import { StructureSelection } from 'molstar/lib/mol-model/structure'; import { Script } from 'molstar/lib/mol-script/script'; -import { MolScriptBuilder as MS } from 'molstar/lib/mol-script/language/builder'; -import { Bundle } from 'molstar/lib/mol-model/structure/structure/element/bundle'; -import { Overpaint } from 'molstar/lib/mol-theme/overpaint'; import 'molstar/lib/mol-plugin-ui/skin/dark.scss'; +import type { Conformation } from '../../../types'; + +interface UseMolstarOptions { + structureUrl?: string; + label?: string; + autoLoad?: boolean; + highlightIndices?: number[] | null; + theme?: string; + representation?: string; + conformations?: Conformation[] | null; + activeMode?: number | null; + hideControls?: boolean; +} + +// Extend HTMLElement to hold React root +interface HTMLElementWithRoot extends HTMLElement { + __reactRoot?: ReturnType; +} + /** * useMolstar — React hook that encapsulates the Mol* viewer lifecycle. * * Handles initialization, structure loading from .cif URL, pLDDT coloring, * and cleanup on unmount. No Mol* code should exist outside this hook. - * - * @param {Object} options - * @param {string} options.structureUrl — URL to the .cif file - * @param {string} options.label — label for the structure - * @param {boolean} options.autoLoad — whether to load immediately (default true) - * @returns {{ containerRef, isLoading, error, resetCamera }} */ export function useMolstar({ structureUrl, @@ -35,15 +44,15 @@ export function useMolstar({ conformations = null, activeMode = null, hideControls = false, -}) { - const containerRef = useRef(null); - const pluginRef = useRef(null); +}: UseMolstarOptions) { + const containerRef = useRef(null); + const pluginRef = useRef(null); const initRef = useRef(false); const pocketActiveRef = useRef(false); // Track if a pocket highlight is active - const poseStructureRefs = useRef(new Map()); - const activeModeRef = useRef(null); + const poseStructureRefs = useRef>(new Map()); + const activeModeRef = useRef(null); const [isLoading, setIsLoading] = useState(false); - const [error, setError] = useState(null); + const [error, setError] = useState(null); // Initialize Mol* plugin useEffect(() => { @@ -89,13 +98,14 @@ export function useMolstar({ ); const plugin = await createPluginUI({ - target: containerRef.current, + target: containerRef.current as HTMLElement, spec, - render: (component, target) => { - let root = target.__reactRoot; + render: (component: any, target: any) => { + const el = target as HTMLElementWithRoot; + let root = el.__reactRoot; if (!root) { - root = createRoot(target); - target.__reactRoot = root; + root = createRoot(el); + el.__reactRoot = root; } root.render(component); }, @@ -124,10 +134,10 @@ export function useMolstar({ if (autoLoad && structureUrl) { await loadStructure(plugin, structureUrl); } - } catch (err) { + } catch (err: unknown) { console.error('[useMolstar] init failed:', err); if (!disposed) { - setError(`Viewer init failed: ${err.message}`); + setError(`Viewer init failed: ${err instanceof Error ? err.message : String(err)}`); } } }; @@ -146,6 +156,7 @@ export function useMolstar({ } initRef.current = false; }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // Reload structure when URL changes (after init) @@ -155,6 +166,7 @@ export function useMolstar({ if (!pluginRef.current.isInitialized) return; loadStructure(pluginRef.current, structureUrl); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [structureUrl]); // Update background when theme changes @@ -177,15 +189,13 @@ export function useMolstar({ useEffect(() => { if (!pluginRef.current || !pluginRef.current.isInitialized || isLoading) return; updateRepresentationStyle(pluginRef.current, representation); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [representation, isLoading]); /** * Update the representation type for all structures. - * Uses Mol*'s component manager to remove existing representations - * and add new ones with the desired type. - * Supported types: 'cartoon', 'ball-and-stick', 'gaussian-surface', 'spacefill', etc. */ - const updateRepresentationStyle = async (plugin, type) => { + const updateRepresentationStyle = async (plugin: any, type: string) => { try { const { structures } = plugin.managers.structure.hierarchy.current; if (!structures || structures.length === 0) return; @@ -216,7 +226,7 @@ export function useMolstar({ /** * Load a .cif file and apply pLDDT confidence coloring. */ - const loadStructure = async (plugin, url) => { + const loadStructure = async (plugin: any, url: string) => { setIsLoading(true); setError(null); @@ -231,14 +241,14 @@ export function useMolstar({ } // Download the CIF file - let data; + let data: any; try { data = await plugin.builders.data.download( { url, isBinary: false, label }, { state: { isGhost: true } } ); - } catch (dlErr) { - throw new Error(`Download failed for ${url}: ${dlErr.message}`); + } catch (dlErr: unknown) { + throw new Error(`Download failed for ${url}: ${dlErr instanceof Error ? dlErr.message : String(dlErr)}`); } // Detect format from URL @@ -246,7 +256,7 @@ export function useMolstar({ const format = isPdb ? 'pdb' : 'mmcif'; // Parse structure data and build trajectory - let trajectory; + let trajectory: any; try { trajectory = await plugin.builders.structure.parseTrajectory(data, format); } catch (parseErr) { @@ -269,8 +279,6 @@ export function useMolstar({ ); // Apply pLDDT confidence coloring (uncertainty theme) - // AlphaFold stores pLDDT in the B-factor column. - // Mol* 'uncertainty' theme maps B-factor → standard 4-color pLDDT scale await applyPlddtColoring(plugin); // Apply initial representation if not default (cartoon) @@ -281,9 +289,9 @@ export function useMolstar({ // Frame the camera plugin.managers.camera.reset(); - } catch (err) { + } catch (err: unknown) { console.error(`[useMolstar] Load failed for ${url}:`, err); - setError(`Failed to load: ${err.message}`); + setError(`Failed to load: ${err instanceof Error ? err.message : String(err)}`); } finally { setIsLoading(false); } @@ -306,7 +314,7 @@ export function useMolstar({ * Preload all conformations as hidden Mol* structures. * Show only the one matching initialMode. Receptor always stays visible. */ - async function preloadConformations(confs, initialMode) { + async function preloadConformations(confs: Conformation[], initialMode?: number) { const plugin = pluginRef.current; if (!plugin?.isInitialized) return; await clearAllPoses(); @@ -335,7 +343,7 @@ export function useMolstar({ const structRef = structures[structures.length - 1]; if (!structRef) continue; - const modeColors = { + const modeColors: Record> = { 1: Color(0xf97316), 2: Color(0x8b5cf6), 3: Color(0x06b6d4), @@ -373,7 +381,7 @@ export function useMolstar({ /** * Switch visible pose to `mode`. Hide previous. Does not reset camera. */ - async function showConformation(mode) { + async function showConformation(mode: number) { const plugin = pluginRef.current; if (!plugin) return; const hierarchy = plugin.managers.structure.hierarchy; @@ -396,7 +404,7 @@ export function useMolstar({ * Highlight specific residues in the 3D viewer (pocket visualization). * Uses Mol*'s native selection manager to highlight and focus the pocket. */ - const highlightPocket = useCallback(async (residueIndices) => { + const highlightPocket = useCallback(async (residueIndices: number[]) => { const plugin = pluginRef.current; if (!plugin || !residueIndices || residueIndices.length === 0) return; @@ -410,7 +418,7 @@ export function useMolstar({ // Clear previous selections plugin.managers.interactivity.lociSelects.deselectAll(); - let targetLoci = null; + let targetLoci: any = null; for (const s of structures) { if (!s.cell?.obj?.data) continue; @@ -418,9 +426,9 @@ export function useMolstar({ // Create a selection matching either label_seq_id (CIF) or auth_seq_id (PDB) const sel = Script.getStructureSelection( - Q => Q.struct.generator.atomGroups({ + (Q: any) => Q.struct.generator.atomGroups({ 'residue-test': Q.core.logic.or( - residueIndices.flatMap(idx => [ + residueIndices.flatMap((idx: number) => [ Q.core.rel.eq([Q.struct.atomProperty.macromolecular.label_seq_id(), idx]), Q.core.rel.eq([Q.struct.atomProperty.macromolecular.auth_seq_id(), idx]) ]) @@ -487,6 +495,7 @@ export function useMolstar({ } else { clearAllPoses().catch((e) => console.warn('[useMolstar] clearAllPoses failed:', e)); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [conformations, isLoading]); // When activeMode changes and poses are already loaded: just switch visibility @@ -495,6 +504,7 @@ export function useMolstar({ if (!plugin || activeMode == null || !poseStructureRefs.current.size) return; if (activeMode === activeModeRef.current) return; showConformation(activeMode).catch((e) => console.warn('[useMolstar] showConformation failed:', e)); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [activeMode]); return { @@ -512,34 +522,23 @@ export function useMolstar({ /** * Apply pLDDT confidence coloring to all representations. - * - * AlphaFold stores pLDDT (confidence, 0-100) in the B-factor column. - * Mol*'s built-in 'uncertainty' theme uses a 'red-white-blue' scale with - * reverse=true, which maps HIGH B-factor → RED. That's correct for actual - * uncertainty, but WRONG for pLDDT where HIGH = HIGH confidence = should be BLUE. - * - * Strategy: - * 1. Apply uncertainty theme via the normal API (sets up proper B-factor reading). - * 2. Do a direct state-tree update to replace colorTheme.params.list with the - * reversed color array, so the theme factory sees blue→white→red and its - * built-in `reverse:true` flips it to red→white→blue mapping (0→red, 100→blue). */ -async function applyPlddtColoring(plugin) { +async function applyPlddtColoring(plugin: any) { const themeNames = ['uncertainty', 'plddt-confidence', 'b-factor']; const registry = plugin.representation.structure.themes.colorThemeRegistry; - let themeName = null; + let themeName: string | null = null; const availableThemes = registry._list || []; for (const name of themeNames) { - if (availableThemes.some(t => t.name === name)) { + if (availableThemes.some((t: any) => t.name === name)) { themeName = name; break; } } if (!themeName) { - console.warn('[useMolstar] No pLDDT color theme found. Available:', availableThemes.map(t => t.name)); + console.warn('[useMolstar] No pLDDT color theme found. Available:', availableThemes.map((t: any) => t.name)); return; } @@ -549,7 +548,7 @@ async function applyPlddtColoring(plugin) { // Step 1: Apply the uncertainty theme via normal API for (const s of structures) { if (!s.components) continue; - const validComponents = s.components.filter(c => c && c.representations); + const validComponents = s.components.filter((c: any) => c && c.representations); if (validComponents.length > 0) { try { await plugin.managers.structure.component.updateRepresentationsTheme( @@ -563,10 +562,6 @@ async function applyPlddtColoring(plugin) { } // Step 2: Directly patch representation state cells to flip the color list. - // The uncertainty theme default list is 'red-white-blue' with reverse=true, - // meaning domain_min(0)→blue, domain_max(100)→red. - // We swap the list to 'blue-white-red' so that with reverse=true: - // domain_min(0)→red, domain_max(100)→blue. Exactly what we want for pLDDT. try { const update = plugin.state.data.build(); let patched = false; @@ -581,9 +576,7 @@ async function applyPlddtColoring(plugin) { const ct = cell.transform.params.colorTheme; if (ct.name !== 'uncertainty') continue; - update.to(cell).update(old => { - // Reverse the color list array in-place so the theme factory's - // built-in reverse:true flips it back to the correct pLDDT mapping. + update.to(cell).update((old: any) => { if (old.colorTheme?.params?.list?.colors) { old.colorTheme.params.list.colors = [...old.colorTheme.params.list.colors].reverse(); } @@ -600,4 +593,3 @@ async function applyPlddtColoring(plugin) { console.warn('[useMolstar] Failed to patch color list for pLDDT:', e); } } - diff --git a/app/src/components/dashboard/TargetTable.jsx b/app/src/components/dashboard/TargetTable.tsx similarity index 95% rename from app/src/components/dashboard/TargetTable.jsx rename to app/src/components/dashboard/TargetTable.tsx index f02a397..0690aff 100644 --- a/app/src/components/dashboard/TargetTable.jsx +++ b/app/src/components/dashboard/TargetTable.tsx @@ -2,8 +2,15 @@ import React from 'react'; import { useNavigate } from 'react-router-dom'; import { Badge } from '../common/Badge'; import { GapScoreBar } from '../common/GapScoreBar'; +import type { Complex } from '../../types'; -export function TargetTable({ data = [], filter = 'all', onFilterChange }) { +interface TargetTableProps { + data?: Complex[]; + filter?: string; + onFilterChange: (filter: string) => void; +} + +export function TargetTable({ data = [], filter = 'all', onFilterChange }: TargetTableProps) { const navigate = useNavigate(); const filters = [ @@ -112,7 +119,7 @@ export function TargetTable({ data = [], filter = 'all', onFilterChange }) { })} {data.length === 0 && ( - + No targets found for this filter. diff --git a/app/src/components/layout/Footer.jsx b/app/src/components/layout/Footer.tsx similarity index 100% rename from app/src/components/layout/Footer.jsx rename to app/src/components/layout/Footer.tsx diff --git a/app/src/components/layout/Navbar.jsx b/app/src/components/layout/Navbar.tsx similarity index 100% rename from app/src/components/layout/Navbar.jsx rename to app/src/components/layout/Navbar.tsx diff --git a/app/src/components/search/ResultCard.jsx b/app/src/components/search/ResultCard.tsx similarity index 91% rename from app/src/components/search/ResultCard.jsx rename to app/src/components/search/ResultCard.tsx index 4c5c608..fb7688f 100644 --- a/app/src/components/search/ResultCard.jsx +++ b/app/src/components/search/ResultCard.tsx @@ -2,8 +2,13 @@ import React from 'react'; import { useNavigate } from 'react-router-dom'; import { Badge } from '../common/Badge'; import { GapScoreBar } from '../common/GapScoreBar'; +import type { Complex } from '../../types'; -export function ResultCard({ complex }) { +interface ResultCardProps { + complex: Complex; +} + +export function ResultCard({ complex }: ResultCardProps) { const navigate = useNavigate(); const { @@ -24,13 +29,13 @@ export function ResultCard({ complex }) { navigate(`/complex/${uniprot_id}`); }; - const getDrugBadgeVariant = (count) => { + const getDrugBadgeVariant = (count: number): 'unknown' | 'undrugged' | 'drugged' => { if (count === -1) return 'unknown'; if (count === 0) return 'undrugged'; return 'drugged'; }; - const getDrugBadgeText = (count) => { + const getDrugBadgeText = (count: number): string => { if (count === -1) return 'DRUGS UNKNOWN'; if (count === 0) return 'UNDRUGGED'; return `${count} DRUGS`; diff --git a/app/src/components/search/SearchBar.jsx b/app/src/components/search/SearchBar.tsx similarity index 82% rename from app/src/components/search/SearchBar.jsx rename to app/src/components/search/SearchBar.tsx index fc671a6..eb12724 100644 --- a/app/src/components/search/SearchBar.jsx +++ b/app/src/components/search/SearchBar.tsx @@ -1,20 +1,26 @@ -import React, { useState, useEffect } from 'react'; +import React from 'react'; -export function SearchBar({ onSearch, loading = false, initialValue = '' }) { - const [value, setValue] = useState(initialValue); +interface SearchBarProps { + onSearch: (query: string) => void; + loading?: boolean; + initialValue?: string; +} + +export function SearchBar({ onSearch, loading = false, initialValue = '' }: SearchBarProps) { + const [value, setValue] = React.useState(initialValue); - useEffect(() => { + React.useEffect(() => { setValue(initialValue); }, [initialValue]); - const handleSubmit = (e) => { + const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (value.trim() && !loading) { onSearch(value); } }; - const handleKeyDown = (e) => { + const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter') { handleSubmit(e); } diff --git a/app/src/config.js b/app/src/config.ts similarity index 78% rename from app/src/config.js rename to app/src/config.ts index afb144c..66d5507 100644 --- a/app/src/config.js +++ b/app/src/config.ts @@ -1,6 +1,8 @@ +import type { DemoProtein } from './types'; + export const API_BASE = '/api'; -export const DEMO_PROTEINS = [ +export const DEMO_PROTEINS: DemoProtein[] = [ { id: 'P04637', label: 'TP53', description: 'Tumor suppressor · Human · 5 known drugs' }, { id: 'P9WIU3', label: 'FtsZ', description: 'Cell division · M. tuberculosis · 0 known drugs' }, { id: 'Q55DI5', label: 'Q55DI5', description: 'Transcription factor · D. discoideum · Dramatic reveal' } diff --git a/app/src/hooks/useBindingSites.js b/app/src/hooks/useBindingSites.ts similarity index 61% rename from app/src/hooks/useBindingSites.js rename to app/src/hooks/useBindingSites.ts index 5dfdaf1..847da31 100644 --- a/app/src/hooks/useBindingSites.js +++ b/app/src/hooks/useBindingSites.ts @@ -1,19 +1,16 @@ import { useState, useEffect, useCallback } from 'react'; import { API_BASE } from '../config'; +import { safeJson } from '../utils/safeFetch'; +import type { BindingSitesData, Pocket } from '../types'; /** * useBindingSites — fetches predicted binding sites for a complex. * Lazy-loads: only fetches when `enabled` is true. - * - * @param {string} complexId — UniProt or AlphaFold ID - * @param {boolean} enabled — whether to trigger the fetch - * @param {boolean} showAll — whether to fetch all pockets without limit - * @returns {{ pockets, totalPockets, interfaceCount, loading, error, refetch }} */ -export function useBindingSites(complexId, enabled = false) { - const [data, setData] = useState(null); +export function useBindingSites(complexId: string | undefined, enabled = false) { + const [data, setData] = useState(null); const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); + const [error, setError] = useState(null); const fetchSites = useCallback(async () => { if (!complexId) return; @@ -25,15 +22,19 @@ export function useBindingSites(complexId, enabled = false) { const response = await fetch( `${API_BASE}/complex/${encodeURIComponent(complexId)}/binding-sites` ); - const body = await response.json(); + const body = await safeJson(response); if (!response.ok) { - throw new Error(body.message || 'Failed to load binding sites'); + throw new Error(body?.message || `Failed to load binding sites (HTTP ${response.status})`); + } + + if (!body) { + throw new Error('Server returned an empty response for binding sites'); } setData(body); - } catch (err) { - setError(err.message || 'An error occurred loading binding sites.'); + } catch (err: unknown) { + setError(err instanceof Error ? err.message : 'An error occurred loading binding sites.'); } finally { setLoading(false); } diff --git a/app/src/hooks/useChemblFragments.js b/app/src/hooks/useChemblFragments.ts similarity index 67% rename from app/src/hooks/useChemblFragments.js rename to app/src/hooks/useChemblFragments.ts index 840cce5..ab0dfc8 100644 --- a/app/src/hooks/useChemblFragments.js +++ b/app/src/hooks/useChemblFragments.ts @@ -1,15 +1,25 @@ import { useState, useEffect, useCallback, useRef } from 'react'; +import { safeJson } from '../utils/safeFetch'; +import type { Fragment } from '../types'; + +interface ChemblOptions { + volume?: number; + hydrophobicity?: number; + polarity?: number; + sourceType?: string; + lazy?: boolean; +} /** * Normalizes fragment data from the API to ensure required fields. */ -function normalizeFragment(f) { - if (!f || typeof f !== 'object') return f; +function normalizeFragment(f: Record): Fragment { + if (!f || typeof f !== 'object') return f as unknown as Fragment; return { ...f, - mw: f.mw != null ? f.mw : f.mol_weight, - id: f.chembl_id || f.zinc_id, - }; + mw: f.mw != null ? (f.mw as number) : (f.mol_weight as number | undefined), + id: (f.chembl_id as string) || (f.zinc_id as string), + } as Fragment; } /** @@ -18,11 +28,11 @@ function normalizeFragment(f) { * When options.lazy is true, fragments are NOT fetched automatically on mount — * call refetch() explicitly (e.g. when the user clicks "Dock Molecule"). */ -export function useChemblFragments(pocketId, options = {}, apiBase = '/api') { - const [fragments, setFragments] = useState([]); +export function useChemblFragments(pocketId: number | string | null | undefined, options: ChemblOptions = {}, apiBase = '/api') { + const [fragments, setFragments] = useState([]); const [isLoading, setIsLoading] = useState(false); - const [error, setError] = useState(null); - const cacheRef = useRef({}); + const [error, setError] = useState(null); + const cacheRef = useRef>({}); const fetchFragments = useCallback(async () => { if (pocketId == null || pocketId === '') return; @@ -49,13 +59,13 @@ export function useChemblFragments(pocketId, options = {}, apiBase = '/api') { if (!res.ok) { throw new Error(`Failed to fetch fragments: HTTP ${res.status}`); } - const json_data = await res.json(); + const json_data = await safeJson(res); const list = (Array.isArray(json_data) ? json_data : []).map(normalizeFragment); cacheRef.current[cacheKey] = list; setFragments(list); - } catch (e) { - setError(e.message || 'Unknown fragments error'); + } catch (e: unknown) { + setError(e instanceof Error ? e.message : 'Unknown fragments error'); setFragments([]); } finally { setIsLoading(false); diff --git a/app/src/hooks/useComplex.js b/app/src/hooks/useComplex.ts similarity index 59% rename from app/src/hooks/useComplex.js rename to app/src/hooks/useComplex.ts index 6032c21..30853a2 100644 --- a/app/src/hooks/useComplex.js +++ b/app/src/hooks/useComplex.ts @@ -1,13 +1,15 @@ import { useState, useEffect } from 'react'; import { API_BASE } from '../config'; +import { safeJson } from '../utils/safeFetch'; +import type { Complex } from '../types'; // Module-level cache — persists across component mounts/unmounts -const complexCache = {}; +const complexCache: Record = {}; -export function useComplex(id) { - const [complex, setComplex] = useState(null); +export function useComplex(id: string | undefined) { + const [complex, setComplex] = useState(null); const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); + const [error, setError] = useState(null); useEffect(() => { if (!id) return; @@ -27,19 +29,23 @@ export function useComplex(id) { try { const response = await fetch(`${API_BASE}/complex/${encodeURIComponent(id)}`); - const body = await response.json(); + const body = await safeJson(response); if (!response.ok) { - throw new Error(body.message || 'Failed to load complex details'); + throw new Error(body?.message || `Failed to load complex details (HTTP ${response.status})`); + } + + if (!body) { + throw new Error('Server returned an empty response'); } if (isMounted) { complexCache[id] = body; setComplex(body); } - } catch (err) { + } catch (err: unknown) { if (isMounted) { - setError(err.message || 'An error occurred.'); + setError(err instanceof Error ? err.message : 'An error occurred.'); } } finally { if (isMounted) { diff --git a/app/src/hooks/useDockingJob.js b/app/src/hooks/useDockingJob.ts similarity index 69% rename from app/src/hooks/useDockingJob.js rename to app/src/hooks/useDockingJob.ts index 9cafb9a..e54d653 100644 --- a/app/src/hooks/useDockingJob.js +++ b/app/src/hooks/useDockingJob.ts @@ -1,6 +1,18 @@ import { useState, useEffect, useCallback, useRef } from 'react'; +import { safeJson } from '../utils/safeFetch'; +import type { Conformation, Fragment } from '../types'; -function normalizeConformations(statusBody) { +type DockingStep = 'idle' | 'running' | 'results' | 'error'; + +interface StatusBody { + status: string; + conformations?: Conformation[]; + pose_pdb?: string; + binding_affinity?: number; + error?: string; +} + +function normalizeConformations(statusBody: StatusBody): Conformation[] { if (Array.isArray(statusBody.conformations) && statusBody.conformations.length > 0) { return statusBody.conformations; } @@ -22,15 +34,15 @@ function normalizeConformations(statusBody) { * Orchestrates docking submission and status polling. */ export function useDockingJob(apiBase = '/api') { - const [step, setStep] = useState('idle'); - const [selectedFragment, setSelectedFragment] = useState(null); - const [conformations, setConformations] = useState([]); - const [activeConformation, setActiveConformation] = useState(null); - const [jobError, setJobError] = useState(null); - const [jobId, setJobId] = useState(null); - - const abortRef = useRef(null); - const pollTimerRef = useRef(null); + const [step, setStep] = useState('idle'); + const [selectedFragment, setSelectedFragment] = useState(null); + const [conformations, setConformations] = useState([]); + const [activeConformation, setActiveConformation] = useState(null); + const [jobError, setJobError] = useState(null); + const [jobId, setJobId] = useState(null); + + const abortRef = useRef(null); + const pollTimerRef = useRef | null>(null); const mountedRef = useRef(true); useEffect(() => { @@ -69,16 +81,16 @@ export function useDockingJob(apiBase = '/api') { setJobId(null); }, [clearPoll]); - const selectFragment = useCallback((f) => { + const selectFragment = useCallback((f: Fragment) => { setSelectedFragment(f); }, []); - const setActiveConformationCb = useCallback((c) => { + const setActiveConformationCb = useCallback((c: Conformation) => { setActiveConformation(c); }, []); const submitDocking = useCallback( - async (pocketId, proteinPdbId, sourceType) => { + async (pocketId: number, proteinPdbId: string, sourceType?: string) => { if (!selectedFragment?.smiles || !proteinPdbId) return; clearPoll(); @@ -117,7 +129,12 @@ export function useDockingJob(apiBase = '/api') { return; } - const body = await res.json(); + const body = await safeJson(res); + if (!body) { + setJobError('Server returned an empty response after docking submission'); + setStep('error'); + return; + } const id = body.job_id; if (!id) { setJobError('Missing job_id from server'); @@ -139,7 +156,12 @@ export function useDockingJob(apiBase = '/api') { setStep('error'); return; } - const result = await st.json(); + const result = await safeJson(st); + if (!result) { + setJobError('Server returned an empty status response'); + setStep('error'); + return; + } const status = result.status; if (status === 'done') { @@ -163,18 +185,18 @@ export function useDockingJob(apiBase = '/api') { delay = Math.min(maxDelay, Math.round(delay * 1.5)); pollTimerRef.current = setTimeout(poll, delay); - } catch (e) { - if (!mountedRef.current || e.name === 'AbortError') return; - setJobError(e.message || String(e)); + } catch (e: unknown) { + if (!mountedRef.current || (e instanceof Error && e.name === 'AbortError')) return; + setJobError(e instanceof Error ? e.message : String(e)); setStep('error'); } }; pollTimerRef.current = setTimeout(poll, delay); - } catch (e) { + } catch (e: unknown) { clearTimeout(submitTimeout); - if (!mountedRef.current || e.name === 'AbortError') return; - setJobError(e.message || String(e)); + if (!mountedRef.current || (e instanceof Error && e.name === 'AbortError')) return; + setJobError(e instanceof Error ? e.message : String(e)); setStep('error'); } }, diff --git a/app/src/hooks/useSearch.js b/app/src/hooks/useSearch.ts similarity index 62% rename from app/src/hooks/useSearch.js rename to app/src/hooks/useSearch.ts index 2ac54e4..6822630 100644 --- a/app/src/hooks/useSearch.js +++ b/app/src/hooks/useSearch.ts @@ -1,17 +1,24 @@ import { useState, useCallback } from 'react'; import { API_BASE } from '../config'; +import { safeJson } from '../utils/safeFetch'; +import type { Complex } from '../types'; + +interface SearchCacheEntry { + results: Complex[]; + source: string | null; +} // Module-level cache — persists across component mounts/unmounts -const searchCache = {}; +const searchCache: Record = {}; export function useSearch() { - const [results, setResults] = useState([]); + const [results, setResults] = useState([]); const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - const [source, setSource] = useState(null); + const [error, setError] = useState(null); + const [source, setSource] = useState(null); const [query, setQuery] = useState(''); - const search = useCallback(async (q) => { + const search = useCallback(async (q: string) => { const trimmedQuery = q?.trim(); if (!trimmedQuery) return; @@ -31,10 +38,14 @@ export function useSearch() { try { const response = await fetch(`${API_BASE}/search?q=${encodeURIComponent(trimmedQuery)}`); - const body = await response.json(); - + const body = await safeJson(response); + if (!response.ok) { - throw new Error(body.message || 'Search failed'); + throw new Error(body?.message || `Search failed (HTTP ${response.status})`); + } + + if (!body) { + throw new Error('Server returned an empty response'); } const fetchedResults = body.results || []; @@ -45,8 +56,8 @@ export function useSearch() { setResults(fetchedResults); setSource(fetchedSource); - } catch (err) { - setError(err.message || 'An error occurred during search.'); + } catch (err: unknown) { + setError(err instanceof Error ? err.message : 'An error occurred during search.'); setResults([]); } finally { setLoading(false); diff --git a/app/src/hooks/useTheme.js b/app/src/hooks/useTheme.ts similarity index 92% rename from app/src/hooks/useTheme.js rename to app/src/hooks/useTheme.ts index 69c7024..725b8a9 100644 --- a/app/src/hooks/useTheme.js +++ b/app/src/hooks/useTheme.ts @@ -1,7 +1,7 @@ import { useState, useEffect } from 'react'; export function useTheme() { - const [theme, setTheme] = useState(() => { + const [theme, setTheme] = useState(() => { // Initializer const savedTheme = localStorage.getItem('ProtPocket-theme'); return savedTheme ? savedTheme : 'light'; diff --git a/app/src/hooks/useUndrugged.js b/app/src/hooks/useUndrugged.ts similarity index 61% rename from app/src/hooks/useUndrugged.js rename to app/src/hooks/useUndrugged.ts index 053b6b1..2222966 100644 --- a/app/src/hooks/useUndrugged.js +++ b/app/src/hooks/useUndrugged.ts @@ -1,10 +1,12 @@ import { useState, useEffect } from 'react'; import { API_BASE } from '../config'; +import { safeJson } from '../utils/safeFetch'; +import type { Complex } from '../types'; export function useUndrugged(filter = 'all', limit = 25) { - const [data, setData] = useState([]); + const [data, setData] = useState([]); const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); + const [error, setError] = useState(null); useEffect(() => { let isMounted = true; @@ -16,21 +18,21 @@ export function useUndrugged(filter = 'all', limit = 25) { try { const url = new URL(`${API_BASE}/undrugged`, window.location.origin); url.searchParams.append('filter', filter); - url.searchParams.append('limit', limit); + url.searchParams.append('limit', String(limit)); const response = await fetch(url.pathname + url.search); - const body = await response.json(); + const body = await safeJson(response); if (!response.ok) { - throw new Error(body.message || 'Failed to load targets'); + throw new Error(body?.message || `Failed to load targets (HTTP ${response.status})`); } if (isMounted) { - setData(body.results || []); + setData(body?.results || []); } - } catch (err) { + } catch (err: unknown) { if (isMounted) { - setError(err.message || 'An error occurred.'); + setError(err instanceof Error ? err.message : 'An error occurred.'); } } finally { if (isMounted) { diff --git a/app/src/main.jsx b/app/src/main.tsx similarity index 62% rename from app/src/main.jsx rename to app/src/main.tsx index 54b39dd..964aeb4 100644 --- a/app/src/main.jsx +++ b/app/src/main.tsx @@ -1,9 +1,9 @@ import React from 'react' import ReactDOM from 'react-dom/client' -import App from './App.jsx' +import App from './App' import './index.css' -ReactDOM.createRoot(document.getElementById('root')).render( +ReactDOM.createRoot(document.getElementById('root')!).render( , diff --git a/app/src/pages/ComplexDetailPage.jsx b/app/src/pages/ComplexDetailPage.jsx deleted file mode 100644 index 69f0e62..0000000 --- a/app/src/pages/ComplexDetailPage.jsx +++ /dev/null @@ -1,247 +0,0 @@ -import React, { useState, useCallback } from 'react'; -import { useParams, useNavigate } from 'react-router-dom'; -import { useComplex } from '../hooks/useComplex'; -import { ComplexHeader } from '../components/complex/ComplexHeader'; -import { ProteinViewer } from '../components/complex/viewer/ProteinViewer'; -import { MetricsPanel } from '../components/complex/MetricsPanel'; -import { BindingSitesPanel } from '../components/complex/BindingSitesPanel'; -import { DockingPanel } from '../components/complex/DockingPanel'; -import { DockingLeaderboard, DockingResultDetail } from '../components/complex/DockingLeaderboard'; -import { LoadingState } from '../components/common/LoadingState'; -import { ErrorState } from '../components/common/ErrorState'; - -export function ComplexDetailPage() { - const { id } = useParams(); - const navigate = useNavigate(); - const { complex, loading, error } = useComplex(id); - const viewerRef = React.useRef(null); - - // Leaderboard state - const [leaderboard, setLeaderboard] = useState([]); - const [selectedEntry, setSelectedEntry] = useState(null); - - // Active docking pocket state — set when user clicks "Dock Molecule" on a pocket row - const [activeDocking, setActiveDocking] = useState(null); // { pocket, sourceType, proteinPdbId, activeTab } - - // Called when user clicks "Dock Molecule" on a pocket row - const handleStartDocking = useCallback((info) => { - // If clicking the same pocket, toggle off - if (activeDocking?.pocket?.pocket_id === info.pocket.pocket_id && activeDocking?.sourceType === info.sourceType) { - viewerRef.current?.clearConformations?.('both'); - setActiveDocking(null); - return; - } - // Clear any previous docked molecule before switching - viewerRef.current?.clearConformations?.('both'); - setActiveDocking(info); - setSelectedEntry(null); - }, [activeDocking]); - - // Called when docking completes - const handleDockingComplete = useCallback((result) => { - const entryId = `${result.sourceType}-${result.pocketId}-${result.fragmentId}-${Date.now()}`; - const newEntry = { ...result, id: entryId }; - setLeaderboard((prev) => { - if (prev.some(e => e.pocketId === result.pocketId && e.fragmentId === result.fragmentId && e.sourceType === result.sourceType)) { - return prev; - } - return [...prev, newEntry]; - }); - setSelectedEntry(newEntry); - setActiveDocking(null); - // Clear any old pose, then show the new one - viewerRef.current?.clearConformations?.('both'); - const target = result.sourceType === 'monomer' ? 'monomer' : 'complex'; - if (result.conformations?.length) { - viewerRef.current?.setConformations?.(result.conformations, 1, target); - } - }, []); - - // Called when undock/re-dock is clicked in DockingPanel - const handleUndock = useCallback(() => { - viewerRef.current?.clearConformations?.('both'); - viewerRef.current?.clearPocketHighlight?.(); - }, []); - - // Called when user selects a leaderboard entry - const handleLeaderboardSelect = useCallback((entry) => { - setSelectedEntry(entry); - setActiveDocking(null); - // Clear old pose first, then show the selected one - viewerRef.current?.clearConformations?.('both'); - const target = entry.sourceType === 'monomer' ? 'monomer' : 'complex'; - if (entry.conformations?.length) { - viewerRef.current?.setConformations?.(entry.conformations, 1, target); - } - }, []); - - // Called when user removes a leaderboard entry - const handleLeaderboardRemove = useCallback((entryId) => { - setLeaderboard((prev) => prev.filter(e => e.id !== entryId)); - setSelectedEntry((prev) => prev?.id === entryId ? null : prev); - }, []); - - // Called when user clicks a conformation in the detail panel - const handleConformationSelect = useCallback((entry, mode) => { - const target = entry.sourceType === 'monomer' ? 'monomer' : 'complex'; - if (entry.conformations?.length) { - viewerRef.current?.setConformations?.(entry.conformations, mode, target); - } - }, []); - - // Determine what to show in the right panel - const renderRightPanel = () => { - // If actively docking a pocket, show DockingPanel - if (activeDocking) { - return ( -
-
-
- - - - - Dock — Pocket #{activeDocking.pocket.pocket_id} - - - {activeDocking.sourceType} - -
- -
- { - const target = activeDocking.activeTab === 'monomer' ? 'monomer' : 'complex'; - if (confs) { - viewerRef.current?.setConformations?.(confs, mode, target); - } else { - viewerRef.current?.clearConformations?.(target); - } - }} - onUndock={handleUndock} - onDockingComplete={handleDockingComplete} - /> -
- ); - } - - // If a leaderboard entry is selected, show result detail - if (selectedEntry) { - return ; - } - - // Default placeholder - return ( -
- - - - - Select a pocket to dock - - - Click "Dock Molecule" on any pocket, or select a result from the leaderboard - -
- ); - }; - - return ( -
-
- - - - {loading && } - {error && } - - {!loading && !error && complex && ( -
- - - - - {/* Docking workspace — below Structural Metrics */} -
- {/* Left: Leaderboard */} -
-
-
- - - - - Docking Leaderboard - - {leaderboard.length > 0 && ( - - {leaderboard.length} - - )} -
-
-
- -
-
- - {/* Right: Docking UI or Result Detail */} -
- {renderRightPanel()} -
-
- - viewerRef.current?.highlightPocket?.(indices, target)} - onClearHighlight={(target) => { - viewerRef.current?.clearPocketHighlight?.(target); - viewerRef.current?.clearConformations?.(target); - }} - monomerStructureUrl={complex.monomer_structure_url?.replace(/\.cif$/i, '.pdb') || ''} - complexStructureUrl={complex.complex_structure_url?.replace(/\.cif$/i, '.pdb') || complex.uniprot_id || ''} - onConformationChange={(confs, mode, target) => viewerRef.current?.setConformations?.(confs, mode, target)} - onStartDocking={handleStartDocking} - activeDockingPocketId={activeDocking?.pocket?.pocket_id} - /> -
- )} -
-
- ); -} diff --git a/app/src/pages/ComplexDetailPage.tsx b/app/src/pages/ComplexDetailPage.tsx new file mode 100644 index 0000000..bc77e07 --- /dev/null +++ b/app/src/pages/ComplexDetailPage.tsx @@ -0,0 +1,137 @@ +import React, { useState, useCallback } from 'react'; +import { useParams, useNavigate } from 'react-router-dom'; +import { useComplex } from '../hooks/useComplex'; +import { ComplexHeader } from '../components/complex/ComplexHeader'; +import { ProteinViewer } from '../components/complex/viewer/ProteinViewer'; +import { MetricsPanel } from '../components/complex/MetricsPanel'; +import { BindingSitesPanel } from '../components/complex/BindingSitesPanel'; +import { DockingPanel } from '../components/complex/DockingPanel'; +import { DockingLeaderboard, DockingResultDetail } from '../components/complex/DockingLeaderboard'; +import { LoadingState } from '../components/common/LoadingState'; +import { ErrorState } from '../components/common/ErrorState'; +import type { Conformation, LeaderboardEntry, Pocket, ProteinViewerHandle, DockingInfo } from '../types'; + +export function ComplexDetailPage() { + const { id } = useParams<{ id: string }>(); + const navigate = useNavigate(); + const { complex, loading, error } = useComplex(id); + const viewerRef = React.useRef(null); + + const [leaderboard, setLeaderboard] = useState([]); + const [selectedEntry, setSelectedEntry] = useState(null); + const [activeDocking, setActiveDocking] = useState<(DockingInfo & { activeTab?: string }) | null>(null); + + const handleStartDocking = useCallback((info: DockingInfo) => { + if (activeDocking?.pocket?.pocket_id === info.pocket.pocket_id && activeDocking?.sourceType === info.sourceType) { + viewerRef.current?.clearConformations?.('both'); + setActiveDocking(null); + return; + } + viewerRef.current?.clearConformations?.('both'); + setActiveDocking(info); + setSelectedEntry(null); + }, [activeDocking]); + + const handleDockingComplete = useCallback((result: { pocketId: number; sourceType: string; fragmentId: string; fragmentName: string; smiles: string; bindingAffinity: number; conformations: Conformation[]; timestamp: number }) => { + const entryId = `${result.sourceType}-${result.pocketId}-${result.fragmentId}-${Date.now()}`; + const newEntry: LeaderboardEntry = { ...result, id: entryId }; + setLeaderboard((prev) => { + if (prev.some(e => e.pocketId === result.pocketId && e.fragmentId === result.fragmentId && e.sourceType === result.sourceType)) return prev; + return [...prev, newEntry]; + }); + setSelectedEntry(newEntry); + setActiveDocking(null); + viewerRef.current?.clearConformations?.('both'); + const target = result.sourceType === 'monomer' ? 'monomer' : 'complex'; + if (result.conformations?.length) { viewerRef.current?.setConformations?.(result.conformations, 1, target); } + }, []); + + const handleUndock = useCallback(() => { + viewerRef.current?.clearConformations?.('both'); + viewerRef.current?.clearPocketHighlight?.(); + }, []); + + const handleLeaderboardSelect = useCallback((entry: LeaderboardEntry) => { + setSelectedEntry(entry); + setActiveDocking(null); + viewerRef.current?.clearConformations?.('both'); + const target = entry.sourceType === 'monomer' ? 'monomer' : 'complex'; + if (entry.conformations?.length) { viewerRef.current?.setConformations?.(entry.conformations, 1, target); } + }, []); + + const handleLeaderboardRemove = useCallback((entryId: string) => { + setLeaderboard((prev) => prev.filter(e => e.id !== entryId)); + setSelectedEntry((prev) => prev?.id === entryId ? null : prev); + }, []); + + const handleConformationSelect = useCallback((entry: LeaderboardEntry, mode: number) => { + const target = entry.sourceType === 'monomer' ? 'monomer' : 'complex'; + if (entry.conformations?.length) { viewerRef.current?.setConformations?.(entry.conformations, mode, target); } + }, []); + + const renderRightPanel = () => { + if (activeDocking) { + return ( +
+
+
+ + Dock — Pocket #{activeDocking.pocket.pocket_id} + {activeDocking.sourceType} +
+ +
+ { const target = activeDocking.activeTab === 'monomer' ? 'monomer' : 'complex'; if (confs) { viewerRef.current?.setConformations?.(confs, mode!, target); } else { viewerRef.current?.clearConformations?.(target); } }} + onUndock={handleUndock} onDockingComplete={handleDockingComplete} /> +
+ ); + } + if (selectedEntry) { return ; } + return ( +
+ + Select a pocket to dock + Click "Dock Molecule" on any pocket, or select a result from the leaderboard +
+ ); + }; + + return ( +
+
+ + {loading && } + {error && } + {!loading && !error && complex && ( +
+ + + +
+
+
+
+ + Docking Leaderboard + {leaderboard.length > 0 && ({leaderboard.length})} +
+
+
+ +
+
+
{renderRightPanel()}
+
+ viewerRef.current?.highlightPocket?.(indices, target)} + onClearHighlight={(target) => { viewerRef.current?.clearPocketHighlight?.(target); viewerRef.current?.clearConformations?.(target); }} + monomerStructureUrl={complex.monomer_structure_url?.replace(/\.cif$/i, '.pdb') || ''} + complexStructureUrl={complex.complex_structure_url?.replace(/\.cif$/i, '.pdb') || complex.uniprot_id || ''} + onConformationChange={(confs, mode, target) => viewerRef.current?.setConformations?.(confs!, mode!, target)} + onStartDocking={handleStartDocking} activeDockingPocketId={activeDocking?.pocket?.pocket_id} /> +
+ )} +
+
+ ); +} diff --git a/app/src/pages/DashboardPage.jsx b/app/src/pages/DashboardPage.tsx similarity index 67% rename from app/src/pages/DashboardPage.jsx rename to app/src/pages/DashboardPage.tsx index 193bc21..c946222 100644 --- a/app/src/pages/DashboardPage.jsx +++ b/app/src/pages/DashboardPage.tsx @@ -11,28 +11,13 @@ export function DashboardPage() { return (
-
-

- Undrugged Target Leaderboard -

-

- Complexes are ranked by their structural gap score—the difference in AlphaFold confidence - between the monomeric and homodimeric states. A higher score indicates a region that only - becomes ordered upon interaction, revealing a potentially druggable cryptic pocket. -

+

Undrugged Target Leaderboard

+

Complexes are ranked by their structural gap score—the difference in AlphaFold confidence between the monomeric and homodimeric states. A higher score indicates a region that only becomes ordered upon interaction, revealing a potentially druggable cryptic pocket.

- {loading && } {error && } - - {!loading && !error && data && data.length > 0 && ( - - )} + {!loading && !error && data && data.length > 0 && ()} {!loading && !error && (!data || data.length === 0) && (
No targets found for the selected filter. diff --git a/app/src/pages/HomePage.jsx b/app/src/pages/HomePage.tsx similarity index 63% rename from app/src/pages/HomePage.jsx rename to app/src/pages/HomePage.tsx index 969e627..1c9d447 100644 --- a/app/src/pages/HomePage.jsx +++ b/app/src/pages/HomePage.tsx @@ -7,7 +7,7 @@ import { MolstarPanel } from '../components/complex/viewer/MolstarPanel'; export function HomePage() { const navigate = useNavigate(); - const handleSearch = (query) => { + const handleSearch = (query: string) => { navigate(`/search?q=${encodeURIComponent(query)}`); }; @@ -18,46 +18,22 @@ export function HomePage() { ]; const pipelineSteps = [ - { - num: '01', - title: 'Discover', - desc: 'Sifting through 1.7M AlphaFold complexes for high-confidence, undrugged WHO and human disease targets.' - }, - { - num: '02', - title: 'Reveal', - desc: 'Calculating thermodynamic Disorder Delta to find hidden structures that only stabilize upon dimerization.' - }, - { - num: '03', - title: 'Target', - desc: 'Running fpocket to autonomously identify geometric cavities situated on these stabilizing interfaces.' - }, - { - num: '04', - title: 'Dock', - desc: 'Performing high-throughput molecular docking of candidates directly inside the pocket using AutoDock Vina.' - } + { num: '01', title: 'Discover', desc: 'Sifting through 1.7M AlphaFold complexes for high-confidence, undrugged WHO and human disease targets.' }, + { num: '02', title: 'Reveal', desc: 'Calculating thermodynamic Disorder Delta to find hidden structures that only stabilize upon dimerization.' }, + { num: '03', title: 'Target', desc: 'Running fpocket to autonomously identify geometric cavities situated on these stabilizing interfaces.' }, + { num: '04', title: 'Dock', desc: 'Performing high-throughput molecular docking of candidates directly inside the pocket using AutoDock Vina.' } ]; return (
- {/* Section 1 — Hero */}
- - End-to-End Drug Lead Generation Platform - -

- From predicted complex to drug lead. Fast. -

-

- ProtPocket surfaces the highest-priority undrugged targets from the AlphaFold complex dataset. We compute structural gap scores and interface pocket viability to jumpstart novel therapeutic design. -

+ End-to-End Drug Lead Generation Platform +

From predicted complex to drug lead. Fast.

+

ProtPocket surfaces the highest-priority undrugged targets from the AlphaFold complex dataset. We compute structural gap scores and interface pocket viability to jumpstart novel therapeutic design.

-
@@ -81,17 +57,12 @@ export function HomePage() {

The Pipeline

-

- We cross-reference AlphaFold structures, ChEMBL drug data, and WHO priority lists in real-time, feeding the best candidates into our autonomous pocket analysis engine. -

+

We cross-reference AlphaFold structures, ChEMBL drug data, and WHO priority lists in real-time, feeding the best candidates into our autonomous pocket analysis engine.

-
{pipelineSteps.map((step, idx) => (
-
- {step.num} -
+
{step.num}

{step.title}

{step.desc}

@@ -100,44 +71,21 @@ export function HomePage() {
- {/* Section 4 — The Science (Interface Pockets) */} + {/* Section 4 — The Science */}
- - The Holy Grail of PPIs - -

- Targeting the Disorder Delta -

-

- Many proteins appear completely disordered as single monomers, but snap into highly stable structures when bound to their partner. We call this the Disorder Delta. -

-

- By combining thermodynamic confidence scoring (pLDDT) with geometric cavity detection (fpocket), ProtPocket flags cavities that sit exactly on these newly stabilized interfaces. These are the prime targets for Protein-Protein Interaction (PPI) inhibitors. -

+ The Holy Grail of PPIs +

Targeting the Disorder Delta

+

Many proteins appear completely disordered as single monomers, but snap into highly stable structures when bound to their partner. We call this the Disorder Delta.

+

By combining thermodynamic confidence scoring (pLDDT) with geometric cavity detection (fpocket), ProtPocket flags cavities that sit exactly on these newly stabilized interfaces. These are the prime targets for Protein-Protein Interaction (PPI) inhibitors.

- {/* Dual Mol* Viewer Setup for Q55DI5 */}
- +
- +
@@ -150,19 +98,12 @@ export function HomePage() {

Analyze Live Targets

Select a curated complex to see the pipeline in action
-
{DEMO_PROTEINS.map((protein) => ( -
navigate(`/complex/${protein.id}`)} - className="flex flex-col gap-4 p-6 bg-bg-secondary border border-border rounded-lg hover:border-accent hover:shadow-[0_4px_20px_rgba(0,0,0,0.05)] cursor-pointer transition-all duration-300" - > +
navigate(`/complex/${protein.id}`)} className="flex flex-col gap-4 p-6 bg-bg-secondary border border-border rounded-lg hover:border-accent hover:shadow-[0_4px_20px_rgba(0,0,0,0.05)] cursor-pointer transition-all duration-300">
{protein.label} -
- ↗ -
+
{protein.description}
@@ -170,7 +111,6 @@ export function HomePage() {
-
); } diff --git a/app/src/pages/SearchPage.jsx b/app/src/pages/SearchPage.tsx similarity index 77% rename from app/src/pages/SearchPage.jsx rename to app/src/pages/SearchPage.tsx index e6be6fd..c5dbbb5 100644 --- a/app/src/pages/SearchPage.jsx +++ b/app/src/pages/SearchPage.tsx @@ -12,15 +12,11 @@ export function SearchPage() { const { search, results, loading, error, source, query } = useSearch(); useEffect(() => { - if (q) { - search(q); - } + if (q) { search(q); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [q]); - const handleSearch = (newQuery) => { - setSearchParams({ q: newQuery }); - }; - + const handleSearch = (newQuery: string) => { setSearchParams({ q: newQuery }); }; const hasSearched = !!query; const hasResults = results.length > 0; @@ -28,11 +24,8 @@ export function SearchPage() {
- {loading && } - {error && } - {!loading && !error && hasSearched && (
{hasResults ? ( @@ -42,19 +35,13 @@ export function SearchPage() { source: {source}
- {results.map((complex) => ( - - ))} + {results.map((complex) => ())}
) : (
- - No targets found matching "{query}" - - - Try adjusting your search terms or exploring the dashboard. - + No targets found matching "{query}" + Try adjusting your search terms or exploring the dashboard.
)}
diff --git a/app/src/scss.d.ts b/app/src/scss.d.ts new file mode 100644 index 0000000..18ded59 --- /dev/null +++ b/app/src/scss.d.ts @@ -0,0 +1,4 @@ +declare module '*.scss' { + const content: string; + export default content; +} diff --git a/app/src/types.ts b/app/src/types.ts new file mode 100644 index 0000000..9893839 --- /dev/null +++ b/app/src/types.ts @@ -0,0 +1,157 @@ +// ── Shared domain types ──────────────────────────────────────────── +// Inferred from existing code usage; kept minimal to avoid deep refactors. + +export interface DemoProtein { + id: string; + label: string; + description: string; +} + +export interface Complex { + uniprot_id: string; + alphafold_id: string; + protein_name: string; + gene_name: string; + organism: string; + disease_associations: string[]; + is_who_pathogen: boolean; + drug_count: number; + review_status: string; + monomer_plddt_avg: number; + dimer_plddt_avg: number; + disorder_delta: number; + gap_score: number; + category: string; + known_drug_names: string[]; + monomer_structure_url: string; + complex_structure_url: string; +} + +export interface Pocket { + pocket_id: number; + druggability_score: number; + volume: number; + hydrophobicity: number; + polarity: number; + avg_plddt: number; + avg_disorder_delta: number; + center: [number, number, number] | null; + residue_names: string[]; + residue_indices: number[]; + is_interface_pocket: boolean; + is_conserved: boolean; + is_emergent: boolean; +} + +export interface Conformation { + mode: number; + binding_affinity: number; + rmsd_lb: number; + rmsd_ub: number; + pose_pdb: string; +} + +export interface Fragment { + chembl_id: string; + zinc_id?: string; + id?: string; + name?: string; + smiles?: string; + mw?: number; + mol_weight?: number; + logp?: number; +} + +export interface LeaderboardEntry { + id: string; + pocketId: number; + sourceType: string; + fragmentId: string; + fragmentName: string; + smiles: string; + bindingAffinity: number; + conformations: Conformation[]; + timestamp: number; +} + +export interface BindingSitesData { + pockets: Pocket[]; + total_pockets: number; + monomer_pockets: Pocket[]; + monomer_total_pockets: number; + interface_pocket_count: number; + comparison: ComparisonData | null; +} + +export interface ComparisonData { + summary_metrics: { + total_monomer_pockets: number; + total_dimer_pockets: number; + avg_monomer_druggability: number; + avg_dimer_druggability: number; + }; + ddgi: number; + pocket_mapping: { + conserved_count: number; + monomer_only_count: number; + emergent_count: number; + interface_count: number; + }; + interface_pockets: Pocket[]; + conserved_pockets: Pocket[]; + emergent_pockets: Pocket[]; + graph_datasets: { + stabilization_scatter: ScatterDataPoint[]; + }; + property_changes: { + monomer_avg_volume: number; + dimer_avg_volume: number; + monomer_avg_hydrophobicity: number; + dimer_avg_hydrophobicity: number; + monomer_avg_polarity: number; + dimer_avg_polarity: number; + }; + stabilization_stats: { + enrichment_score: number; + }; + fragment_comparison: { + unique_interface_fragments: Fragment[]; + unique_dimer_fragments: Fragment[]; + } | null; +} + +export interface ScatterDataPoint { + avg_delta: number; + druggability_score: number; +} + +export interface DockingInfo { + pocket: Pocket; + sourceType: string; + proteinPdbId: string; + activeTab?: string; +} + +export interface DockingResult { + pocketId: number; + sourceType: string; + fragmentId: string; + fragmentName: string; + smiles: string; + bindingAffinity: number; + conformations: Conformation[]; + timestamp: number; +} + +// Mol* viewer imperative handle +export interface ProteinViewerHandle { + highlightPocket: (residueIndices: number[], target?: string) => void; + clearPocketHighlight: (target?: string) => void; + setConformations: (confs: Conformation[], mode: number, target?: string) => void; + clearConformations: (target?: string) => void; +} + +export interface MolstarPanelHandle { + highlightPocket: (residueIndices: number[]) => Promise; + clearPocketHighlight: () => Promise; +} diff --git a/app/src/utils/safeFetch.ts b/app/src/utils/safeFetch.ts new file mode 100644 index 0000000..23dcde5 --- /dev/null +++ b/app/src/utils/safeFetch.ts @@ -0,0 +1,14 @@ +/** + * Safely parse a Response body as JSON. + * Returns `null` if the body is empty or not valid JSON, + * instead of throwing "Unexpected end of JSON input". + */ +export async function safeJson(response: Response): Promise { + const text = await response.text(); + if (!text || text.trim().length === 0) return null; + try { + return JSON.parse(text) as T; + } catch { + return null; + } +} diff --git a/app/tsconfig.json b/app/tsconfig.json new file mode 100644 index 0000000..d8b1a0d --- /dev/null +++ b/app/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noFallthroughCasesInSwitch": true, + + /* Allow JS interop */ + "allowJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src", "vite-env.d.ts"] +} diff --git a/app/vite-env.d.ts b/app/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/app/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/app/vite.config.js b/app/vite.config.ts similarity index 100% rename from app/vite.config.js rename to app/vite.config.ts From 96e10d1eb71a88d6434394184086881a8b3bb48b Mon Sep 17 00:00:00 2001 From: Arshita Jaryal Date: Thu, 14 May 2026 19:17:08 +0530 Subject: [PATCH 2/3] Remove dist from tracking --- .gitignore | 2 + app/dist/assets/index-DHFWRlXl.js | 7504 ---------------------------- app/dist/assets/index-Y4Qzsb0-.css | 2 - app/dist/favicon.png | Bin 87962 -> 0 bytes app/dist/index.html | 17 - 5 files changed, 2 insertions(+), 7523 deletions(-) delete mode 100644 app/dist/assets/index-DHFWRlXl.js delete mode 100644 app/dist/assets/index-Y4Qzsb0-.css delete mode 100644 app/dist/favicon.png delete mode 100644 app/dist/index.html diff --git a/.gitignore b/.gitignore index 7f9db40..96ac8a2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .env node_modules/ /tmp/ +dist/ +app/dist/ \ No newline at end of file diff --git a/app/dist/assets/index-DHFWRlXl.js b/app/dist/assets/index-DHFWRlXl.js deleted file mode 100644 index ff4bcf0..0000000 --- a/app/dist/assets/index-DHFWRlXl.js +++ /dev/null @@ -1,7504 +0,0 @@ -var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(e&&(t=e(e=0)),t),s=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),c=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},l=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},u=(n,r,a)=>(a=n==null?{}:e(i(n)),l(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n)),d=e=>a.call(e,`module.exports`)?e[`module.exports`]:l(t({},`__esModule`,{value:!0}),e);(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var f=s((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=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,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var S=Array.isArray;function C(){}var w={H:null,A:null,T:null,S:null},T=Object.prototype.hasOwnProperty;function E(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function D(e,t){return E(e.type,t,e.props)}function O(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function k(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var A=/\/+/g;function ee(e,t){return typeof e==`object`&&e&&e.key!=null?k(``+e.key):t.toString(36)}function te(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(C,C):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function j(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,j(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+ee(e,0):a,S(o)?(i=``,c!=null&&(i=c.replace(A,`$&/`)+`/`),j(o,r,i,``,function(e){return e})):o!=null&&(O(o)&&(o=D(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(A,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(S(e))for(var u=0;u{t.exports=f()})),m=s((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,S||(S=!0,O());else{var t=n(l);t!==null&&ee(x,t.startTime-e)}}var S=!1,C=-1,w=5,T=-1;function E(){return g?!0:!(e.unstable_now()-Tt&&E());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&ee(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?O():S=!1}}}var O;if(typeof y==`function`)O=function(){y(D)};else if(typeof MessageChannel<`u`){var k=new MessageChannel,A=k.port2;k.port1.onmessage=D,O=function(){A.postMessage(null)}}else O=function(){_(D,0)};function ee(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,ee(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,O()))),r},e.unstable_shouldYield=E,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),h=s(((e,t)=>{t.exports=m()})),g=s((e=>{var t=p();function n(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=g()})),v=s((e=>{var t=h(),n=p(),r=_();function i(e){var t=`https://react.dev/errors/`+e;if(1se||(e.current=oe[se],oe[se]=null,se--)}function ue(e,t){se++,oe[se]=e.current,e.current=t}var de=ce(null),fe=ce(null),pe=ce(null),me=ce(null);function he(e,t){switch(ue(pe,t),ue(fe,e),ue(de,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Jd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Jd(t),e=Yd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}le(de),ue(de,e)}function ge(){le(de),le(fe),le(pe)}function _e(e){e.memoizedState!==null&&ue(me,e);var t=de.current,n=Yd(t,e.type);t!==n&&(ue(fe,e),ue(de,n))}function ve(e){fe.current===e&&(le(de),le(fe)),me.current===e&&(le(me),Zf._currentValue=ae)}var ye,be;function xe(e){if(ye===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);ye=t&&t[1]||``,be=-1)`:-1i||c[r]!==l[i]){var u=` -`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{Se=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?xe(n):``}function we(e,t){switch(e.tag){case 26:case 27:case 5:return xe(e.type);case 16:return xe(`Lazy`);case 13:return e.child!==t&&t!==null?xe(`Suspense Fallback`):xe(`Suspense`);case 19:return xe(`SuspenseList`);case 0:case 15:return Ce(e.type,!1);case 11:return Ce(e.type.render,!1);case 1:return Ce(e.type,!0);case 31:return xe(`Activity`);default:return``}}function Te(e){try{var t=``,n=null;do t+=we(e,n),n=e,e=e.return;while(e);return t}catch(e){return` -Error generating stack: `+e.message+` -`+e.stack}}var Ee=Object.prototype.hasOwnProperty,De=t.unstable_scheduleCallback,Oe=t.unstable_cancelCallback,ke=t.unstable_shouldYield,Ae=t.unstable_requestPaint,je=t.unstable_now,Me=t.unstable_getCurrentPriorityLevel,Ne=t.unstable_ImmediatePriority,Pe=t.unstable_UserBlockingPriority,Fe=t.unstable_NormalPriority,Ie=t.unstable_LowPriority,Le=t.unstable_IdlePriority,Re=t.log,ze=t.unstable_setDisableYieldValue,Be=null,Ve=null;function He(e){if(typeof Re==`function`&&ze(e),Ve&&typeof Ve.setStrictMode==`function`)try{Ve.setStrictMode(Be,e)}catch{}}var Ue=Math.clz32?Math.clz32:Ke,We=Math.log,Ge=Math.LN2;function Ke(e){return e>>>=0,e===0?32:31-(We(e)/Ge|0)|0}var qe=256,Je=262144,Ye=4194304;function Xe(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 Ze(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=Xe(n))):i=Xe(o):i=Xe(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=Xe(n))):i=Xe(o)):i=Xe(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function Qe(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function $e(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 et(){var e=Ye;return Ye<<=1,!(Ye&62914560)&&(Ye=4194304),e}function tt(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function nt(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function rt(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),fn=!1;if(dn)try{var pn={};Object.defineProperty(pn,`passive`,{get:function(){fn=!0}}),window.addEventListener(`test`,pn,pn),window.removeEventListener(`test`,pn,pn)}catch{fn=!1}var mn=null,hn=null,gn=null;function _n(){if(gn)return gn;var e,t=hn,n=t.length,r,i=`value`in mn?mn.value:mn.textContent,a=i.length;for(e=0;e=Wn),qn=` `,Jn=!1;function Yn(e,t){switch(e){case`keyup`:return Hn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function Xn(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var Zn=!1;function Qn(e,t){switch(e){case`compositionend`:return Xn(t);case`keypress`:return t.which===32?(Jn=!0,qn):null;case`textInput`:return e=t.data,e===qn&&Jn?null:e;default:return null}}function $n(e,t){if(Zn)return e===`compositionend`||!Un&&Yn(e,t)?(e=_n(),gn=hn=mn=null,Zn=!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:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=xr(n)}}function Cr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Cr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function wr(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Bt(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=Bt(e.document)}return t}function Tr(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 Er=dn&&`documentMode`in document&&11>=document.documentMode,Dr=null,Or=null,kr=null,Ar=!1;function jr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Ar||Dr==null||Dr!==Bt(r)||(r=Dr,`selectionStart`in r&&Tr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),kr&&br(kr,r)||(kr=r,r=Md(Or,`onSelect`),0>=o,i-=o,Ci=1<<32-Ue(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),Mi&&Ti(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),Mi&&Ti(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return Mi&&Ti(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),Mi&&Ti(a,g),u}function b(e,r,o,c){if(typeof o==`object`&&o&&o.type===y&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case g:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===y){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===O&&Ta(l)===r.type){n(e,r.sibling),c=a(r,o.props),Ma(c,o),c.return=e,e=c;break a}n(e,r);break}else t(e,r);r=r.sibling}o.type===y?(c=ui(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=li(o.type,o.key,o.props,null,e.mode,c),Ma(c,o),c.return=e,e=c)}return s(e);case v:a:{for(l=o.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}else{n(e,r);break}else t(e,r);r=r.sibling}c=pi(o,e.mode,c),c.return=e,e=c}return s(e);case O:return o=Ta(o),b(e,r,o,c)}if(re(o))return h(e,r,o,c);if(te(o)){if(l=te(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),_(e,r,o,c)}if(typeof o.then==`function`)return b(e,r,ja(o),c);if(o.$$typeof===C)return b(e,r,ea(e,o),c);Na(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=di(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{Aa=0;var i=b(e,t,n,r);return ka=null,i}catch(t){if(t===ya||t===xa)throw t;var a=ai(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var Fa=Pa(!0),Ia=Pa(!1),La=!1;function Ra(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function za(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 Ba(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Va(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,Rl&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=ni(e),ti(e,null,n),t}return Qr(e,r,t,n),ni(e)}function Ha(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,at(e,n)}}function Ua(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Wa=!1;function Ga(){if(Wa){var e=da;if(e!==null)throw e}}function Ka(e,t,n,r){Wa=!1;var i=e.updateQueue;La=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var p=s.lane&-536870913,m=p!==s.lane;if(m?(Vl&p)===p:(r&p)===p){p!==0&&p===ua&&(Wa=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var h=e,g=s;p=t;var _=n;switch(g.tag){case 1:if(h=g.payload,typeof h==`function`){d=h.call(_,d,p);break a}d=h;break a;case 3:h.flags=h.flags&-65537|128;case 0:if(h=g.payload,p=typeof h==`function`?h.call(_,d,p):h,p==null)break a;d=f({},d,p);break a;case 2:La=!0}}p=s.callback,p!==null&&(e.flags|=64,m&&(e.flags|=8192),m=i.callbacks,m===null?i.callbacks=[p]:m.push(p))}else m={lane:p,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=m,c=d):u=u.next=m,o|=p;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;m=s,s=m.next,m.next=null,i.lastBaseUpdate=m,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Yl|=o,e.lanes=o,e.memoizedState=d}}function qa(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function Ja(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=M.T,s={};M.T=s,Ms(e,!1,t,n);try{var c=i(),l=M.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?js(e,t,cee(c,r),_u(e)):js(e,t,r,_u(e))}catch(n){js(e,t,{then:function(){},status:`rejected`,reason:n},_u())}finally{ie.p=a,o!==null&&s.types!==null&&(o.types=s.types),M.T=o}}function Ss(){}function Cs(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=ws(e).queue;xs(e,a,t,ae,n===null?Ss:function(){return Ts(e),n(r)})}function ws(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:ae,baseState:ae,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Io,lastRenderedState:ae},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Io,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function Ts(e){var t=ws(e);t.next===null&&(t=e.alternate.memoizedState),js(e,t.next.queue,{},_u())}function Es(){return $i(Zf)}function Ds(){return jo().memoizedState}function Os(){return jo().memoizedState}function dee(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=_u();e=Ba(n);var r=Va(t,e,n);r!==null&&(yu(r,t,n),Ha(r,t,n)),t={cache:oa()},e.payload=t;return}t=t.return}}function ks(e,t,n){var r=_u();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Ns(e)?Ps(t,n):(n=$r(e,t,n,r),n!==null&&(yu(n,e,r),Fs(n,t,r)))}function As(e,t,n){js(e,t,n,_u())}function js(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Ns(e))Ps(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,yr(s,o))return Qr(e,t,i,0),zl===null&&Zr(),!1}catch{}if(n=$r(e,t,i,r),n!==null)return yu(n,e,r),Fs(n,t,r),!0}return!1}function Ms(e,t,n,r){if(r={lane:2,revertLane:gd(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Ns(e)){if(t)throw Error(i(479))}else t=$r(e,n,r,2),t!==null&&yu(t,e,2)}function Ns(e){var t=e.alternate;return e===uo||t!==null&&t===uo}function Ps(e,t){ho=mo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Fs(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,at(e,n)}}var Is={readContext:$i,use:Po,useCallback:xo,useContext:xo,useEffect:xo,useImperativeHandle:xo,useLayoutEffect:xo,useInsertionEffect:xo,useMemo:xo,useReducer:xo,useRef:xo,useState:xo,useDebugValue:xo,useDeferredValue:xo,useTransition:xo,useSyncExternalStore:xo,useId:xo,useHostTransitionStatus:xo,useFormState:xo,useActionState:xo,useOptimistic:xo,useMemoCache:xo,useCacheRefresh:xo};Is.useEffectEvent=xo;var Ls={readContext:$i,use:Po,useCallback:function(e,t){return Ao().memoizedState=[e,t===void 0?null:t],e},useContext:$i,useEffect:ls,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),ss(4194308,4,ms.bind(null,t,e),n)},useLayoutEffect:function(e,t){return ss(4194308,4,e,t)},useInsertionEffect:function(e,t){ss(4,2,e,t)},useMemo:function(e,t){var n=Ao();t=t===void 0?null:t;var r=e();if(go){He(!0);try{e()}finally{He(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=Ao();if(n!==void 0){var i=n(t);if(go){He(!0);try{n(t)}finally{He(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=ks.bind(null,uo,e),[r.memoizedState,e]},useRef:function(e){var t=Ao();return e={current:e},t.memoizedState=e},useState:function(e){e=Ko(e);var t=e.queue,n=As.bind(null,uo,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:gs,useDeferredValue:function(e,t){return ys(Ao(),e,t)},useTransition:function(){var e=Ko(!1);return e=xs.bind(null,uo,e.queue,!0,!1),Ao().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=uo,a=Ao();if(Mi){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),zl===null)throw Error(i(349));Vl&127||Vo(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,ls(Uo.bind(null,r,o,e),[e]),r.flags|=2048,as(9,{destroy:void 0},Ho.bind(null,r,o,n,t),null),n},useId:function(){var e=Ao(),t=zl.identifierPrefix;if(Mi){var n=wi,r=Ci;n=(r&~(1<<32-Ue(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=_o++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[ft]=t,o[pt]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(Vd(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&Ac(t)}}return Fc(t),jc(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&Ac(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=pe.current,zi(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=Ai,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[ft]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||Rd(e.nodeValue,n)),e||Ii(t,!0)}else e=qd(e).createTextNode(r),e[ft]=t,t.stateNode=e}return Fc(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=zi(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[ft]=t}else Bi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Fc(t),e=!1}else n=Vi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(oo(t),t):(oo(t),null);if(t.flags&128)throw Error(i(558))}return Fc(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=zi(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[ft]=t}else Bi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Fc(t),a=!1}else a=Vi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(oo(t),t):(oo(t),null)}return oo(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),Nc(t,t.updateQueue),Fc(t),null);case 4:return ge(),e===null&&Od(t.stateNode.containerInfo),Fc(t),null;case 10:return qi(t.type),Fc(t),null;case 19:if(le(so),r=t.memoizedState,r===null)return Fc(t),null;if(a=(t.flags&128)!=0,o=r.rendering,o===null)if(a)Pc(r,!1);else{if(Jl!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=co(e),o!==null){for(t.flags|=128,Pc(r,!1),e=o.updateQueue,t.updateQueue=e,Nc(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)ci(n,e),n=n.sibling;return ue(so,so.current&1|2),Mi&&Ti(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&je()>au&&(t.flags|=128,a=!0,Pc(r,!1),t.lanes=4194304)}else{if(!a)if(e=co(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,Nc(t,e),Pc(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!Mi)return Fc(t),null}else 2*je()-r.renderingStartTime>au&&n!==536870912&&(t.flags|=128,a=!0,Pc(r,!1),t.lanes=4194304);r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(Fc(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=je(),e.sibling=null,n=so.current,ue(so,a?n&1|2:n&1),Mi&&Ti(t,r.treeForkCount),e);case 22:case 23:return oo(t),$a(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(Fc(t),t.subtreeFlags&6&&(t.flags|=8192)):Fc(t),n=t.updateQueue,n!==null&&Nc(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&le(ha),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),qi(aa),Fc(t),null;case 25:return null;case 30:return null}throw Error(i(156,t.tag))}function Lc(e,t){switch(Oi(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return qi(aa),ge(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return ve(t),null;case 31:if(t.memoizedState!==null){if(oo(t),t.alternate===null)throw Error(i(340));Bi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(oo(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));Bi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return le(so),null;case 4:return ge(),null;case 10:return qi(t.type),null;case 22:case 23:return oo(t),$a(),e!==null&&le(ha),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return qi(aa),null;case 25:return null;default:return null}}function Rc(e,t){switch(Oi(t),t.tag){case 3:qi(aa),ge();break;case 26:case 27:case 5:ve(t);break;case 4:ge();break;case 31:t.memoizedState!==null&&oo(t);break;case 13:oo(t);break;case 19:le(so);break;case 10:qi(t.type);break;case 22:case 23:oo(t),$a(),e!==null&&le(ha);break;case 24:qi(aa)}}function zc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Yu(t,t.return,e)}}function Bc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Yu(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Yu(t,t.return,e)}}function Vc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Ja(t,n)}catch(t){Yu(e,e.return,t)}}}function Hc(e,t,n){n.props=Ws(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Yu(e,t,n)}}function Uc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Yu(e,t,n)}}function Wc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null)if(typeof r==`function`)try{r()}catch(n){Yu(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Yu(e,t,n)}else n.current=null}function Gc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Yu(e,e.return,t)}}function Kc(e,t,n){try{var r=e.stateNode;Hd(r,e.type,n,t),r[pt]=t}catch(t){Yu(e,e.return,t)}}function qc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&tf(e.type)||e.tag===4}function Jc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||qc(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&&tf(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Yc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=tn));else if(r!==4&&(r===27&&tf(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(Yc(e,t,n),e=e.sibling;e!==null;)Yc(e,t,n),e=e.sibling}function Xc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&tf(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Xc(e,t,n),e=e.sibling;e!==null;)Xc(e,t,n),e=e.sibling}function Zc(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Vd(t,r,n),t[ft]=e,t[pt]=n}catch(t){Yu(e,e.return,t)}}var Qc=!1,$c=!1,el=!1,tl=typeof WeakSet==`function`?WeakSet:Set,nl=null;function rl(e,t){if(e=e.containerInfo,Gd=ap,e=wr(e),Tr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var a=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||a!==0&&f.nodeType!==3||(c=s+a),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===a&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(Kd={focusedElem:e,selectionRange:n},ap=!1,nl=t;nl!==null;)if(t=nl,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,nl=e;else for(;nl!==null;){switch(t=nl,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),Vd(o,r,n),o[ft]=e,Tt(o),r=o;break a;case`link`:var s=Hf(`link`,`href`,a).get(r+(n.href||``));if(s){for(var c=0;cg&&(o=g,g=h,h=o);var _=Sr(s,h),v=Sr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,M.T=null,n=pu,pu=null;var o=lu,s=du;if(cu=0,uu=lu=null,du=0,Rl&6)throw Error(i(331));var c=Rl;if(Rl|=4,Nl(o.current),Tl(o,o.current,s,n),Rl=c,ld(0,!1),Ve&&typeof Ve.onPostCommitFiberRoot==`function`)try{Ve.onPostCommitFiberRoot(Be,o)}catch{}return!0}finally{ie.p=a,M.T=r,Gu(e,t)}}function Ju(e,t,n){t=hi(n,t),t=Xs(e.stateNode,t,2),e=Va(e,t,2),e!==null&&(nt(e,2),cd(e))}function Yu(e,t,n){if(e.tag===3)Ju(e,e,n);else for(;t!==null;){if(t.tag===3){Ju(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(su===null||!su.has(r))){e=hi(n,e),n=Zs(2),r=Va(t,n,2),r!==null&&(Qs(n,r,t,e),nt(r,2),cd(r));break}}t=t.return}}function Xu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Ll;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(Kl=!0,i.add(n),e=Zu.bind(null,e,t,n),t.then(e,e))}function Zu(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,zl===e&&(Vl&n)===n&&(Jl===4||Jl===3&&(Vl&62914560)===Vl&&300>je()-ru?!(Rl&2)&&Eu(e,0):Zl|=n,$l===Vl&&($l=0)),cd(e)}function Qu(e,t){t===0&&(t=et()),e=ei(e,t),e!==null&&(nt(e,t),cd(e))}function $u(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),Qu(e,n)}function ed(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),Qu(e,n)}function td(e,t){return De(e,t)}var nd=null,rd=null,id=!1,ad=!1,od=!1,sd=0;function cd(e){e!==rd&&e.next===null&&(rd===null?nd=rd=e:rd=rd.next=e),ad=!0,id||(id=!0,hd())}function ld(e,t){if(!od&&ad){od=!0;do for(var n=!1,r=nd;r!==null;){if(!t)if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-Ue(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,md(r,a))}else a=Vl,a=Ze(r,r===zl?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||Qe(r,a)||(n=!0,md(r,a));r=r.next}while(n);od=!1}}function ud(){dd()}function dd(){ad=id=!1;var e=0;sd!==0&&pee()&&(e=sd);for(var t=je(),n=null,r=nd;r!==null;){var i=r.next,a=fd(r,t);a===0?(r.next=null,n===null?nd=i:n.next=i,i===null&&(rd=n)):(n=r,(e!==0||a&3)&&(ad=!0)),r=i}cu!==0&&cu!==5||ld(e,!1),sd!==0&&(sd=0)}function fd(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Ud(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function Sf(e,t,n){var r=xf;if(r&&typeof t==`string`&&t){var i=Vt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),gf.has(i)||(gf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Vd(t,`link`,e),Tt(t),r.head.appendChild(t)))}}function Cf(e){vf.D(e),Sf(`dns-prefetch`,e,null)}function wf(e,t){vf.C(e,t),Sf(`preconnect`,e,t)}function Tf(e,t,n){vf.L(e,t,n);var r=xf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Vt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Vt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Vt(n.imageSizes)+`"]`)):i+=`[href="`+Vt(e)+`"]`;var a=i;switch(t){case`style`:a=jf(e);break;case`script`:a=Ff(e)}hf.has(a)||(e=f({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),hf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(Mf(a))||t===`script`&&r.querySelector(If(a))||(t=r.createElement(`link`),Vd(t,`link`,e),Tt(t),r.head.appendChild(t)))}}function Ef(e,t){vf.m(e,t);var n=xf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Vt(r)+`"][href="`+Vt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Ff(e)}if(!hf.has(a)&&(e=f({rel:`modulepreload`,href:e},t),hf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(If(a)))return}r=n.createElement(`link`),Vd(r,`link`,e),Tt(r),n.head.appendChild(r)}}}function Df(e,t,n){vf.S(e,t,n);var r=xf;if(r&&e){var i=wt(r).hoistableStyles,a=jf(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(Mf(a)))s.loading=5;else{e=f({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=hf.get(a))&&zf(e,n);var c=o=r.createElement(`link`);Tt(c),Vd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Rf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Of(e,t){vf.X(e,t);var n=xf;if(n&&e){var r=wt(n).hoistableScripts,i=Ff(e),a=r.get(i);a||(a=n.querySelector(If(i)),a||(e=f({src:e,async:!0},t),(t=hf.get(i))&&Bf(e,t),a=n.createElement(`script`),Tt(a),Vd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t){vf.M(e,t);var n=xf;if(n&&e){var r=wt(n).hoistableScripts,i=Ff(e),a=r.get(i);a||(a=n.querySelector(If(i)),a||(e=f({src:e,async:!0,type:`module`},t),(t=hf.get(i))&&Bf(e,t),a=n.createElement(`script`),Tt(a),Vd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Af(e,t,n,r){var a=(a=pe.current)?_f(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=jf(n.href),n=wt(a).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=jf(n.href);var o=wt(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(Mf(e)))&&!o._p&&(s.instance=o,s.state.loading=5),hf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},hf.set(e,n),o||Pf(a,e,n,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Ff(n),n=wt(a).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function jf(e){return`href="`+Vt(e)+`"`}function Mf(e){return`link[rel="stylesheet"][`+e+`]`}function Nf(e){return f({},e,{"data-precedence":e.precedence,precedence:null})}function Pf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Vd(t,`link`,n),Tt(t),e.head.appendChild(t))}function Ff(e){return`[src="`+Vt(e)+`"]`}function If(e){return`script[async]`+e}function Lf(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Vt(n.href)+`"]`);if(r)return t.instance=r,Tt(r),r;var a=f({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),Tt(r),Vd(r,`style`,a),Rf(r,n.precedence,e),t.instance=r;case`stylesheet`:a=jf(n.href);var o=e.querySelector(Mf(a));if(o)return t.state.loading|=4,t.instance=o,Tt(o),o;r=Nf(n),(a=hf.get(a))&&zf(r,a),o=(e.ownerDocument||e).createElement(`link`),Tt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Vd(o,`link`,r),t.state.loading|=4,Rf(o,n.precedence,e),t.instance=o;case`script`:return o=Ff(n.src),(a=e.querySelector(If(o)))?(t.instance=a,Tt(a),a):(r=n,(a=hf.get(o))&&(r=f({},n),Bf(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),Tt(a),Vd(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Rf(r,n.precedence,e));return t.instance}function Rf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Wf(e,t,n){if(n===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 Gf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function yee(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=jf(r.href),a=t.querySelector(Mf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=qf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,Tt(a);return}a=t.ownerDocument||t,r=Nf(r),(i=hf.get(i))&&zf(r,i),a=a.createElement(`link`),Tt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Vd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=qf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function bee(e,t){return e.stylesheets&&e.count===0&&Yf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function qf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Yf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Jf=null;function Yf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Jf=new Map,t.forEach(Xf,e),Jf=null,qf.call(e))}function Xf(e,t){if(!(t.state.loading&4)){var n=Jf.get(e);if(n)var r=n.get(null);else{n=new Map,Jf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=v()})),b=`modulepreload`,x=function(e){return`/`+e},S={},C=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}r=o(t.map(t=>{if(t=x(t,n),t in S)return;S[t]=!0;let r=t.endsWith(`.css`),i=r?`[rel="stylesheet"]`:``;if(n)for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;let o=document.createElement(`link`);if(o.rel=r?`stylesheet`:b,r||(o.as=`script`),o.crossOrigin=``,o.href=t,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),r)return new Promise((e,n)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},w=u(p(),1),T=`popstate`;function E(e){return typeof e==`object`&&!!e&&`pathname`in e&&`search`in e&&`hash`in e&&`state`in e&&`key`in e}function D(e={}){function t(e,t){let n=t.state?.masked,{pathname:r,search:i,hash:a}=n||e.location;return te(``,{pathname:r,search:i,hash:a},t.state&&t.state.usr||null,t.state&&t.state.key||`default`,n?{pathname:e.location.pathname,search:e.location.search,hash:e.location.hash}:void 0)}function n(e,t){return typeof t==`string`?t:j(t)}return re(t,n,null,e)}function O(e,t){if(e===!1||e==null)throw Error(t)}function k(e,t){if(!e){typeof console<`u`&&console.warn(t);try{throw Error(t)}catch{}}}function A(){return Math.random().toString(36).substring(2,10)}function ee(e,t){return{usr:e.state,key:e.key,idx:t,masked:e.unstable_mask?{pathname:e.pathname,search:e.search,hash:e.hash}:void 0}}function te(e,t,n=null,r,i){return{pathname:typeof e==`string`?e:e.pathname,search:``,hash:``,...typeof t==`string`?ne(t):t,state:n,key:t&&t.key||r||A(),unstable_mask:i}}function j({pathname:e=`/`,search:t=``,hash:n=``}){return t&&t!==`?`&&(e+=t.charAt(0)===`?`?t:`?`+t),n&&n!==`#`&&(e+=n.charAt(0)===`#`?n:`#`+n),e}function ne(e){let t={};if(e){let n=e.indexOf(`#`);n>=0&&(t.hash=e.substring(n),e=e.substring(0,n));let r=e.indexOf(`?`);r>=0&&(t.search=e.substring(r),e=e.substring(0,r)),e&&(t.pathname=e)}return t}function re(e,t,n,r={}){let{window:i=document.defaultView,v5Compat:a=!1}=r,o=i.history,s=`POP`,c=null,l=u();l??(l=0,o.replaceState({...o.state,idx:l},``));function u(){return(o.state||{idx:null}).idx}function d(){s=`POP`;let e=u(),t=e==null?null:e-l;l=e,c&&c({action:s,location:h.location,delta:t})}function f(e,t){s=`PUSH`;let r=E(e)?e:te(h.location,e,t);n&&n(r,e),l=u()+1;let d=ee(r,l),f=h.createHref(r.unstable_mask||r);try{o.pushState(d,``,f)}catch(e){if(e instanceof DOMException&&e.name===`DataCloneError`)throw e;i.location.assign(f)}a&&c&&c({action:s,location:h.location,delta:1})}function p(e,t){s=`REPLACE`;let r=E(e)?e:te(h.location,e,t);n&&n(r,e),l=u();let i=ee(r,l),d=h.createHref(r.unstable_mask||r);o.replaceState(i,``,d),a&&c&&c({action:s,location:h.location,delta:0})}function m(e){return M(e)}let h={get action(){return s},get location(){return e(i,o)},listen(e){if(c)throw Error(`A history only accepts one active listener`);return i.addEventListener(T,d),c=e,()=>{i.removeEventListener(T,d),c=null}},createHref(e){return t(i,e)},createURL:m,encodeLocation(e){let t=m(e);return{pathname:t.pathname,search:t.search,hash:t.hash}},push:f,replace:p,go(e){return o.go(e)}};return h}function M(e,t=!1){let n=`http://localhost`;typeof window<`u`&&(n=window.location.origin===`null`?window.location.href:window.location.origin),O(n,`No window.location.(origin|href) available to create URL`);let r=typeof e==`string`?e:j(e);return r=r.replace(/ $/,`%20`),!t&&r.startsWith(`//`)&&(r=n+r),new URL(r,n)}function ie(e,t,n=`/`){return ae(e,t,n,!1)}function ae(e,t,n,r){let i=Ce((typeof t==`string`?ne(t):t).pathname||`/`,n);if(i==null)return null;let a=se(e);le(a);let o=null;for(let e=0;o==null&&e{let c={relativePath:s===void 0?e.path||``:s,caseSensitive:e.caseSensitive===!0,childrenIndex:a,route:e};if(c.relativePath.startsWith(`/`)){if(!c.relativePath.startsWith(r)&&o)return;O(c.relativePath.startsWith(r),`Absolute route path "${c.relativePath}" nested under path "${r}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),c.relativePath=c.relativePath.slice(r.length)}let l=je([r,c.relativePath]),u=n.concat(c);e.children&&e.children.length>0&&(O(e.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${l}".`),se(e.children,t,u,l,o)),!(e.path==null&&!e.index)&&t.push({path:l,score:_e(l,e.index),routesMeta:u})};return e.forEach((e,t)=>{if(e.path===``||!e.path?.includes(`?`))a(e,t);else for(let n of ce(e.path))a(e,t,!0,n)}),t}function ce(e){let t=e.split(`/`);if(t.length===0)return[];let[n,...r]=t,i=n.endsWith(`?`),a=n.replace(/\?$/,``);if(r.length===0)return i?[a,``]:[a];let o=ce(r.join(`/`)),s=[];return s.push(...o.map(e=>e===``?a:[a,e].join(`/`))),i&&s.push(...o),s.map(t=>e.startsWith(`/`)&&t===``?`/`:t)}function le(e){e.sort((e,t)=>e.score===t.score?ve(e.routesMeta.map(e=>e.childrenIndex),t.routesMeta.map(e=>e.childrenIndex)):t.score-e.score)}var ue=/^:[\w-]+$/,de=3,fe=2,pe=1,me=10,he=-2,ge=e=>e===`*`;function _e(e,t){let n=e.split(`/`),r=n.length;return n.some(ge)&&(r+=he),t&&(r+=fe),n.filter(e=>!ge(e)).reduce((e,t)=>e+(ue.test(t)?de:t===``?pe:me),r)}function ve(e,t){return e.length===t.length&&e.slice(0,-1).every((e,n)=>e===t[n])?e[e.length-1]-t[t.length-1]:0}function ye(e,t,n=!1){let{routesMeta:r}=e,i={},a=`/`,o=[];for(let e=0;e{if(t===`*`){let e=s[r]||``;o=a.slice(0,a.length-e.length).replace(/(.)\/+$/,`$1`)}let i=s[r];return n&&!i?e[t]=void 0:e[t]=(i||``).replace(/%2F/g,`/`),e},{}),pathname:a,pathnameBase:o,pattern:e}}function xe(e,t=!1,n=!0){k(e===`*`||!e.endsWith(`*`)||e.endsWith(`/*`),`Route path "${e}" will be treated as if it were "${e.replace(/\*$/,`/*`)}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${e.replace(/\*$/,`/*`)}".`);let r=[],i=`^`+e.replace(/\/*\*?$/,``).replace(/^\/*/,`/`).replace(/[\\.*+^${}|()[\]]/g,`\\$&`).replace(/\/:([\w-]+)(\?)?/g,(e,t,n,i,a)=>{if(r.push({paramName:t,isOptional:n!=null}),n){let t=a.charAt(i+e.length);return t&&t!==`/`?`/([^\\/]*)`:`(?:/([^\\/]*))?`}return`/([^\\/]+)`}).replace(/\/([\w-]+)\?(\/|$)/g,`(/$1)?$2`);return e.endsWith(`*`)?(r.push({paramName:`*`}),i+=e===`*`||e===`/*`?`(.*)$`:`(?:\\/(.+)|\\/*)$`):n?i+=`\\/*$`:e!==``&&e!==`/`&&(i+=`(?:(?=\\/|$))`),[new RegExp(i,t?void 0:`i`),r]}function Se(e){try{return e.split(`/`).map(e=>decodeURIComponent(e).replace(/\//g,`%2F`)).join(`/`)}catch(t){return k(!1,`The URL path "${e}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${t}).`),e}}function Ce(e,t){if(t===`/`)return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith(`/`)?t.length-1:t.length,r=e.charAt(n);return r&&r!==`/`?null:e.slice(n)||`/`}var we=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function Te(e,t=`/`){let{pathname:n,search:r=``,hash:i=``}=typeof e==`string`?ne(e):e,a;return n?(n=n.replace(/\/\/+/g,`/`),a=n.startsWith(`/`)?Ee(n.substring(1),`/`):Ee(n,t)):a=t,{pathname:a,search:Ne(r),hash:Pe(i)}}function Ee(e,t){let n=t.replace(/\/+$/,``).split(`/`);return e.split(`/`).forEach(e=>{e===`..`?n.length>1&&n.pop():e!==`.`&&n.push(e)}),n.length>1?n.join(`/`):`/`}function De(e,t,n,r){return`Cannot include a '${e}' character in a manually specified \`to.${t}\` field [${JSON.stringify(r)}]. Please separate it out to the \`to.${n}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function Oe(e){return e.filter((e,t)=>t===0||e.route.path&&e.route.path.length>0)}function ke(e){let t=Oe(e);return t.map((e,n)=>n===t.length-1?e.pathname:e.pathnameBase)}function Ae(e,t,n,r=!1){let i;typeof e==`string`?i=ne(e):(i={...e},O(!i.pathname||!i.pathname.includes(`?`),De(`?`,`pathname`,`search`,i)),O(!i.pathname||!i.pathname.includes(`#`),De(`#`,`pathname`,`hash`,i)),O(!i.search||!i.search.includes(`#`),De(`#`,`search`,`hash`,i)));let a=e===``||i.pathname===``,o=a?`/`:i.pathname,s;if(o==null)s=n;else{let e=t.length-1;if(!r&&o.startsWith(`..`)){let t=o.split(`/`);for(;t[0]===`..`;)t.shift(),--e;i.pathname=t.join(`/`)}s=e>=0?t[e]:`/`}let c=Te(i,s),l=o&&o!==`/`&&o.endsWith(`/`),u=(a||o===`.`)&&n.endsWith(`/`);return!c.pathname.endsWith(`/`)&&(l||u)&&(c.pathname+=`/`),c}var je=e=>e.join(`/`).replace(/\/\/+/g,`/`),Me=e=>e.replace(/\/+$/,``).replace(/^\/*/,`/`),Ne=e=>!e||e===`?`?``:e.startsWith(`?`)?e:`?`+e,Pe=e=>!e||e===`#`?``:e.startsWith(`#`)?e:`#`+e,Fe=class{constructor(e,t,n,r=!1){this.status=e,this.statusText=t||``,this.internal=r,n instanceof Error?(this.data=n.toString(),this.error=n):this.data=n}};function Ie(e){return e!=null&&typeof e.status==`number`&&typeof e.statusText==`string`&&typeof e.internal==`boolean`&&`data`in e}function Le(e){return e.map(e=>e.route.path).filter(Boolean).join(`/`).replace(/\/\/*/g,`/`)||`/`}var Re=typeof window<`u`&&window.document!==void 0&&window.document.createElement!==void 0;function ze(e,t){let n=e;if(typeof n!=`string`||!we.test(n))return{absoluteURL:void 0,isExternal:!1,to:n};let r=n,i=!1;if(Re)try{let e=new URL(window.location.href),r=n.startsWith(`//`)?new URL(e.protocol+n):new URL(n),a=Ce(r.pathname,t);r.origin===e.origin&&a!=null?n=a+r.search+r.hash:i=!0}catch{k(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:r,isExternal:i,to:n}}Object.getOwnPropertyNames(Object.prototype).sort().join(`\0`);var Be=[`POST`,`PUT`,`PATCH`,`DELETE`];new Set(Be);var Ve=[`GET`,...Be];new Set(Ve);var He=w.createContext(null);He.displayName=`DataRouter`;var Ue=w.createContext(null);Ue.displayName=`DataRouterState`;var We=w.createContext(!1),Ge=w.createContext({isTransitioning:!1});Ge.displayName=`ViewTransition`;var Ke=w.createContext(new Map);Ke.displayName=`Fetchers`;var qe=w.createContext(null);qe.displayName=`Await`;var Je=w.createContext(null);Je.displayName=`Navigation`;var Ye=w.createContext(null);Ye.displayName=`Location`;var Xe=w.createContext({outlet:null,matches:[],isDataRoute:!1});Xe.displayName=`Route`;var Ze=w.createContext(null);Ze.displayName=`RouteError`;var Qe=`REACT_ROUTER_ERROR`,$e=`REDIRECT`,et=`ROUTE_ERROR_RESPONSE`;function tt(e){if(e.startsWith(`${Qe}:${$e}:{`))try{let t=JSON.parse(e.slice(28));if(typeof t==`object`&&t&&typeof t.status==`number`&&typeof t.statusText==`string`&&typeof t.location==`string`&&typeof t.reloadDocument==`boolean`&&typeof t.replace==`boolean`)return t}catch{}}function nt(e){if(e.startsWith(`${Qe}:${et}:{`))try{let t=JSON.parse(e.slice(40));if(typeof t==`object`&&t&&typeof t.status==`number`&&typeof t.statusText==`string`)return new Fe(t.status,t.statusText,t.data)}catch{}}function rt(e,{relative:t}={}){O(it(),`useHref() may be used only in the context of a component.`);let{basename:n,navigator:r}=w.useContext(Je),{hash:i,pathname:a,search:o}=dt(e,{relative:t}),s=a;return n!==`/`&&(s=a===`/`?n:je([n,a])),r.createHref({pathname:s,search:o,hash:i})}function it(){return w.useContext(Ye)!=null}function at(){return O(it(),`useLocation() may be used only in the context of a component.`),w.useContext(Ye).location}var ot=`You should call navigate() in a React.useEffect(), not when your component is first rendered.`;function st(e){w.useContext(Je).static||w.useLayoutEffect(e)}function ct(){let{isDataRoute:e}=w.useContext(Xe);return e?eee():lt()}function lt(){O(it(),`useNavigate() may be used only in the context of a component.`);let e=w.useContext(He),{basename:t,navigator:n}=w.useContext(Je),{matches:r}=w.useContext(Xe),{pathname:i}=at(),a=JSON.stringify(ke(r)),o=w.useRef(!1);return st(()=>{o.current=!0}),w.useCallback((r,s={})=>{if(k(o.current,ot),!o.current)return;if(typeof r==`number`){n.go(r);return}let c=Ae(r,JSON.parse(a),i,s.relative===`path`);e==null&&t!==`/`&&(c.pathname=c.pathname===`/`?t:je([t,c.pathname])),(s.replace?n.replace:n.push)(c,s.state,s)},[t,n,a,i,e])}w.createContext(null);function ut(){let{matches:e}=w.useContext(Xe),t=e[e.length-1];return t?t.params:{}}function dt(e,{relative:t}={}){let{matches:n}=w.useContext(Xe),{pathname:r}=at(),i=JSON.stringify(ke(n));return w.useMemo(()=>Ae(e,JSON.parse(i),r,t===`path`),[e,i,r,t])}function ft(e,t){return pt(e,t)}function pt(e,t,n){O(it(),`useRoutes() may be used only in the context of a component.`);let{navigator:r}=w.useContext(Je),{matches:i}=w.useContext(Xe),a=i[i.length-1],o=a?a.params:{},s=a?a.pathname:`/`,c=a?a.pathnameBase:`/`,l=a&&a.route;{let e=l&&l.path||``;jt(s,!l||e.endsWith(`*`)||e.endsWith(`*?`),`You rendered descendant (or called \`useRoutes()\`) at "${s}" (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 u=at(),d;if(t){let e=typeof t==`string`?ne(t):t;O(c===`/`||e.pathname?.startsWith(c),`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 "${c}" but pathname "${e.pathname}" was given in the \`location\` prop.`),d=e}else d=u;let f=d.pathname||`/`,p=f;if(c!==`/`){let e=c.replace(/^\//,``).split(`/`);p=`/`+f.replace(/^\//,``).split(`/`).slice(e.length).join(`/`)}let m=ie(e,{pathname:p});k(l||m!=null,`No routes matched location "${d.pathname}${d.search}${d.hash}" `),k(m==null||m[m.length-1].route.element!==void 0||m[m.length-1].route.Component!==void 0||m[m.length-1].route.lazy!==void 0,`Matched leaf route at location "${d.pathname}${d.search}${d.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 h=bt(m&&m.map(e=>Object.assign({},e,{params:Object.assign({},o,e.params),pathname:je([c,r.encodeLocation?r.encodeLocation(e.pathname.replace(/\?/g,`%3F`).replace(/#/g,`%23`)).pathname:e.pathname]),pathnameBase:e.pathnameBase===`/`?c:je([c,r.encodeLocation?r.encodeLocation(e.pathnameBase.replace(/\?/g,`%3F`).replace(/#/g,`%23`)).pathname:e.pathnameBase])})),i,n);return t&&h?w.createElement(Ye.Provider,{value:{location:{pathname:`/`,search:``,hash:``,state:null,key:`default`,unstable_mask:void 0,...d},navigationType:`POP`}},h):h}function mt(){let e=kt(),t=Ie(e)?`${e.status} ${e.statusText}`:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,r=`rgba(200,200,200, 0.5)`,i={padding:`0.5rem`,backgroundColor:r},a={padding:`2px 4px`,backgroundColor:r},o=null;return console.error(`Error handled by React Router default ErrorBoundary:`,e),o=w.createElement(w.Fragment,null,w.createElement(`p`,null,`💿 Hey developer 👋`),w.createElement(`p`,null,`You can provide a way better UX than this when your app throws errors by providing your own `,w.createElement(`code`,{style:a},`ErrorBoundary`),` or`,` `,w.createElement(`code`,{style:a},`errorElement`),` prop on your route.`)),w.createElement(w.Fragment,null,w.createElement(`h2`,null,`Unexpected Application Error!`),w.createElement(`h3`,{style:{fontStyle:`italic`}},t),n?w.createElement(`pre`,{style:i},n):null,o)}var ht=w.createElement(mt,null),gt=class extends w.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||t.revalidation!==`idle`&&e.revalidation===`idle`?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error===void 0?t.error:e.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){this.props.onError?this.props.onError(e,t):console.error(`React Router caught the following error during render`,e)}render(){let e=this.state.error;if(this.context&&typeof e==`object`&&e&&`digest`in e&&typeof e.digest==`string`){let t=nt(e.digest);t&&(e=t)}let t=e===void 0?this.props.children:w.createElement(Xe.Provider,{value:this.props.routeContext},w.createElement(Ze.Provider,{value:e,children:this.props.component}));return this.context?w.createElement(vt,{error:e},t):t}};gt.contextType=We;var _t=new WeakMap;function vt({children:e,error:t}){let{basename:n}=w.useContext(Je);if(typeof t==`object`&&t&&`digest`in t&&typeof t.digest==`string`){let e=tt(t.digest);if(e){let r=_t.get(t);if(r)throw r;let i=ze(e.location,n);if(Re&&!_t.get(t))if(i.isExternal||e.reloadDocument)window.location.href=i.absoluteURL||i.to;else{let n=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(i.to,{replace:e.replace}));throw _t.set(t,n),n}return w.createElement(`meta`,{httpEquiv:`refresh`,content:`0;url=${i.absoluteURL||i.to}`})}}return e}function yt({routeContext:e,match:t,children:n}){let r=w.useContext(He);return r&&r.static&&r.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=t.route.id),w.createElement(Xe.Provider,{value:e},n)}function bt(e,t=[],n){let r=n?.state;if(e==null){if(!r)return null;if(r.errors)e=r.matches;else if(t.length===0&&!r.initialized&&r.matches.length>0)e=r.matches;else return null}let i=e,a=r?.errors;if(a!=null){let e=i.findIndex(e=>e.route.id&&a?.[e.route.id]!==void 0);O(e>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(a).join(`,`)}`),i=i.slice(0,Math.min(i.length,e+1))}let o=!1,s=-1;if(n&&r){o=r.renderFallback;for(let e=0;e=0?i.slice(0,s+1):[i[0]];break}}}}let c=n?.onError,l=r&&c?(e,t)=>{c(e,{location:r.location,params:r.matches?.[0]?.params??{},unstable_pattern:Le(r.matches),errorInfo:t})}:void 0;return i.reduceRight((e,n,c)=>{let u,d=!1,f=null,p=null;r&&(u=a&&n.route.id?a[n.route.id]:void 0,f=n.route.errorElement||ht,o&&(s<0&&c===0?(jt(`route-fallback`,!1,"No `HydrateFallback` element provided to render during initial hydration"),d=!0,p=null):s===c&&(d=!0,p=n.route.hydrateFallbackElement||null)));let m=t.concat(i.slice(0,c+1)),h=()=>{let t;return t=u?f:d?p:n.route.Component?w.createElement(n.route.Component,null):n.route.element?n.route.element:e,w.createElement(yt,{match:n,routeContext:{outlet:e,matches:m,isDataRoute:r!=null},children:t})};return r&&(n.route.ErrorBoundary||n.route.errorElement||c===0)?w.createElement(gt,{location:r.location,revalidation:r.revalidation,component:f,error:u,children:h(),routeContext:{outlet:null,matches:m,isDataRoute:!0},onError:l}):h()},null)}function xt(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function St(e){let t=w.useContext(He);return O(t,xt(e)),t}function Ct(e){let t=w.useContext(Ue);return O(t,xt(e)),t}function wt(e){let t=w.useContext(Xe);return O(t,xt(e)),t}function Tt(e){let t=wt(e),n=t.matches[t.matches.length-1];return O(n.route.id,`${e} can only be used on routes that contain a unique "id"`),n.route.id}function Et(){return Tt(`useRouteId`)}function Dt(){return Ct(`useNavigation`).navigation}function Ot(){let{matches:e,loaderData:t}=Ct(`useMatches`);return w.useMemo(()=>e.map(e=>oe(e,t)),[e,t])}function kt(){let e=w.useContext(Ze),t=Ct(`useRouteError`),n=Tt(`useRouteError`);return e===void 0?t.errors?.[n]:e}function eee(){let{router:e}=St(`useNavigate`),t=Tt(`useNavigate`),n=w.useRef(!1);return st(()=>{n.current=!0}),w.useCallback(async(r,i={})=>{k(n.current,ot),n.current&&(typeof r==`number`?await e.navigate(r):await e.navigate(r,{fromRouteId:t,...i}))},[e,t])}var At={};function jt(e,t,n){!t&&!At[e]&&(At[e]=!0,k(!1,n))}w.useOptimistic,w.memo(tee);function tee({routes:e,future:t,state:n,isStatic:r,onError:i}){return pt(e,void 0,{state:n,isStatic:r,onError:i,future:t})}function Mt(e){O(!1,`A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .`)}function Nt({basename:e=`/`,children:t=null,location:n,navigationType:r=`POP`,navigator:i,static:a=!1,unstable_useTransitions:o}){O(!it(),`You cannot render a inside another . You should never have more than one in your app.`);let s=e.replace(/^\/*/,`/`),c=w.useMemo(()=>({basename:s,navigator:i,static:a,unstable_useTransitions:o,future:{}}),[s,i,a,o]);typeof n==`string`&&(n=ne(n));let{pathname:l=`/`,search:u=``,hash:d=``,state:f=null,key:p=`default`,unstable_mask:m}=n,h=w.useMemo(()=>{let e=Ce(l,s);return e==null?null:{location:{pathname:e,search:u,hash:d,state:f,key:p,unstable_mask:m},navigationType:r}},[s,l,u,d,f,p,r,m]);return k(h!=null,` is not able to match the URL "${l}${u}${d}" because it does not start with the basename, so the won't render anything.`),h==null?null:w.createElement(Je.Provider,{value:c},w.createElement(Ye.Provider,{children:t,value:h}))}function Pt({children:e,location:t}){return ft(Ft(e),t)}function Ft(e,t=[]){let n=[];return w.Children.forEach(e,(e,r)=>{if(!w.isValidElement(e))return;let i=[...t,r];if(e.type===w.Fragment){n.push.apply(n,Ft(e.props.children,i));return}O(e.type===Mt,`[${typeof e.type==`string`?e.type:e.type.name}] is not a component. All component children of must be a or `),O(!e.props.index||!e.props.children,`An index route cannot have child routes.`);let a={id:e.props.id||i.join(`-`),caseSensitive:e.props.caseSensitive,element:e.props.element,Component:e.props.Component,index:e.props.index,path:e.props.path,middleware:e.props.middleware,loader:e.props.loader,action:e.props.action,hydrateFallbackElement:e.props.hydrateFallbackElement,HydrateFallback:e.props.HydrateFallback,errorElement:e.props.errorElement,ErrorBoundary:e.props.ErrorBoundary,hasErrorBoundary:e.props.hasErrorBoundary===!0||e.props.ErrorBoundary!=null||e.props.errorElement!=null,shouldRevalidate:e.props.shouldRevalidate,handle:e.props.handle,lazy:e.props.lazy};e.props.children&&(a.children=Ft(e.props.children,i)),n.push(a)}),n}var It=`get`,Lt=`application/x-www-form-urlencoded`;function Rt(e){return typeof HTMLElement<`u`&&e instanceof HTMLElement}function zt(e){return Rt(e)&&e.tagName.toLowerCase()===`button`}function Bt(e){return Rt(e)&&e.tagName.toLowerCase()===`form`}function nee(e){return Rt(e)&&e.tagName.toLowerCase()===`input`}function Vt(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function Ht(e,t){return e.button===0&&(!t||t===`_self`)&&!Vt(e)}function Ut(e=``){return new URLSearchParams(typeof e==`string`||Array.isArray(e)||e instanceof URLSearchParams?e:Object.keys(e).reduce((t,n)=>{let r=e[n];return t.concat(Array.isArray(r)?r.map(e=>[n,e]):[[n,r]])},[]))}function Wt(e,t){let n=Ut(e);return t&&t.forEach((e,r)=>{n.has(r)||t.getAll(r).forEach(e=>{n.append(r,e)})}),n}var Gt=null;function Kt(){if(Gt===null)try{new FormData(document.createElement(`form`),0),Gt=!1}catch{Gt=!0}return Gt}var qt=new Set([`application/x-www-form-urlencoded`,`multipart/form-data`,`text/plain`]);function Jt(e){return e!=null&&!qt.has(e)?(k(!1,`"${e}" is not a valid \`encType\` for \`\`/\`\` and will default to "${Lt}"`),null):e}function ree(e,t){let n,r,i,a,o;if(Bt(e)){let o=e.getAttribute(`action`);r=o?Ce(o,t):null,n=e.getAttribute(`method`)||It,i=Jt(e.getAttribute(`enctype`))||Lt,a=new FormData(e)}else if(zt(e)||nee(e)&&(e.type===`submit`||e.type===`image`)){let o=e.form;if(o==null)throw Error(`Cannot submit a