From 24320dea4e1711ea62e97c328ed5fc40afd5631e Mon Sep 17 00:00:00 2001 From: Samuel-Hills Date: Tue, 22 Sep 2026 21:07:43 +0200 Subject: [PATCH 1/3] feat: merge local datasets in the browser --- frontend/dist/assets/index-BX9JKcmw.js | 3958 ----------------- frontend/dist/assets/index-C7QO1l1G.js | 3958 +++++++++++++++++ frontend/dist/assets/index-DJuBJMLM.css | 1 - frontend/dist/assets/index-Dv87rxaM.css | 1 + frontend/dist/index.html | 40 +- .../dataset/MergeDatasetsDialog.tsx | 133 + frontend/src/lib/replayApi.test.ts | 21 + frontend/src/lib/replayApi.ts | 20 + frontend/src/pages/EditDataset.tsx | 34 +- lelab/datasets.py | 55 + lelab/server.py | 14 + tests/test_datasets.py | 115 + 12 files changed, 4368 insertions(+), 3982 deletions(-) delete mode 100644 frontend/dist/assets/index-BX9JKcmw.js create mode 100644 frontend/dist/assets/index-C7QO1l1G.js delete mode 100644 frontend/dist/assets/index-DJuBJMLM.css create mode 100644 frontend/dist/assets/index-Dv87rxaM.css create mode 100644 frontend/src/components/dataset/MergeDatasetsDialog.tsx create mode 100644 frontend/src/lib/replayApi.test.ts diff --git a/frontend/dist/assets/index-BX9JKcmw.js b/frontend/dist/assets/index-BX9JKcmw.js deleted file mode 100644 index c1958ac04..000000000 --- a/frontend/dist/assets/index-BX9JKcmw.js +++ /dev/null @@ -1,3958 +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)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(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},c=(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},l=(n,r,a)=>(a=n==null?{}:e(i(n)),c(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));(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 u=o((e=>{var t=Symbol.for(`react.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.provider`),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.iterator;function p(e){return typeof e!=`object`||!e?null:(e=f&&e[f]||e[`@@iterator`],typeof e==`function`?e:null)}var m={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},h=Object.assign,g={};function _(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}_.prototype.isReactComponent={},_.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`setState(...): takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},_.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function v(){}v.prototype=_.prototype;function y(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}var b=y.prototype=new v;b.constructor=y,h(b,_.prototype),b.isPureReactComponent=!0;var x=Array.isArray,S=Object.prototype.hasOwnProperty,C={current:null},w={key:!0,ref:!0,__self:!0,__source:!0};function T(e,n,r){var i,a={},o=null,s=null;if(n!=null)for(i in n.ref!==void 0&&(s=n.ref),n.key!==void 0&&(o=``+n.key),n)S.call(n,i)&&!w.hasOwnProperty(i)&&(a[i]=n[i]);var c=arguments.length-2;if(c===1)a.children=r;else if(1{t.exports=u()})),f=o((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(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=typeof setTimeout==`function`?setTimeout:null,_=typeof clearTimeout==`function`?clearTimeout:null,v=typeof setImmediate<`u`?setImmediate:null;typeof navigator<`u`&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function y(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 b(e){if(h=!1,y(e),!m)if(n(c)!==null)m=!0,M(x);else{var t=n(l);t!==null&&N(b,t.startTime-e)}}function x(t,i){m=!1,h&&(h=!1,_(w),w=-1),p=!0;var a=f;try{for(y(i),d=n(c);d!==null&&(!(d.expirationTime>i)||t&&!D());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=i);i=e.unstable_now(),typeof s==`function`?d.callback=s:d===n(c)&&r(c),y(i)}else r(c);d=n(c)}if(d!==null)var u=!0;else{var g=n(l);g!==null&&N(b,g.startTime-i),u=!1}return u}finally{d=null,f=a,p=!1}}var S=!1,C=null,w=-1,T=5,E=-1;function D(){return!(e.unstable_now()-Ee||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(_(w),w=-1):h=!0,N(b,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,M(x))),r},e.unstable_shouldYield=D,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),p=o(((e,t)=>{t.exports=f()})),m=o((e=>{var t=d(),n=p();function r(e){for(var t=`https://reactjs.org/docs/error-decoder.html?invariant=`+e,n=1;n`u`||window.document===void 0||window.document.createElement===void 0),l=Object.prototype.hasOwnProperty,u=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,f={},m={};function h(e){return l.call(m,e)?!0:l.call(f,e)?!1:u.test(e)?m[e]=!0:(f[e]=!0,!1)}function g(e,t,n,r){if(n!==null&&n.type===0)return!1;switch(typeof t){case`function`:case`symbol`:return!0;case`boolean`:return r?!1:n===null?(e=e.toLowerCase().slice(0,5),e!==`data-`&&e!==`aria-`):!n.acceptsBooleans;default:return!1}}function _(e,t,n,r){if(t==null||g(e,t,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function v(e,t,n,r,i,a,o){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=r,this.attributeNamespace=i,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=a,this.removeEmptyString=o}var y={};`children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style`.split(` `).forEach(function(e){y[e]=new v(e,0,!1,e,null,!1,!1)}),[[`acceptCharset`,`accept-charset`],[`className`,`class`],[`htmlFor`,`for`],[`httpEquiv`,`http-equiv`]].forEach(function(e){var t=e[0];y[t]=new v(t,1,!1,e[1],null,!1,!1)}),[`contentEditable`,`draggable`,`spellCheck`,`value`].forEach(function(e){y[e]=new v(e,2,!1,e.toLowerCase(),null,!1,!1)}),[`autoReverse`,`externalResourcesRequired`,`focusable`,`preserveAlpha`].forEach(function(e){y[e]=new v(e,2,!1,e,null,!1,!1)}),`allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope`.split(` `).forEach(function(e){y[e]=new v(e,3,!1,e.toLowerCase(),null,!1,!1)}),[`checked`,`multiple`,`muted`,`selected`].forEach(function(e){y[e]=new v(e,3,!0,e,null,!1,!1)}),[`capture`,`download`].forEach(function(e){y[e]=new v(e,4,!1,e,null,!1,!1)}),[`cols`,`rows`,`size`,`span`].forEach(function(e){y[e]=new v(e,6,!1,e,null,!1,!1)}),[`rowSpan`,`start`].forEach(function(e){y[e]=new v(e,5,!1,e.toLowerCase(),null,!1,!1)});var b=/[\-:]([a-z])/g;function x(e){return e[1].toUpperCase()}`accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height`.split(` `).forEach(function(e){var t=e.replace(b,x);y[t]=new v(t,1,!1,e,null,!1,!1)}),`xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type`.split(` `).forEach(function(e){var t=e.replace(b,x);y[t]=new v(t,1,!1,e,`http://www.w3.org/1999/xlink`,!1,!1)}),[`xml:base`,`xml:lang`,`xml:space`].forEach(function(e){var t=e.replace(b,x);y[t]=new v(t,1,!1,e,`http://www.w3.org/XML/1998/namespace`,!1,!1)}),[`tabIndex`,`crossOrigin`].forEach(function(e){y[e]=new v(e,1,!1,e.toLowerCase(),null,!1,!1)}),y.xlinkHref=new v(`xlinkHref`,1,!1,`xlink:href`,`http://www.w3.org/1999/xlink`,!0,!1),[`src`,`href`,`action`,`formAction`].forEach(function(e){y[e]=new v(e,1,!1,e.toLowerCase(),null,!0,!0)});function S(e,t,n,r){var i=y.hasOwnProperty(t)?y[t]:null;(i===null?r||!(2s||i[o]!==a[s]){var c=` -`+i[o].replace(` at new `,` at `);return e.displayName&&c.includes(``)&&(c=c.replace(``,e.displayName)),c}while(1<=o&&0<=s);break}}}finally{oe=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:``)?ae(e):``}function ce(e){switch(e.tag){case 5:return ae(e.type);case 16:return ae(`Lazy`);case 13:return ae(`Suspense`);case 19:return ae(`SuspenseList`);case 0:case 2:case 15:return e=se(e.type,!1),e;case 11:return e=se(e.type.render,!1),e;case 1:return e=se(e.type,!0),e;default:return``}}function le(e){if(e==null)return null;if(typeof e==`function`)return e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case E:return`Fragment`;case T:return`Portal`;case O:return`Profiler`;case D:return`StrictMode`;case M:return`Suspense`;case N:return`SuspenseList`}if(typeof e==`object`)switch(e.$$typeof){case A:return(e.displayName||`Context`)+`.Consumer`;case k:return(e._context.displayName||`Context`)+`.Provider`;case j:var t=e.render;return e=e.displayName,e||=(e=t.displayName||t.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case P:return t=e.displayName||null,t===null?le(e.type)||`Memo`:t;case F:t=e._payload,e=e._init;try{return le(e(t))}catch{}}return null}function ue(e){var t=e.type;switch(e.tag){case 24:return`Cache`;case 9:return(t.displayName||`Context`)+`.Consumer`;case 10:return(t._context.displayName||`Context`)+`.Provider`;case 18:return`DehydratedFragment`;case 11:return e=t.render,e=e.displayName||e.name||``,t.displayName||(e===``?`ForwardRef`:`ForwardRef(`+e+`)`);case 7:return`Fragment`;case 5:return t;case 4:return`Portal`;case 3:return`Root`;case 6:return`Text`;case 16:return le(t);case 8:return t===D?`StrictMode`:`Mode`;case 22:return`Offscreen`;case 12:return`Profiler`;case 21:return`Scope`;case 13:return`Suspense`;case 19:return`SuspenseList`;case 25:return`TracingMarker`;case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t==`function`)return t.displayName||t.name||null;if(typeof t==`string`)return t}return null}function de(e){switch(typeof e){case`boolean`:case`number`:case`string`:case`undefined`:return e;case`object`:return e;default:return``}}function fe(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()===`input`&&(t===`checkbox`||t===`radio`)}function I(e){var t=fe(e)?`checked`:`value`,n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=``+e[t];if(!e.hasOwnProperty(t)&&n!==void 0&&typeof n.get==`function`&&typeof n.set==`function`){var i=n.get,a=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return i.call(this)},set:function(e){r=``+e,a.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=``+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function pe(e){e._valueTracker||=I(e)}function me(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r=``;return e&&(r=fe(e)?e.checked?`true`:`false`:e.value),e=r,e===n?!1:(t.setValue(e),!0)}function he(e){if(e||=typeof document<`u`?document:void 0,e===void 0)return null;try{return e.activeElement||e.body}catch{return e.body}}function L(e,t){var n=t.checked;return re({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??e._wrapperState.initialChecked})}function ge(e,t){var n=t.defaultValue==null?``:t.defaultValue,r=t.checked==null?t.defaultChecked:t.checked;n=de(t.value==null?n:t.value),e._wrapperState={initialChecked:r,initialValue:n,controlled:t.type===`checkbox`||t.type===`radio`?t.checked!=null:t.value!=null}}function R(e,t){t=t.checked,t!=null&&S(e,`checked`,t,!1)}function _e(e,t){R(e,t);var n=de(t.value),r=t.type;if(n!=null)r===`number`?(n===0&&e.value===``||e.value!=n)&&(e.value=``+n):e.value!==``+n&&(e.value=``+n);else if(r===`submit`||r===`reset`){e.removeAttribute(`value`);return}t.hasOwnProperty(`value`)?ye(e,t.type,n):t.hasOwnProperty(`defaultValue`)&&ye(e,t.type,de(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function ve(e,t,n){if(t.hasOwnProperty(`value`)||t.hasOwnProperty(`defaultValue`)){var r=t.type;if(!(r!==`submit`&&r!==`reset`||t.value!==void 0&&t.value!==null))return;t=``+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}n=e.name,n!==``&&(e.name=``),e.defaultChecked=!!e._wrapperState.initialChecked,n!==``&&(e.name=n)}function ye(e,t,n){(t!==`number`||he(e.ownerDocument)!==e)&&(n==null?e.defaultValue=``+e._wrapperState.initialValue:e.defaultValue!==``+n&&(e.defaultValue=``+n))}var be=Array.isArray;function xe(e,t,n,r){if(e=e.options,t){t={};for(var i=0;i`+t.valueOf().toString()+``,t=Oe.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function Ae(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&n.nodeType===3){n.nodeValue=t;return}}e.textContent=t}var je={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Me=[`Webkit`,`ms`,`Moz`,`O`];Object.keys(je).forEach(function(e){Me.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),je[t]=je[e]})});function Ne(e,t,n){return t==null||typeof t==`boolean`||t===``?``:n||typeof t!=`number`||t===0||je.hasOwnProperty(e)&&je[e]?(``+t).trim():t+`px`}function Pe(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=n.indexOf(`--`)===0,i=Ne(n,t[n],r);n===`float`&&(n=`cssFloat`),r?e.setProperty(n,i):e[n]=i}}var Fe=re({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Ie(e,t){if(t){if(Fe[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(r(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(r(60));if(typeof t.dangerouslySetInnerHTML!=`object`||!(`__html`in t.dangerouslySetInnerHTML))throw Error(r(61))}if(t.style!=null&&typeof t.style!=`object`)throw Error(r(62))}}function Le(e,t){if(e.indexOf(`-`)===-1)return typeof t.is==`string`;switch(e){case`annotation-xml`:case`color-profile`:case`font-face`:case`font-face-src`:case`font-face-uri`:case`font-face-format`:case`font-face-name`:case`missing-glyph`:return!1;default:return!0}}var Re=null;function ze(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var Be=null,Ve=null,He=null;function Ue(e){if(e=Hi(e)){if(typeof Be!=`function`)throw Error(r(280));var t=e.stateNode;t&&(t=Wi(t),Be(e.stateNode,e.type,t))}}function We(e){Ve?He?He.push(e):He=[e]:Ve=e}function Ge(){if(Ve){var e=Ve,t=He;if(He=Ve=null,Ue(e),t)for(e=0;e>>=0,e===0?32:31-(Ot(e)/kt|0)|0}var jt=64,Mt=4194304;function Nt(e){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: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 e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Pt(e,t){var n=e.pendingLanes;if(n===0)return 0;var r=0,i=e.suspendedLanes,a=e.pingedLanes,o=n&268435455;if(o!==0){var s=o&~i;s===0?(a&=o,a!==0&&(r=Nt(a))):r=Nt(s)}else o=n&~i,o===0?a!==0&&(r=Nt(a)):r=Nt(o);if(r===0)return 0;if(t!==0&&t!==r&&(t&i)===0&&(i=r&-r,a=t&-t,i>=a||i===16&&a&4194240))return t;if(r&4&&(r|=n&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=r;0n;n++)t.push(e);return t}function Bt(e,t,n){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-Dt(t),e[t]=n}function z(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0=nr),ar=` `,or=!1;function sr(e,t){switch(e){case`keyup`:return er.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function cr(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var lr=!1;function ur(e,t){switch(e){case`compositionend`:return cr(t);case`keypress`:return t.which===32?(or=!0,ar):null;case`textInput`:return e=t.data,e===ar&&or?null:e;default:return null}}function dr(e,t){if(lr)return e===`compositionend`||!tr&&sr(e,t)?(e=Tn(),wn=Cn=Sn=null,lr=!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=Nr(n)}}function Fr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Fr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Ir(){for(var e=window,t=he();t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=he(e.document)}return t}function Lr(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`)}function Rr(e){var t=Ir(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&Fr(n.ownerDocument.documentElement,n)){if(r!==null&&Lr(n)){if(t=r.start,e=r.end,e===void 0&&(e=t),`selectionStart`in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if(e=(t=n.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var i=n.textContent.length,a=Math.min(r.start,i);r=r.end===void 0?a:Math.min(r.end,i),!e.extend&&a>r&&(i=r,r=a,a=i),i=Pr(n,a);var o=Pr(n,r);i&&o&&(e.rangeCount!==1||e.anchorNode!==i.node||e.anchorOffset!==i.offset||e.focusNode!==o.node||e.focusOffset!==o.offset)&&(t=t.createRange(),t.setStart(i.node,i.offset),e.removeAllRanges(),a>r?(e.addRange(t),e.extend(o.node,o.offset)):(t.setEnd(o.node,o.offset),e.addRange(t)))}}for(t=[],e=n;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof n.focus==`function`&&n.focus(),n=0;n=document.documentMode,Br=null,Vr=null,Hr=null,Ur=!1;function Wr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Ur||Br==null||Br!==he(r)||(r=Br,`selectionStart`in r&&Lr(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}),Hr&&Mr(Hr,r)||(Hr=r,r=hi(Vr,`onSelect`),0Ki||(e.current=Gi[Ki],Gi[Ki]=null,Ki--)}function Yi(e,t){Ki++,Gi[Ki]=e.current,e.current=t}var Xi={},Zi=qi(Xi),Qi=qi(!1),$i=Xi;function ea(e,t){var n=e.type.contextTypes;if(!n)return Xi;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var i={},a;for(a in n)i[a]=t[a];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=i),i}function V(e){return e=e.childContextTypes,e!=null}function ta(){Ji(Qi),Ji(Zi)}function na(e,t,n){if(Zi.current!==Xi)throw Error(r(168));Yi(Zi,t),Yi(Qi,n)}function ra(e,t,n){var i=e.stateNode;if(t=t.childContextTypes,typeof i.getChildContext!=`function`)return n;for(var a in i=i.getChildContext(),i)if(!(a in t))throw Error(r(108,ue(e)||`Unknown`,a));return re({},n,i)}function ia(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Xi,$i=Zi.current,Yi(Zi,e),Yi(Qi,Qi.current),!0}function aa(e,t,n){var i=e.stateNode;if(!i)throw Error(r(169));n?(e=ra(e,t,$i),i.__reactInternalMemoizedMergedChildContext=e,Ji(Qi),Ji(Zi),Yi(Zi,e)):Ji(Qi),Yi(Qi,n)}var oa=null,sa=!1,ca=!1;function la(e){oa===null?oa=[e]:oa.push(e)}function ua(e){sa=!0,la(e)}function da(){if(!ca&&oa!==null){ca=!0;var e=0,t=Ht;try{var n=oa;for(Ht=1;e>=o,i-=o,ya=1<<32-Dt(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(r,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(r,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(r,d),Ea&&ba(r,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),Ea&&ba(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 Ea&&ba(a,g),u}for(h=i(a,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)}),Ea&&ba(a,g),u}function _(e,r,i,o){if(typeof i==`object`&&i&&i.type===E&&i.key===null&&(i=i.props.children),typeof i==`object`&&i){switch(i.$$typeof){case w:a:{for(var c=i.key,l=r;l!==null;){if(l.key===c){if(c=i.type,c===E){if(l.tag===7){n(e,l.sibling),r=a(l,i.props.children),r.return=e,e=r;break a}}else if(l.elementType===c||typeof c==`object`&&c&&c.$$typeof===F&&Ba(c)===l.type){n(e,l.sibling),r=a(l,i.props),r.ref=Ra(e,l,i),r.return=e,e=r;break a}n(e,l);break}else t(e,l);l=l.sibling}i.type===E?(r=ru(i.props.children,e.mode,o,i.key),r.return=e,e=r):(o=nu(i.type,i.key,i.props,null,e.mode,o),o.ref=Ra(e,r,i),o.return=e,e=o)}return s(e);case T:a:{for(l=i.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===i.containerInfo&&r.stateNode.implementation===i.implementation){n(e,r.sibling),r=a(r,i.children||[]),r.return=e,e=r;break a}else{n(e,r);break}else t(e,r);r=r.sibling}r=ou(i,e.mode,o),r.return=e,e=r}return s(e);case F:return l=i._init,_(e,r,l(i._payload),o)}if(be(i))return h(e,r,i,o);if(ne(i))return g(e,r,i,o);za(e,i)}return typeof i==`string`&&i!==``||typeof i==`number`?(i=``+i,r!==null&&r.tag===6?(n(e,r.sibling),r=a(r,i),r.return=e,e=r):(n(e,r),r=au(i,e.mode,o),r.return=e,e=r),s(e)):n(e,r)}return _}var Ha=Va(!0),Ua=Va(!1),Wa=qi(null),Ga=null,Ka=null,qa=null;function Ja(){qa=Ka=Ga=null}function Ya(e){var t=Wa.current;Ji(Wa),e._currentValue=t}function Xa(e,t,n){for(;e!==null;){var r=e.alternate;if((e.childLanes&t)===t?r!==null&&(r.childLanes&t)!==t&&(r.childLanes|=t):(e.childLanes|=t,r!==null&&(r.childLanes|=t)),e===n)break;e=e.return}}function Za(e,t){Ga=e,qa=Ka=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&t)!==0&&(Bs=!0),e.firstContext=null)}function Qa(e){var t=e._currentValue;if(qa!==e)if(e={context:e,memoizedValue:t,next:null},Ka===null){if(Ga===null)throw Error(r(308));Ka=e,Ga.dependencies={lanes:0,firstContext:e}}else Ka=Ka.next=e;return t}var $a=null;function eo(e){$a===null?$a=[e]:$a.push(e)}function to(e,t,n,r){var i=t.interleaved;return i===null?(n.next=n,eo(t)):(n.next=i.next,i.next=n),t.interleaved=n,no(e,r)}function no(e,t){e.lanes|=t;var n=e.alternate;for(n!==null&&(n.lanes|=t),n=e,e=e.return;e!==null;)e.childLanes|=t,n=e.alternate,n!==null&&(n.childLanes|=t),n=e,e=e.return;return n.tag===3?n.stateNode:null}var ro=!1;function io(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function ao(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function oo(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function so(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,Jc&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,no(e,n)}return i=r.interleaved,i===null?(t.next=t,eo(r)):(t.next=i.next,i.next=t),r.interleaved=t,no(e,n)}function co(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194240)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Vt(e,n)}}function lo(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={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,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,effects:r.effects},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function uo(e,t,n,r){var i=e.updateQueue;ro=!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 f=s.lane,p=s.eventTime;if((r&f)===f){u!==null&&(u=u.next={eventTime:p,lane:0,tag:s.tag,payload:s.payload,callback:s.callback,next:null});a:{var m=e,h=s;switch(f=t,p=n,h.tag){case 1:if(m=h.payload,typeof m==`function`){d=m.call(p,d,f);break a}d=m;break a;case 3:m.flags=m.flags&-65537|128;case 0:if(m=h.payload,f=typeof m==`function`?m.call(p,d,f):m,f==null)break a;d=re({},d,f);break a;case 2:ro=!0}}s.callback!==null&&s.lane!==0&&(e.flags|=64,f=i.effects,f===null?i.effects=[s]:f.push(s))}else p={eventTime:p,lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;f=s,s=f.next,f.next=null,i.lastBaseUpdate=f,i.shared.pending=null}}while(1);if(u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,t=i.shared.interleaved,t!==null){i=t;do o|=i.lane,i=i.next;while(i!==t)}else a===null&&(i.shared.lanes=0);tl|=o,e.lanes=o,e.memoizedState=d}}function fo(e,t,n){if(e=t.effects,t.effects=null,e!==null)for(t=0;tn?n:4,e(!0);var r=Do.transition;Do.transition={};try{e(!1),t()}finally{Ht=n,Do.transition=r}}function ps(){return Vo().memoizedState}function ms(e,t,n){var r=yl(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},gs(e))_s(t,n);else if(n=to(e,t,n,r),n!==null){var i=vl();bl(n,e,r,i),vs(n,t,r)}}function hs(e,t,n){var r=yl(e),i={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(gs(e))_s(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,jr(s,o)){var c=t.interleaved;c===null?(i.next=i,eo(t)):(i.next=c.next,c.next=i),t.interleaved=i;return}}catch{}n=to(e,t,i,r),n!==null&&(i=vl(),bl(n,e,r,i),vs(n,t,r))}}function gs(e){var t=e.alternate;return e===ko||t!==null&&t===ko}function _s(e,t){No=Mo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function vs(e,t,n){if(n&4194240){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Vt(e,n)}}var ys={readContext:Qa,useCallback:Io,useContext:Io,useEffect:Io,useImperativeHandle:Io,useInsertionEffect:Io,useLayoutEffect:Io,useMemo:Io,useReducer:Io,useRef:Io,useState:Io,useDebugValue:Io,useDeferredValue:Io,useTransition:Io,useMutableSource:Io,useSyncExternalStore:Io,useId:Io,unstable_isNewReconciler:!1},bs={readContext:Qa,useCallback:function(e,t){return Bo().memoizedState=[e,t===void 0?null:t],e},useContext:Qa,useEffect:rs,useImperativeHandle:function(e,t,n){return n=n==null?null:n.concat([e]),ts(4194308,4,os.bind(null,t,e),n)},useLayoutEffect:function(e,t){return ts(4194308,4,e,t)},useInsertionEffect:function(e,t){return ts(4,2,e,t)},useMemo:function(e,t){var n=Bo();return t=t===void 0?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=Bo();return t=n===void 0?t:n(t),r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=ms.bind(null,ko,e),[r.memoizedState,e]},useRef:function(e){var t=Bo();return e={current:e},t.memoizedState=e},useState:Qo,useDebugValue:cs,useDeferredValue:function(e){return Bo().memoizedState=e},useTransition:function(){var e=Qo(!1),t=e[0];return e=fs.bind(null,e[1]),Bo().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var i=ko,a=Bo();if(Ea){if(n===void 0)throw Error(r(407));n=n()}else{if(n=t(),Yc===null)throw Error(r(349));Oo&30||qo(i,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,rs(Yo.bind(null,i,o,e),[e]),i.flags|=2048,$o(9,Jo.bind(null,i,o,n,t),void 0,null),n},useId:function(){var e=Bo(),t=Yc.identifierPrefix;if(Ea){var n=H,r=ya;n=(r&~(1<<32-Dt(r)-1)).toString(32)+n,t=`:`+t+`R`+n,n=Po++,0<\/script>`,e=e.removeChild(e.firstChild)):typeof i.is==`string`?e=c.createElement(n,{is:i.is}):(e=c.createElement(n),n===`select`&&(c=e,i.multiple?c.multiple=!0:i.size&&(c.size=i.size))):e=c.createElementNS(e,n),e[Fi]=t,e[Ii]=i,uc(e,t,!1,!1),t.stateNode=e;a:{switch(c=Le(n,i),n){case`dialog`:ci(`cancel`,e),ci(`close`,e),o=i;break;case`iframe`:case`object`:case`embed`:ci(`load`,e),o=i;break;case`video`:case`audio`:for(o=0;osl&&(t.flags|=128,i=!0,pc(s,!1),t.lanes=4194304)}else{if(!i)if(e=Co(c),e!==null){if(t.flags|=128,i=!0,n=e.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),pc(s,!0),s.tail===null&&s.tailMode===`hidden`&&!c.alternate&&!Ea)return mc(t),null}else 2*_t()-s.renderingStartTime>sl&&n!==1073741824&&(t.flags|=128,i=!0,pc(s,!1),t.lanes=4194304);s.isBackwards?(c.sibling=t.child,t.child=c):(n=s.last,n===null?t.child=c:n.sibling=c,s.last=c)}return s.tail===null?(mc(t),null):(t=s.tail,s.rendering=t,s.tail=t.sibling,s.renderingStartTime=_t(),t.sibling=null,n=So.current,Yi(So,i?n&1|2:n&1),t);case 22:case 23:return Al(),i=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==i&&(t.flags|=8192),i&&t.mode&1?Zc&1073741824&&(mc(t),t.subtreeFlags&6&&(t.flags|=8192)):mc(t),null;case 24:return null;case 25:return null}throw Error(r(156,t.tag))}function gc(e,t){switch(Ca(t),t.tag){case 1:return V(t.type)&&ta(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return yo(),Ji(Qi),Ji(Zi),To(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 5:return xo(t),null;case 13:if(Ji(So),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(r(340));Fa()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return Ji(So),null;case 4:return yo(),null;case 10:return Ya(t.type._context),null;case 22:case 23:return Al(),null;case 24:return null;default:return null}}var _c=!1,vc=!1,yc=typeof WeakSet==`function`?WeakSet:Set,W=null;function bc(e,t){var n=e.ref;if(n!==null)if(typeof n==`function`)try{n(null)}catch(n){Wl(e,t,n)}else n.current=null}function xc(e,t,n){try{n()}catch(n){Wl(e,t,n)}}var Sc=!1;function Cc(e,t){if(Ci=hn,e=Ir(),Lr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var i=n.getSelection&&n.getSelection();if(i&&i.rangeCount!==0){n=i.anchorNode;var a=i.anchorOffset,o=i.focusNode;i=i.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||i!==0&&f.nodeType!==3||(l=s+i),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===i&&(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(wi={focusedElem:e,selectionRange:n},hn=!1,W=t;W!==null;)if(t=W,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,W=e;else for(;W!==null;){t=W;try{var h=t.alternate;if(t.flags&1024)switch(t.tag){case 0:case 11:case 15:break;case 1:if(h!==null){var g=h.memoizedProps,_=h.memoizedState,v=t.stateNode;v.__reactInternalSnapshotBeforeUpdate=v.getSnapshotBeforeUpdate(t.elementType===t.type?g:Cs(t.type,g),_)}break;case 3:var y=t.stateNode.containerInfo;y.nodeType===1?y.textContent=``:y.nodeType===9&&y.documentElement&&y.removeChild(y.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(r(163))}}catch(e){Wl(t,t.return,e)}if(e=t.sibling,e!==null){e.return=t.return,W=e;break}W=t.return}return h=Sc,Sc=!1,h}function wc(e,t,n){var r=t.updateQueue;if(r=r===null?null:r.lastEffect,r!==null){var i=r=r.next;do{if((i.tag&e)===e){var a=i.destroy;i.destroy=void 0,a!==void 0&&xc(t,n,a)}i=i.next}while(i!==r)}}function Tc(e,t){if(t=t.updateQueue,t=t===null?null:t.lastEffect,t!==null){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function Ec(e){var t=e.ref;if(t!==null){var n=e.stateNode;switch(e.tag){case 5:e=n;break;default:e=n}typeof t==`function`?t(e):t.current=e}}function Dc(e){var t=e.alternate;t!==null&&(e.alternate=null,Dc(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[Fi],delete t[Ii],delete t[Ri],delete t[zi],delete t[Bi])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function Oc(e){return e.tag===5||e.tag===3||e.tag===4}function kc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Oc(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.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 Ac(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.nodeType===8?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(n.nodeType===8?(t=n.parentNode,t.insertBefore(e,n)):(t=n,t.appendChild(e)),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=Si));else if(r!==4&&(e=e.child,e!==null))for(Ac(e,t,n),e=e.sibling;e!==null;)Ac(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&&(e=e.child,e!==null))for(jc(e,t,n),e=e.sibling;e!==null;)jc(e,t,n),e=e.sibling}var Mc=null,Nc=!1;function Pc(e,t,n){for(n=n.child;n!==null;)Fc(e,t,n),n=n.sibling}function Fc(e,t,n){if(Tt&&typeof Tt.onCommitFiberUnmount==`function`)try{Tt.onCommitFiberUnmount(wt,n)}catch{}switch(n.tag){case 5:vc||bc(n,t);case 6:var r=Mc,i=Nc;Mc=null,Pc(e,t,n),Mc=r,Nc=i,Mc!==null&&(Nc?(e=Mc,n=n.stateNode,e.nodeType===8?e.parentNode.removeChild(n):e.removeChild(n)):Mc.removeChild(n.stateNode));break;case 18:Mc!==null&&(Nc?(e=Mc,n=n.stateNode,e.nodeType===8?ji(e.parentNode,n):e.nodeType===1&&ji(e,n),pn(e)):ji(Mc,n.stateNode));break;case 4:r=Mc,i=Nc,Mc=n.stateNode.containerInfo,Nc=!0,Pc(e,t,n),Mc=r,Nc=i;break;case 0:case 11:case 14:case 15:if(!vc&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){i=r=r.next;do{var a=i,o=a.destroy;a=a.tag,o!==void 0&&(a&2||a&4)&&xc(n,t,o),i=i.next}while(i!==r)}Pc(e,t,n);break;case 1:if(!vc&&(bc(n,t),r=n.stateNode,typeof r.componentWillUnmount==`function`))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(e){Wl(n,t,e)}Pc(e,t,n);break;case 21:Pc(e,t,n);break;case 22:n.mode&1?(vc=(r=vc)||n.memoizedState!==null,Pc(e,t,n),vc=r):Pc(e,t,n);break;default:Pc(e,t,n)}}function Ic(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var n=e.stateNode;n===null&&(n=e.stateNode=new yc),t.forEach(function(t){var r=Jl.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))})}}function G(e,t){var n=t.deletions;if(n!==null)for(var i=0;ia&&(a=s),i&=~o}if(i=a,i=_t()-i,i=(120>i?120:480>i?480:1080>i?1080:1920>i?1920:3e3>i?3e3:4320>i?4320:1960*Wc(i/1960))-i,10e?16:e,pl===null)var i=!1;else{if(e=pl,pl=null,ml=0,Jc&6)throw Error(r(331));var a=Jc;for(Jc|=4,W=e.current;W!==null;){var o=W,s=o.child;if(W.flags&16){var c=o.deletions;if(c!==null){for(var l=0;l_t()-ol?jl(e,0):rl|=n),xl(e,t)}function Kl(e,t){t===0&&(e.mode&1?(t=Mt,Mt<<=1,!(Mt&130023424)&&(Mt=4194304)):t=1);var n=vl();e=no(e,t),e!==null&&(Bt(e,t,n),xl(e,n))}function ql(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),Kl(e,n)}function Jl(e,t){var n=0;switch(e.tag){case 13:var i=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:i=e.stateNode;break;default:throw Error(r(314))}i!==null&&i.delete(t),Kl(e,n)}var Yl=function(e,t,n){if(e!==null)if(e.memoizedProps!==t.pendingProps||Qi.current)Bs=!0;else{if((e.lanes&n)===0&&!(t.flags&128))return Bs=!1,lc(e,t,n);Bs=!!(e.flags&131072)}else Bs=!1,Ea&&t.flags&1048576&&xa(t,ha,t.index);switch(t.lanes=0,t.tag){case 2:var i=t.type;sc(e,t),e=t.pendingProps;var a=ea(t,Zi.current);Za(t,n),a=Ro(null,t,i,e,a,n);var o=zo();return t.flags|=1,typeof a==`object`&&a&&typeof a.render==`function`&&a.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,V(i)?(o=!0,ia(t)):o=!1,t.memoizedState=a.state!==null&&a.state!==void 0?a.state:null,io(t),a.updater=Ts,t.stateNode=a,a._reactInternals=t,ks(t,i,e,n),t=Ys(null,t,i,!0,o,n)):(t.tag=0,Ea&&o&&Sa(t),Vs(null,t,a,n),t=t.child),t;case 16:i=t.elementType;a:{switch(sc(e,t),e=t.pendingProps,a=i._init,i=a(i._payload),t.type=i,a=t.tag=eu(i),e=Cs(i,e),a){case 0:t=qs(null,t,i,e,n);break a;case 1:t=Js(null,t,i,e,n);break a;case 11:t=Hs(null,t,i,e,n);break a;case 14:t=Us(null,t,i,Cs(i.type,e),n);break a}throw Error(r(306,i,``))}return t;case 0:return i=t.type,a=t.pendingProps,a=t.elementType===i?a:Cs(i,a),qs(e,t,i,a,n);case 1:return i=t.type,a=t.pendingProps,a=t.elementType===i?a:Cs(i,a),Js(e,t,i,a,n);case 3:a:{if(Xs(t),e===null)throw Error(r(387));i=t.pendingProps,o=t.memoizedState,a=o.element,ao(e,t),uo(t,i,null,n);var s=t.memoizedState;if(i=s.element,o.isDehydrated)if(o={element:i,isDehydrated:!1,cache:s.cache,pendingSuspenseBoundaries:s.pendingSuspenseBoundaries,transitions:s.transitions},t.updateQueue.baseState=o,t.memoizedState=o,t.flags&256){a=As(Error(r(423)),t),t=Zs(e,t,i,n,a);break a}else if(i!==a){a=As(Error(r(424)),t),t=Zs(e,t,i,n,a);break a}else for(Ta=Mi(t.stateNode.containerInfo.firstChild),wa=t,Ea=!0,Da=null,n=Ua(t,null,i,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling;else{if(Fa(),i===a){t=cc(e,t,n);break a}Vs(e,t,i,n)}t=t.child}return t;case 5:return bo(t),e===null&&ja(t),i=t.type,a=t.pendingProps,o=e===null?null:e.memoizedProps,s=a.children,Ti(i,a)?s=null:o!==null&&Ti(i,o)&&(t.flags|=32),Ks(e,t),Vs(e,t,s,n),t.child;case 6:return e===null&&ja(t),null;case 13:return ec(e,t,n);case 4:return vo(t,t.stateNode.containerInfo),i=t.pendingProps,e===null?t.child=Ha(t,null,i,n):Vs(e,t,i,n),t.child;case 11:return i=t.type,a=t.pendingProps,a=t.elementType===i?a:Cs(i,a),Hs(e,t,i,a,n);case 7:return Vs(e,t,t.pendingProps,n),t.child;case 8:return Vs(e,t,t.pendingProps.children,n),t.child;case 12:return Vs(e,t,t.pendingProps.children,n),t.child;case 10:a:{if(i=t.type._context,a=t.pendingProps,o=t.memoizedProps,s=a.value,Yi(Wa,i._currentValue),i._currentValue=s,o!==null)if(jr(o.value,s)){if(o.children===a.children&&!Qi.current){t=cc(e,t,n);break a}}else for(o=t.child,o!==null&&(o.return=t);o!==null;){var c=o.dependencies;if(c!==null){s=o.child;for(var l=c.firstContext;l!==null;){if(l.context===i){if(o.tag===1){l=oo(-1,n&-n),l.tag=2;var u=o.updateQueue;if(u!==null){u=u.shared;var d=u.pending;d===null?l.next=l:(l.next=d.next,d.next=l),u.pending=l}}o.lanes|=n,l=o.alternate,l!==null&&(l.lanes|=n),Xa(o.return,n,t),c.lanes|=n;break}l=l.next}}else if(o.tag===10)s=o.type===t.type?null:o.child;else if(o.tag===18){if(s=o.return,s===null)throw Error(r(341));s.lanes|=n,c=s.alternate,c!==null&&(c.lanes|=n),Xa(s,n,t),s=o.sibling}else s=o.child;if(s!==null)s.return=o;else for(s=o;s!==null;){if(s===t){s=null;break}if(o=s.sibling,o!==null){o.return=s.return,s=o;break}s=s.return}o=s}Vs(e,t,a.children,n),t=t.child}return t;case 9:return a=t.type,i=t.pendingProps.children,Za(t,n),a=Qa(a),i=i(a),t.flags|=1,Vs(e,t,i,n),t.child;case 14:return i=t.type,a=Cs(i,t.pendingProps),a=Cs(i.type,a),Us(e,t,i,a,n);case 15:return Ws(e,t,t.type,t.pendingProps,n);case 17:return i=t.type,a=t.pendingProps,a=t.elementType===i?a:Cs(i,a),sc(e,t),t.tag=1,V(i)?(e=!0,ia(t)):e=!1,Za(t,n),Ds(t,i,a),ks(t,i,a,n),Ys(null,t,i,!0,e,n);case 19:return oc(e,t,n);case 22:return Gs(e,t,n)}throw Error(r(156,t.tag))};function Xl(e,t){return pt(e,t)}function Zl(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Ql(e,t,n,r){return new Zl(e,t,n,r)}function $l(e){return e=e.prototype,!(!e||!e.isReactComponent)}function eu(e){if(typeof e==`function`)return+!!$l(e);if(e!=null){if(e=e.$$typeof,e===j)return 11;if(e===P)return 14}return 2}function tu(e,t){var n=e.alternate;return n===null?(n=Ql(e.tag,t,e.key,e.mode),n.elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=e.flags&14680064,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function nu(e,t,n,i,a,o){var s=2;if(i=e,typeof e==`function`)$l(e)&&(s=1);else if(typeof e==`string`)s=5;else a:switch(e){case E:return ru(n.children,a,o,t);case D:s=8,a|=8;break;case O:return e=Ql(12,n,t,a|2),e.elementType=O,e.lanes=o,e;case M:return e=Ql(13,n,t,a),e.elementType=M,e.lanes=o,e;case N:return e=Ql(19,n,t,a),e.elementType=N,e.lanes=o,e;case ee:return iu(n,a,o,t);default:if(typeof e==`object`&&e)switch(e.$$typeof){case k:s=10;break a;case A:s=9;break a;case j:s=11;break a;case P:s=14;break a;case F:s=16,i=null;break a}throw Error(r(130,e==null?e:typeof e,``))}return t=Ql(s,n,t,a),t.elementType=e,t.type=i,t.lanes=o,t}function ru(e,t,n,r){return e=Ql(7,e,r,t),e.lanes=n,e}function iu(e,t,n,r){return e=Ql(22,e,r,t),e.elementType=ee,e.lanes=n,e.stateNode={isHidden:!1},e}function au(e,t,n){return e=Ql(6,e,null,t),e.lanes=n,e}function ou(e,t,n){return t=Ql(4,e.children===null?[]:e.children,e.key,t),t.lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function su(e,t,n,r,i){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=zt(0),this.expirationTimes=zt(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=zt(0),this.identifierPrefix=r,this.onRecoverableError=i,this.mutableSourceEagerHydrationData=null}function cu(e,t,n,r,i,a,o,s,c){return e=new su(e,t,n,s,c),t===1?(t=1,!0===a&&(t|=8)):t=0,a=Ql(3,null,null,t),e.current=a,a.stateNode=e,a.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},io(a),e}function lu(e,t,n){var r=3{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=m()})),g=o((e=>{var t=h();e.createRoot=t.createRoot,e.hydrateRoot=t.hydrateRoot})),_=l(d(),1),v=l(h(),1),y=g(),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=/^(?:[a-z][a-z0-9+.-]*:|[\\/]{2})/i,T=/^[\\/]{2}/;function E(e,t){return t+e.replace(/\\/g,`/`)}var D=`popstate`;function O(e){return typeof e==`object`&&!!e&&`pathname`in e&&`search`in e&&`hash`in e&&`state`in e&&`key`in e}function k(e={}){function t(e,t){let n=t.state?.masked,{pathname:r,search:i,hash:a}=n||e.location;return P(``,{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:F(t)}return te(t,n,null,e)}function A(e,t){if(e===!1||e==null)throw Error(t)}function j(e,t){if(!e){typeof console<`u`&&console.warn(t);try{throw Error(t)}catch{}}}function M(){return Math.random().toString(36).substring(2,10)}function N(e,t){return{usr:e.state,key:e.key,idx:t,masked:e.mask?{pathname:e.pathname,search:e.search,hash:e.hash}:void 0}}function P(e,t,n=null,r,i){return{pathname:typeof e==`string`?e:e.pathname,search:``,hash:``,...typeof t==`string`?ee(t):t,state:n,key:t&&t.key||r||M(),mask:i}}function F({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 ee(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 te(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=O(e)?e:P(h.location,e,t);n&&n(r,e),l=u()+1;let d=N(r,l),f=h.createHref(r.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=O(e)?e:P(h.location,e,t);n&&n(r,e),l=u();let i=N(r,l),d=h.createHref(r.mask||r);o.replaceState(i,``,d),a&&c&&c({action:s,location:h.location,delta:0})}function m(e){return ne(i,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(D,d),c=e,()=>{i.removeEventListener(D,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 ne(e,t,n=!1){let r=`http://localhost`;e&&(r=e.location.origin===`null`?e.location.href:e.location.origin),A(r,`No window.location.(origin|href) available to create URL`);let i=typeof t==`string`?t:F(t);return i=i.replace(/ $/,`%20`),!n&&T.test(i)&&(i=r+i),new URL(i,r)}function re(e,t,n=`/`){return ie(e,t,n,!1)}function ie(e,t,n,r,i){let a=xe((typeof t==`string`?ee(t):t).pathname||`/`,n);if(a==null)return null;let o=i??oe(e),s=null,c=be(a);for(let e=0;s==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;A(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=ke([r,c.relativePath]),u=n.concat(c);e.children&&e.children.length>0&&(A(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:L(l,e.index),routesMeta:u.map((e,t)=>{let[n,r]=ye(e.relativePath,e.caseSensitive,t===u.length-1);return{...e,matcher:n,compiledParams:r}})})};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?ge(e.routesMeta.map(e=>e.childrenIndex),t.routesMeta.map(e=>e.childrenIndex)):t.score-e.score)}var ue=/^:[\w-]+$/,de=3,fe=2,I=1,pe=10,me=-2,he=e=>e===`*`;function L(e,t){let n=e.split(`/`),r=n.length;return n.some(he)&&(r+=me),t&&(r+=fe),n.filter(e=>!he(e)).reduce((e,t)=>e+(ue.test(t)?de:t===``?I:pe),r)}function ge(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 R(e,t,n=!1){let{routesMeta:r}=e,i={},a=`/`,o=[];for(let e=0;e{if(t===`*`){let e=s[r]||``;o=Ae(a.slice(0,a.length-e.length),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 ye(e,t=!1,n=!0){j(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 be(e){try{return e.split(`/`).map(e=>decodeURIComponent(e).replace(/\//g,`%2F`)).join(`/`)}catch(t){return j(!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 xe(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)||`/`}function Se(e,t=`/`){let{pathname:n,search:r=``,hash:i=``}=typeof e==`string`?ee(e):e,a;return n?(n=Oe(n),a=n.startsWith(`/`)||n.startsWith(`\\`)?Ce(n.substring(1),`/`):Ce(n,t)):a=t,{pathname:a,search:Me(r),hash:Ne(i)}}function Ce(e,t){let n=Ae(t).split(`/`);return e.split(`/`).forEach(e=>{e===`..`?n.length>1&&n.pop():e!==`.`&&n.push(e)}),n.length>1?n.join(`/`):`/`}function we(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 Te(e){return e.filter((e,t)=>t===0||e.route.path&&e.route.path.length>0)}function Ee(e){let t=Te(e);return t.map((e,n)=>n===t.length-1?e.pathname:e.pathnameBase)}function De(e,t,n,r=!1){let i;typeof e==`string`?i=ee(e):(i={...e},A(!i.pathname||!i.pathname.includes(`?`),we(`?`,`pathname`,`search`,i)),A(!i.pathname||!i.pathname.includes(`#`),we(`#`,`pathname`,`hash`,i)),A(!i.search||!i.search.includes(`#`),we(`#`,`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=Se(i,s),l=o&&o!==`/`&&o.endsWith(`/`),u=(a||o===`.`)&&n.endsWith(`/`);return!c.pathname.endsWith(`/`)&&(l||u)&&(c.pathname+=`/`),c}var Oe=e=>e.replace(/[\\/]{2,}/g,`/`),ke=e=>Oe(e.join(`/`));function Ae(e,t=0){let n=e.length;for(;n>t&&e.charCodeAt(n-1)===47;)n--;return n===e.length?e:e.slice(0,n)}var je=e=>Ae(e).replace(/^\/*/,`/`),Me=e=>!e||e===`?`?``:e.startsWith(`?`)?e:`?`+e,Ne=e=>!e||e===`#`?``:e.startsWith(`#`)?e:`#`+e,Pe=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 Fe(e){return e!=null&&typeof e.status==`number`&&typeof e.statusText==`string`&&typeof e.internal==`boolean`&&`data`in e}function Ie(e){return ke(e.map(e=>e.route.path).filter(Boolean))||`/`}var Le=typeof window<`u`&&window.document!==void 0&&window.document.createElement!==void 0;function Re(e,t){let n=e;if(typeof n!=`string`||!w.test(n))return{absoluteURL:void 0,isExternal:!1,to:n};let r=n,i=!1;if(Le)try{let e=new URL(window.location.href),r=T.test(n)?new URL(E(n,e.protocol)):new URL(n),a=xe(r.pathname,t);r.origin===e.origin&&a!=null?n=a+r.search+r.hash:i=!0}catch{j(!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 ze=new URL(`http://localhost`);function Be(e){if(e.createURL)return e.createURL(`/`);try{return new URL(e.createHref(`/`),ze)}catch{return ze}}function Ve(e,t){return e.origin===t.origin&&(e.origin!==`null`||e.protocol===t.protocol&&e.host===t.host)}function He(e,t){if(e.startsWith(`//`))return!0;let n=t.protocol.toLowerCase();return e.toLowerCase().startsWith(n)?t.host===``||e.slice(n.length).startsWith(`//`):!1}function Ue(e,t,n,r){let i=null;try{i=e==null?null:new URL(e,n)}catch{}let a=new URL(t,n),o=i!=null&&!Ve(i,n),s=!Ve(a,n);if(r===`reject`){if(o||s)throw Error(`External navigation is not allowed`)}else if(s&&(i==null||!He(e,i)||!Ve(i,a)))throw Error(`External navigation is not allowed`)}var We=[`POST`,`PUT`,`PATCH`,`DELETE`];new Set(We);var Ge=[`GET`,...We];new Set(Ge);var Ke=[`about:`,`blob:`,`chrome:`,`chrome-untrusted:`,`content:`,`data:`,`devtools:`,`file:`,`filesystem:`,`javascript:`];function qe(e){try{return Ke.includes(new URL(e).protocol)}catch{return!1}}var Je=_.createContext(null);Je.displayName=`DataRouter`;var Ye=_.createContext(null);Ye.displayName=`DataRouterState`;var Xe=_.createContext(!1);function Ze(){return _.useContext(Xe)}var Qe=_.createContext({isTransitioning:!1});Qe.displayName=`ViewTransition`;var $e=_.createContext(new Map);$e.displayName=`Fetchers`;var et=_.createContext(null);et.displayName=`Await`;var tt=_.createContext(null);tt.displayName=`Navigation`;var nt=_.createContext(null);nt.displayName=`Location`;var rt=_.createContext({outlet:null,matches:[],isDataRoute:!1});rt.displayName=`Route`;var it=_.createContext(null);it.displayName=`RouteError`;var at=`REACT_ROUTER_ERROR`,ot=`REDIRECT`,st=`ROUTE_ERROR_RESPONSE`;function ct(e){if(e.startsWith(`${at}:${ot}:{`))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 lt(e){if(e.startsWith(`${at}:${st}:{`))try{let t=JSON.parse(e.slice(40));if(typeof t==`object`&&t&&typeof t.status==`number`&&typeof t.statusText==`string`)return new Pe(t.status,t.statusText,t.data)}catch{}}function ut(e,{relative:t}={}){A(dt(),`useHref() may be used only in the context of a component.`);let{basename:n,navigator:r}=_.useContext(tt),{hash:i,pathname:a,search:o}=vt(e,{relative:t}),s=a;return n!==`/`&&(s=a===`/`?n:ke([n,a])),r.createHref({pathname:s,search:o,hash:i})}function dt(){return _.useContext(nt)!=null}function ft(){return A(dt(),`useLocation() may be used only in the context of a component.`),_.useContext(nt).location}var pt=`You should call navigate() in a React.useEffect(), not when your component is first rendered.`;function mt(e){_.useContext(tt).static||_.useLayoutEffect(e)}function ht(){let{isDataRoute:e}=_.useContext(rt);return e?Lt():gt()}function gt(){A(dt(),`useNavigate() may be used only in the context of a component.`);let e=_.useContext(Je),{basename:t,navigator:n}=_.useContext(tt),{matches:r}=_.useContext(rt),{pathname:i}=ft(),a=JSON.stringify(Ee(r)),o=_.useRef(!1);return mt(()=>{o.current=!0}),_.useCallback((r,s={})=>{if(j(o.current,pt),!o.current)return;if(typeof r==`number`){n.go(r);return}let c=De(r,JSON.parse(a),i,s.relative===`path`);e==null&&t!==`/`&&(c.pathname=c.pathname===`/`?t:ke([t,c.pathname])),Ue(typeof r==`string`?r:F(r),n.createHref(c),Be(n),`reject`),(s.replace?n.replace:n.push)(c,s.state,s)},[t,n,a,i,e])}_.createContext(null);function _t(){let{matches:e}=_.useContext(rt);return e[e.length-1]?.params??{}}function vt(e,{relative:t}={}){let{matches:n}=_.useContext(rt),{pathname:r}=ft(),i=JSON.stringify(Ee(n));return _.useMemo(()=>De(e,JSON.parse(i),r,t===`path`),[e,i,r,t])}function yt(e,t){return bt(e,t)}function bt(e,t,n){A(dt(),`useRoutes() may be used only in the context of a component.`);let{navigator:r}=_.useContext(tt),{matches:i}=_.useContext(rt),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||``;zt(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=ft(),d;if(t){let e=typeof t==`string`?ee(t):t;A(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=n&&n.state.matches.length?n.state.matches.map(e=>Object.assign(e,{route:n.manifest[e.route.id]||e.route})):re(e,{pathname:p});j(l||m!=null,`No routes matched location "${d.pathname}${d.search}${d.hash}" `),j(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=Dt(m&&m.map(e=>Object.assign({},e,{params:Object.assign({},o,e.params),pathname:ke([c,r.encodeLocation?r.encodeLocation(e.pathname.replace(/%/g,`%25`).replace(/\?/g,`%3F`).replace(/#/g,`%23`)).pathname:e.pathname]),pathnameBase:e.pathnameBase===`/`?c:ke([c,r.encodeLocation?r.encodeLocation(e.pathnameBase.replace(/%/g,`%25`).replace(/\?/g,`%3F`).replace(/#/g,`%23`)).pathname:e.pathnameBase])})),i,n);return t&&h?_.createElement(nt.Provider,{value:{location:{pathname:`/`,search:``,hash:``,state:null,key:`default`,mask:void 0,...d},navigationType:`POP`}},h):h}function xt(){let e=It(),t=Fe(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=_.createElement(_.Fragment,null,_.createElement(`p`,null,`💿 Hey developer 👋`),_.createElement(`p`,null,`You can provide a way better UX than this when your app throws errors by providing your own `,_.createElement(`code`,{style:a},`ErrorBoundary`),` or`,` `,_.createElement(`code`,{style:a},`errorElement`),` prop on your route.`)),_.createElement(_.Fragment,null,_.createElement(`h2`,null,`Unexpected Application Error!`),_.createElement(`h3`,{style:{fontStyle:`italic`}},t),n?_.createElement(`pre`,{style:i},n):null,o)}var St=_.createElement(xt,null),Ct=class extends _.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=lt(e.digest);t&&(e=t)}let t=e===void 0?this.props.children:_.createElement(rt.Provider,{value:this.props.routeContext},_.createElement(it.Provider,{value:e,children:this.props.component}));return this.context?_.createElement(Tt,{error:e},t):t}};Ct.contextType=Xe;var wt=new WeakMap;function Tt({children:e,error:t}){let{basename:n,navigator:r}=_.useContext(tt);if(typeof t==`object`&&t&&`digest`in t&&typeof t.digest==`string`){let e=ct(t.digest);if(e){let i=wt.get(t);if(i)throw i;let a=Re(e.location,n),o=a.absoluteURL||a.to;if(Ue(e.location,o,Be(r),`allow-explicit`),qe(o))throw Error(`Invalid redirect location`);if(Le&&!wt.get(t))if(a.isExternal||e.reloadDocument)window.location.href=o;else{let n=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(a.to,{replace:e.replace}));throw wt.set(t,n),n}return _.createElement(`meta`,{httpEquiv:`refresh`,content:`0;url=${o}`})}}return e}function Et({routeContext:e,match:t,children:n}){let r=_.useContext(Je);return r&&r.static&&r.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=t.route.id),_.createElement(rt.Provider,{value:e},n)}function Dt(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);A(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??{},pattern:Ie(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||St,o&&(s<0&&c===0?(zt(`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?_.createElement(n.route.Component,null):n.route.element?n.route.element:e,_.createElement(Et,{match:n,routeContext:{outlet:e,matches:m,isDataRoute:r!=null},children:t})};return r&&(n.route.ErrorBoundary||n.route.errorElement||c===0)?_.createElement(Ct,{location:r.location,revalidation:r.revalidation,component:f,error:u,children:h(),routeContext:{outlet:null,matches:m,isDataRoute:!0},onError:l}):h()},null)}function Ot(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function kt(e){let t=_.useContext(Je);return A(t,Ot(e)),t}function At(e){let t=_.useContext(Ye);return A(t,Ot(e)),t}function jt(e){let t=_.useContext(rt);return A(t,Ot(e)),t}function Mt(e){let t=jt(e),n=t.matches[t.matches.length-1];return A(n.route.id,`${e} can only be used on routes that contain a unique "id"`),n.route.id}function Nt(){return Mt(`useRouteId`)}function Pt(){let e=At(`useNavigation`);return _.useMemo(()=>{let{matches:t,historyAction:n,...r}=e.navigation;return r},[e.navigation])}function Ft(){let{matches:e,loaderData:t}=At(`useMatches`);return _.useMemo(()=>e.map(e=>ae(e,t)),[e,t])}function It(){let e=_.useContext(it),t=At(`useRouteError`),n=Mt(`useRouteError`);return e===void 0?t.errors?.[n]:e}function Lt(){let{router:e}=kt(`useNavigate`),t=Mt(`useNavigate`),n=_.useRef(!1);return mt(()=>{n.current=!0}),_.useCallback(async(r,i={})=>{j(n.current,pt),n.current&&(typeof r==`number`?await e.navigate(r):await e.navigate(r,{fromRouteId:t,...i}))},[e,t])}var Rt={};function zt(e,t,n){!t&&!Rt[e]&&(Rt[e]=!0,j(!1,n))}_.memo(Bt);function Bt({routes:e,manifest:t,future:n,state:r,isStatic:i,onError:a}){return bt(e,void 0,{manifest:t,state:r,isStatic:i,onError:a,future:n})}function z(e){A(!1,`A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .`)}function Vt({basename:e=`/`,children:t=null,location:n,navigationType:r=`POP`,navigator:i,static:a=!1,useTransitions:o}){A(!dt(),`You cannot render a inside another . You should never have more than one in your app.`);let s=e.replace(/^\/*/,`/`),c=_.useMemo(()=>({basename:s,navigator:i,static:a,useTransitions:o,future:{}}),[s,i,a,o]);typeof n==`string`&&(n=ee(n));let{pathname:l=`/`,search:u=``,hash:d=``,state:f=null,key:p=`default`,mask:m}=n,h=_.useMemo(()=>{let e=xe(l,s);return e==null?null:{location:{pathname:e,search:u,hash:d,state:f,key:p,mask:m},navigationType:r}},[s,l,u,d,f,p,r,m]);return j(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:_.createElement(tt.Provider,{value:c},_.createElement(nt.Provider,{children:t,value:h}))}function Ht({children:e,location:t}){return yt(Ut(e),t)}_.Component;function Ut(e,t=[]){let n=[];return _.Children.forEach(e,(e,r)=>{if(!_.isValidElement(e))return;let i=[...t,r];if(e.type===_.Fragment){n.push.apply(n,Ut(e.props.children,i));return}A(e.type===z,`[${typeof e.type==`string`?e.type:e.type.name}] is not a component. All component children of must be a or `),A(!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=Ut(e.props.children,i)),n.push(a)}),n}var Wt=`get`,Gt=`application/x-www-form-urlencoded`;function Kt(e){return typeof HTMLElement<`u`&&e instanceof HTMLElement}function qt(e){return Kt(e)&&e.tagName.toLowerCase()===`button`}function Jt(e){return Kt(e)&&e.tagName.toLowerCase()===`form`}function Yt(e){return Kt(e)&&e.tagName.toLowerCase()===`input`}function Xt(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function Zt(e,t){return e.button===0&&(!t||t===`_self`)&&!Xt(e)}function Qt(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 $t(e,t){let n=Qt(e);return t&&t.forEach((e,r)=>{n.has(r)||t.getAll(r).forEach(e=>{n.append(r,e)})}),n}var en=null;function tn(){if(en===null)try{new FormData(document.createElement(`form`),0),en=!1}catch{en=!0}return en}var nn=new Set([`application/x-www-form-urlencoded`,`multipart/form-data`,`text/plain`]);function rn(e){return e!=null&&!nn.has(e)?(j(!1,`"${e}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${Gt}"`),null):e}function an(e,t){let n,r,i,a,o;if(Jt(e)){let o=e.getAttribute(`action`);r=o?xe(o,t):null,n=e.getAttribute(`method`)||Wt,i=rn(e.getAttribute(`enctype`))||Gt,a=new FormData(e)}else if(qt(e)||Yt(e)&&(e.type===`submit`||e.type===`image`)){let o=e.form;if(o==null)throw Error(`Cannot submit a + + + + + ); +} diff --git a/frontend/src/lib/replayApi.test.ts b/frontend/src/lib/replayApi.test.ts new file mode 100644 index 000000000..ea3dca443 --- /dev/null +++ b/frontend/src/lib/replayApi.test.ts @@ -0,0 +1,21 @@ +import { expect, test, vi } from "vitest"; + +import { mergeLocalDatasets } from "./replayApi"; + +test("posts the selected local datasets and output name", async () => { + const fetcher = vi.fn().mockResolvedValue( + new Response( + JSON.stringify({ success: true, repo_id: "local/combined", num_episodes: 4, total_frames: 120 }), + { status: 200, headers: { "Content-Type": "application/json" } }, + ), + ); + + await expect(mergeLocalDatasets("http://localhost:8000", fetcher, ["local/one", "local/two"], "combined")) + .resolves.toEqual({ success: true, repo_id: "local/combined", num_episodes: 4, total_frames: 120 }); + + expect(fetcher).toHaveBeenCalledWith("http://localhost:8000/datasets/merge", { + method: "POST", + signal: undefined, + body: JSON.stringify({ source_repo_ids: ["local/one", "local/two"], output_name: "combined" }), + }); +}); diff --git a/frontend/src/lib/replayApi.ts b/frontend/src/lib/replayApi.ts index dadcf8ae9..21c591ec2 100644 --- a/frontend/src/lib/replayApi.ts +++ b/frontend/src/lib/replayApi.ts @@ -9,6 +9,13 @@ export interface DatasetItem { source: DatasetSource; } +export interface MergeDatasetsResult { + success: true; + repo_id: string; + num_episodes: number; + total_frames: number; +} + export async function listDatasets( baseUrl: string, fetcher: Fetcher, @@ -35,3 +42,16 @@ export async function listLocalDatasets( action: "List local datasets", }); } + +export async function mergeLocalDatasets( + baseUrl: string, + fetcher: Fetcher, + sourceRepoIds: string[], + outputName: string, +): Promise { + return apiRequest(baseUrl, fetcher, "/datasets/merge", { + method: "POST", + body: { source_repo_ids: sourceRepoIds, output_name: outputName }, + action: "Merge datasets", + }); +} diff --git a/frontend/src/pages/EditDataset.tsx b/frontend/src/pages/EditDataset.tsx index a291cb7de..7e8f89dbe 100644 --- a/frontend/src/pages/EditDataset.tsx +++ b/frontend/src/pages/EditDataset.tsx @@ -1,6 +1,6 @@ -import React, { useEffect, useMemo } from "react"; +import React, { useEffect, useMemo, useState } from "react"; import { useNavigate, useSearchParams } from "react-router-dom"; -import { AlertCircle, ArrowLeft, Database, Loader2, Upload } from "lucide-react"; +import { AlertCircle, ArrowLeft, Database, Loader2, Merge, Upload } from "lucide-react"; import { Select, SelectContent, @@ -11,9 +11,13 @@ import { import { Button } from "@/components/ui/button"; import EpisodeList from "@/components/dataset/EpisodeList"; import EpisodeViewer from "@/components/dataset/EpisodeViewer"; +import MergeDatasetsDialog from "@/components/dataset/MergeDatasetsDialog"; +import { useApi } from "@/contexts/ApiContext"; import { useDatasets } from "@/hooks/useDatasets"; import { useEpisodeDetail, useEpisodes } from "@/hooks/useEpisodes"; +import { useToast } from "@/hooks/use-toast"; import { formatDuration } from "@/lib/datasetApi"; +import { mergeLocalDatasets } from "@/lib/replayApi"; const Stat: React.FC<{ label: string; value: string }> = ({ label, value }) => ( @@ -33,7 +37,10 @@ const EditDataset = () => { const navigate = useNavigate(); const [searchParams, setSearchParams] = useSearchParams(); - const { datasets, loading: datasetsLoading } = useDatasets(); + const { datasets, loading: datasetsLoading, refresh } = useDatasets(); + const { baseUrl, fetchWithHeaders } = useApi(); + const { toast } = useToast(); + const [mergeOpen, setMergeOpen] = useState(false); // A Hub-only dataset has no videos on disk to decode. const localDatasets = useMemo( () => datasets.filter((d) => d.source === "local" || d.source === "both"), @@ -62,6 +69,12 @@ const EditDataset = () => { return api ? { ...params, api } : params; }; const setDataset = (next: string) => setSearchParams(withApi({ dataset: next })); + const handleMerge = async (sourceRepoIds: string[], outputName: string) => { + const result = await mergeLocalDatasets(baseUrl, fetchWithHeaders, sourceRepoIds, outputName); + refresh(); + setDataset(result.repo_id); + toast({ title: "Datasets merged", description: `${result.num_episodes} episodes are ready to browse.` }); + }; const setEpisode = (next: number) => { if (!repoId) return; setSearchParams(withApi({ dataset: repoId, episode: String(next) })); @@ -113,6 +126,15 @@ const EditDataset = () => { + {/* Picking a dataset now lands here rather than on /upload, so the upload + delete flow hangs off the page you browse from. */} {repoId && ( @@ -206,6 +228,12 @@ const EditDataset = () => { )} + ); }; diff --git a/lelab/datasets.py b/lelab/datasets.py index 2948fe51f..f5b575218 100644 --- a/lelab/datasets.py +++ b/lelab/datasets.py @@ -14,17 +14,26 @@ import base64 import logging +import re +import shutil +import tempfile from datetime import UTC, datetime from pathlib import Path from typing import Any from huggingface_hub.errors import HfHubHTTPError +from lerobot.datasets import LeRobotDataset +from lerobot.datasets.dataset_tools import merge_datasets + from . import episode_media from .utils.hf_auth import cached_whoami, shared_hf_api logger = logging.getLogger(__name__) +LOCAL_DATASET_NAMESPACE = "local" +_DATASET_NAME_RE = re.compile(r"[A-Za-z0-9._-]+$") + def _lerobot_cache_root() -> Path: return episode_media.lerobot_cache_root() @@ -173,6 +182,52 @@ def list_all_datasets() -> list[dict[str, Any]]: return out +def handle_merge_local_datasets(source_repo_ids: list[str], output_name: str) -> dict[str, Any]: + """Merge local datasets into a new local dataset without touching sources.""" + source_repo_ids = [repo_id.strip() for repo_id in source_repo_ids] + if len(source_repo_ids) < 2: + raise ValueError("Select at least two local datasets to merge") + if len(set(source_repo_ids)) != len(source_repo_ids): + raise ValueError("Select each source dataset only once") + + output_name = output_name.strip() + if not _DATASET_NAME_RE.fullmatch(output_name): + raise ValueError("Output name may contain only letters, numbers, '.', '_' and '-'") + + output_repo_id = f"{LOCAL_DATASET_NAMESPACE}/{output_name}" + cache_root = _lerobot_cache_root() + output_dir = (cache_root / output_repo_id).resolve() + if cache_root not in output_dir.parents: + raise ValueError("Invalid output dataset path") + if output_dir.exists(): + raise ValueError(f"A local dataset already exists at {output_repo_id}") + + source_dirs = [episode_media.resolve_dataset_dir(repo_id) for repo_id in source_repo_ids] + datasets = [ + LeRobotDataset(repo_id=repo_id, root=source_dir) + for repo_id, source_dir in zip(source_repo_ids, source_dirs, strict=True) + ] + + output_dir.parent.mkdir(parents=True, exist_ok=True) + staging_parent = Path(tempfile.mkdtemp(prefix=f".{output_name}.merge-", dir=output_dir.parent)) + staging_output = staging_parent / "dataset" + try: + merged = merge_datasets(datasets, output_repo_id=output_repo_id, output_dir=staging_output) + staging_output.rename(output_dir) + except Exception: + shutil.rmtree(staging_parent, ignore_errors=True) + raise + else: + shutil.rmtree(staging_parent, ignore_errors=True) + + return { + "success": True, + "repo_id": output_repo_id, + "num_episodes": merged.num_episodes, + "total_frames": merged.num_frames, + } + + # ── episode browsing ──────────────────────────────────────────────────────── # # Everything below reads a *local* dataset only. Browsing a Hub-only dataset diff --git a/lelab/server.py b/lelab/server.py index 08d5d53af..3f10d7813 100644 --- a/lelab/server.py +++ b/lelab/server.py @@ -135,6 +135,11 @@ def from_legacy(cls, raw: dict) -> "StartTrainingBody": return cls(config=TrainingRequest.model_validate(raw)) +class MergeDatasetsRequest(BaseModel): + source_repo_ids: list[str] + output_name: str + + # Cache for HF Jobs hardware flavors (5-minute TTL) _flavors_cache: dict = {"data": None, "fetched_at": 0.0} _FLAVOR_CACHE_TTL_SECONDS = 300.0 @@ -391,6 +396,15 @@ def datasets_list(scope: str = "all"): return dataset_browser.list_all_datasets() +@app.post("/datasets/merge") +def merge_local_datasets(request: MergeDatasetsRequest): + """Merge two or more local datasets into a new local dataset.""" + try: + return dataset_browser.handle_merge_local_datasets(request.source_repo_ids, request.output_name) + except (DatasetNotFoundError, ValueError) as exc: + raise HTTPException(status_code=400, detail=str(exc)) from exc + + @app.get("/dataset-episodes") def dataset_episodes(repo_id: str): """List the episodes of a local dataset.""" diff --git a/tests/test_datasets.py b/tests/test_datasets.py index ba7113d18..30de15766 100644 --- a/tests/test_datasets.py +++ b/tests/test_datasets.py @@ -135,6 +135,121 @@ def test_list_all_datasets_merges_hub_and_local( assert by_id["alice/aloha"]["source"] == "hub" +def test_merge_local_datasets_creates_new_dataset_without_touching_sources( + tmp_lerobot_home: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + from lelab import datasets as datasets_mod + + _make_dataset(tmp_lerobot_home, "alice/first") + _make_dataset(tmp_lerobot_home, "bob/second") + calls = [] + + class FakeDataset: + def __init__(self, repo_id: str, root: Path) -> None: + self.repo_id = repo_id + self.root = root + + class FakeMergedDataset: + num_episodes = 7 + num_frames = 70 + + def fake_merge(datasets, output_repo_id: str, output_dir: Path): + calls.append((datasets, output_repo_id, output_dir)) + (output_dir / "meta").mkdir(parents=True) + (output_dir / "meta" / "info.json").write_text("{}") + return FakeMergedDataset() + + monkeypatch.setattr(datasets_mod, "LeRobotDataset", FakeDataset) + monkeypatch.setattr(datasets_mod, "merge_datasets", fake_merge) + + result = datasets_mod.handle_merge_local_datasets(["alice/first", "bob/second"], "combined") + + assert result == {"success": True, "repo_id": "local/combined", "num_episodes": 7, "total_frames": 70} + assert [dataset.repo_id for dataset in calls[0][0]] == ["alice/first", "bob/second"] + assert calls[0][1] == "local/combined" + assert (tmp_lerobot_home / "local" / "combined" / "meta" / "info.json").is_file() + assert (tmp_lerobot_home / "alice" / "first" / "meta" / "info.json").is_file() + assert (tmp_lerobot_home / "bob" / "second" / "meta" / "info.json").is_file() + + +@pytest.mark.parametrize( + ("source_repo_ids", "output_name", "message"), + [ + (["alice/first"], "combined", "at least two"), + (["alice/first", "alice/first"], "combined", "only once"), + (["alice/first", "bob/second"], "not/a-name", "Output name"), + ], +) +def test_merge_local_datasets_rejects_invalid_request( + tmp_lerobot_home: Path, source_repo_ids: list[str], output_name: str, message: str +) -> None: + from lelab.datasets import handle_merge_local_datasets + + with pytest.raises(ValueError, match=message): + handle_merge_local_datasets(source_repo_ids, output_name) + + +def test_merge_local_datasets_rejects_existing_output(tmp_lerobot_home: Path) -> None: + from lelab.datasets import handle_merge_local_datasets + + _make_dataset(tmp_lerobot_home, "local/combined") + with pytest.raises(ValueError, match="already exists"): + handle_merge_local_datasets(["alice/first", "bob/second"], "combined") + + +def test_merge_local_datasets_cleans_staging_output_on_failure( + tmp_lerobot_home: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + from lelab import datasets as datasets_mod + + _make_dataset(tmp_lerobot_home, "alice/first") + _make_dataset(tmp_lerobot_home, "bob/second") + monkeypatch.setattr(datasets_mod, "LeRobotDataset", lambda repo_id, root: object()) + + def failing_merge(datasets, output_repo_id: str, output_dir: Path): + output_dir.mkdir(parents=True) + raise RuntimeError("incompatible features") + + monkeypatch.setattr(datasets_mod, "merge_datasets", failing_merge) + + with pytest.raises(RuntimeError, match="incompatible features"): + datasets_mod.handle_merge_local_datasets(["alice/first", "bob/second"], "combined") + + assert not (tmp_lerobot_home / "local" / "combined").exists() + assert not list((tmp_lerobot_home / "local").glob(".combined.merge-*")) + assert (tmp_lerobot_home / "alice" / "first" / "meta" / "info.json").is_file() + assert (tmp_lerobot_home / "bob" / "second" / "meta" / "info.json").is_file() + + +def test_merge_route_returns_result_and_maps_validation_error( + client: TestClient, monkeypatch: pytest.MonkeyPatch +) -> None: + from lelab import datasets as datasets_mod + + monkeypatch.setattr( + datasets_mod, + "handle_merge_local_datasets", + lambda source_repo_ids, output_name: { + "success": True, + "repo_id": "local/combined", + "num_episodes": 3, + "total_frames": 30, + }, + ) + response = client.post( + "/datasets/merge", json={"source_repo_ids": ["alice/one", "alice/two"], "output_name": "combined"} + ) + assert response.status_code == 200 + assert response.json()["repo_id"] == "local/combined" + + monkeypatch.setattr( + datasets_mod, "handle_merge_local_datasets", lambda *_: (_ for _ in ()).throw(ValueError("bad input")) + ) + response = client.post("/datasets/merge", json={"source_repo_ids": [], "output_name": "combined"}) + assert response.status_code == 400 + assert response.json()["detail"] == "bad input" + + # ── episode browsing ──────────────────────────────────────────────────────── # # The handlers are covered end-to-end through the routes, so the query-param From c6f5800d3f5d5589e237ee5acf05b93776f3b89f Mon Sep 17 00:00:00 2001 From: Samuel-Hills Date: Wed, 30 Sep 2026 12:03:48 -0400 Subject: [PATCH 2/3] fix: address local dataset merge review --- .../{index-C7QO1l1G.js => index-Dpbx8D4U.js} | 2 +- frontend/dist/index.html | 2 +- .../dataset/MergeDatasetsDialog.test.tsx | 41 +++++++++++++ .../dataset/MergeDatasetsDialog.tsx | 31 +++++++--- frontend/src/pages/EditDataset.tsx | 36 ++++++----- lelab/datasets.py | 10 ++++ tests/test_datasets.py | 59 +++++++++++++++++++ 7 files changed, 157 insertions(+), 24 deletions(-) rename frontend/dist/assets/{index-C7QO1l1G.js => index-Dpbx8D4U.js} (98%) create mode 100644 frontend/src/components/dataset/MergeDatasetsDialog.test.tsx diff --git a/frontend/dist/assets/index-C7QO1l1G.js b/frontend/dist/assets/index-Dpbx8D4U.js similarity index 98% rename from frontend/dist/assets/index-C7QO1l1G.js rename to frontend/dist/assets/index-Dpbx8D4U.js index c4e323292..8d7885cff 100644 --- a/frontend/dist/assets/index-C7QO1l1G.js +++ b/frontend/dist/assets/index-Dpbx8D4U.js @@ -3955,4 +3955,4 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function Iae(e,t){if(e){if(typeof e==`string`)return S7(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if(n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`)return Array.from(e);if(n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return S7(e,t)}}function Lae(e){if(typeof Symbol<`u`&&e[Symbol.iterator]!=null||e[`@@iterator`]!=null)return Array.from(e)}function Rae(e){if(Array.isArray(e))return S7(e)}function S7(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);ns){l=[].concat(x7(i.slice(0,u)),[s-d]);break}var f=l.length%2==0?[0,c]:[c];return[].concat(x7(t.repeat(i,o)),x7(l),f).map(function(e){return`${e}px`}).join(`, `)}),D7(e,`id`,gR(`recharts-line-`)),D7(e,`pathRef`,function(t){e.mainCurve=t}),D7(e,`handleAnimationEnd`,function(){e.setState({isAnimationFinished:!0}),e.props.onAnimationEnd&&e.props.onAnimationEnd()}),D7(e,`handleAnimationStart`,function(){e.setState({isAnimationFinished:!1}),e.props.onAnimationStart&&e.props.onAnimationStart()}),e}return Wae(t,e),Bae(t,[{key:`componentDidMount`,value:function(){if(this.props.isAnimationActive){var e=this.getTotalLength();this.setState({totalLength:e})}}},{key:`componentDidUpdate`,value:function(){if(this.props.isAnimationActive){var e=this.getTotalLength();e!==this.state.totalLength&&this.setState({totalLength:e})}}},{key:`getTotalLength`,value:function(){var e=this.mainCurve;try{return e&&e.getTotalLength&&e.getTotalLength()||0}catch{return 0}}},{key:`renderErrorBar`,value:function(e,t){if(this.props.isAnimationActive&&!this.state.isAnimationFinished)return null;var n=this.props,r=n.points,i=n.xAxis,a=n.yAxis,o=n.layout,s=n.children,c=KR(s,x$);if(!c)return null;var l=function(e,t){return{x:e.x,y:e.y,value:e.value,errorVal:G$(e.payload,t)}},u={clipPath:e?`url(#clipPath-${t})`:null};return _.createElement(mz,u,c.map(function(e){return _.cloneElement(e,{key:`bar-${e.props.dataKey}`,data:r,xAxis:i,yAxis:a,layout:o,dataPointFormatter:l})}))}},{key:`renderDots`,value:function(e,n,r){if(this.props.isAnimationActive&&!this.state.isAnimationFinished)return null;var i=this.props,a=i.dot,o=i.points,s=i.dataKey,c=$R(this.props,!1),l=$R(a,!0),u=o.map(function(e,n){var r=b7(b7(b7({key:`dot-${n}`,r:3},c),l),{},{index:n,cx:e.x,cy:e.y,value:e.value,dataKey:s,payload:e.payload,points:o});return t.renderDotItem(a,r)}),d={clipPath:e?`url(#clipPath-${n?``:`dots-`}${r})`:null};return _.createElement(mz,v7({className:`recharts-line-dots`,key:`dots`},d),u)}},{key:`renderCurveStatically`,value:function(e,t,n,r){var i=this.props,a=i.type,o=i.layout,s=i.connectNulls;i.ref;var c=b7(b7(b7({},$R(_7(i,Mae),!0)),{},{fill:`none`,className:`recharts-line-curve`,clipPath:t?`url(#clipPath-${n})`:null,points:e},r),{},{type:a,layout:o,connectNulls:s});return _.createElement(a2,v7({},c,{pathRef:this.pathRef}))}},{key:`renderCurveWithAnimation`,value:function(e,t){var n=this,r=this.props,i=r.points,a=r.strokeDasharray,o=r.isAnimationActive,s=r.animationBegin,c=r.animationDuration,l=r.animationEasing,u=r.animationId,d=r.animateNewValues,f=r.width,p=r.height,m=this.state,h=m.prevPoints,g=m.totalLength;return _.createElement(B3,{begin:s,duration:c,isActive:o,easing:l,from:{t:0},to:{t:1},key:`line-${u}`,onAnimationEnd:this.handleAnimationEnd,onAnimationStart:this.handleAnimationStart},function(r){var o=r.t;if(h){var s=h.length/i.length,c=i.map(function(e,t){var n=Math.floor(t*s);if(h[n]){var r=h[n],i=bR(r.x,e.x),a=bR(r.y,e.y);return b7(b7({},e),{},{x:i(o),y:a(o)})}if(d){var c=bR(f*2,e.x),l=bR(p/2,e.y);return b7(b7({},e),{},{x:c(o),y:l(o)})}return b7(b7({},e),{},{x:e.x,y:e.y})});return n.renderCurveStatically(c,e,t)}var l=bR(0,g)(o),u;if(a){var m=`${a}`.split(/[,\s]+/gim).map(function(e){return parseFloat(e)});u=n.getStrokeDasharray(l,g,m)}else u=n.generateSimpleStrokeDasharray(g,l);return n.renderCurveStatically(i,e,t,{strokeDasharray:u})})}},{key:`renderCurve`,value:function(e,t){var n=this.props,r=n.points,i=n.isAnimationActive,a=this.state,o=a.prevPoints,s=a.totalLength;return i&&r&&r.length&&(!o&&s>0||!(0,M$.default)(o,r))?this.renderCurveWithAnimation(e,t):this.renderCurveStatically(r,e,t)}},{key:`render`,value:function(){var e=this.props,t=e.hide,n=e.dot,r=e.points,i=e.className,a=e.xAxis,o=e.yAxis,s=e.top,c=e.left,l=e.width,u=e.height,d=e.isAnimationActive,f=e.id;if(t||!r||!r.length)return null;var p=this.state.isAnimationFinished,m=r.length===1,h=Xo(`recharts-line`,i),g=a&&a.allowDataOverflow,v=o&&o.allowDataOverflow,y=g||v,b=(0,uR.default)(f)?this.id:f,x=$R(n,!1)??{r:3,strokeWidth:2},S=x.r,C=S===void 0?3:S,w=x.strokeWidth,T=w===void 0?2:w,E=(ZR(n)?n:{}).clipDot,D=E===void 0?!0:E,O=C*2+T;return _.createElement(mz,{className:h},g||v?_.createElement(`defs`,null,_.createElement(`clipPath`,{id:`clipPath-${b}`},_.createElement(`rect`,{x:g?c:c-l/2,y:v?s:s-u/2,width:g?l:l*2,height:v?u:u*2})),!D&&_.createElement(`clipPath`,{id:`clipPath-dots-${b}`},_.createElement(`rect`,{x:c-O/2,y:s-O/2,width:l+O,height:u+O}))):null,!m&&this.renderCurve(y,b),this.renderErrorBar(y,b),(m||n)&&this.renderDots(y,D,b),(!d||p)&&A0.renderCallByParent(this.props,r))}}],[{key:`getDerivedStateFromProps`,value:function(e,t){return e.animationId===t.prevAnimationId?e.points===t.curPoints?null:{curPoints:e.points}:{prevAnimationId:e.animationId,curPoints:e.points,prevPoints:t.curPoints}}},{key:`repeat`,value:function(e,t){for(var n=e.length%2==0?e:[].concat(x7(e),[0]),r=[],i=0;i=0)&&Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}function Jae(e,t){if(e==null)return{};var n={};for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r)){if(t.indexOf(r)>=0)continue;n[r]=e[r]}return n}function N7(){return N7=Object.assign?Object.assign.bind():function(e){for(var t=1;t0||!(0,M$.default)(s,r)||!(0,M$.default)(c,i))?this.renderAreaWithAnimation(e,t):this.renderAreaStatically(r,i,e,t)}},{key:`render`,value:function(){var e=this.props,t=e.hide,n=e.dot,r=e.points,i=e.className,a=e.top,o=e.left,s=e.xAxis,c=e.yAxis,l=e.width,u=e.height,d=e.isAnimationActive,f=e.id;if(t||!r||!r.length)return null;var p=this.state.isAnimationFinished,m=r.length===1,h=Xo(`recharts-area`,i),g=s&&s.allowDataOverflow,v=c&&c.allowDataOverflow,y=g||v,b=(0,uR.default)(f)?this.id:f,x=$R(n,!1)??{r:3,strokeWidth:2},S=x.r,C=S===void 0?3:S,w=x.strokeWidth,T=w===void 0?2:w,E=(ZR(n)?n:{}).clipDot,D=E===void 0?!0:E,O=C*2+T;return _.createElement(mz,{className:h},g||v?_.createElement(`defs`,null,_.createElement(`clipPath`,{id:`clipPath-${b}`},_.createElement(`rect`,{x:g?o:o-l/2,y:v?a:a-u/2,width:g?l:l*2,height:v?u:u*2})),!D&&_.createElement(`clipPath`,{id:`clipPath-dots-${b}`},_.createElement(`rect`,{x:o-O/2,y:a-O/2,width:l+O,height:u+O}))):null,m?null:this.renderArea(y,b),(n||m)&&this.renderDots(y,D,b),(!d||p)&&A0.renderCallByParent(this.props,r))}}],[{key:`getDerivedStateFromProps`,value:function(e,t){return e.animationId===t.prevAnimationId?e.points!==t.curPoints||e.baseLine!==t.curBaseLine?{curPoints:e.points,curBaseLine:e.baseLine}:null:{prevAnimationId:e.animationId,curPoints:e.points,curBaseLine:e.baseLine,prevPoints:t.curPoints,prevBaseLine:t.curBaseLine}}}])}(_.PureComponent);A7=H7,B7(H7,`displayName`,`Area`),B7(H7,`defaultProps`,{stroke:`#3182bd`,fill:`#3182bd`,fillOpacity:.6,xAxisId:0,yAxisId:0,legendType:`line`,connectNulls:!1,points:[],dot:!1,activeDot:!0,hide:!1,isAnimationActive:!AW.isSsr,animationBegin:0,animationDuration:1500,animationEasing:`ease`}),B7(H7,`getBaseValue`,function(e,t,n,r){var i=e.layout,a=e.baseValue,o=t.props.baseValue??a;if(Q(o)&&typeof o==`number`)return o;var s=i===`horizontal`?r:n,c=s.scale.domain();if(s.type===`number`){var l=Math.max(c[0],c[1]),u=Math.min(c[0],c[1]);return o===`dataMin`?u:o===`dataMax`||l<0?l:Math.max(Math.min(c[0],c[1]),0)}return o===`dataMin`?c[0]:o===`dataMax`?c[1]:c[0]}),B7(H7,`getComposedData`,function(e){var t=e.props,n=e.item,r=e.xAxis,i=e.yAxis,a=e.xAxisTicks,o=e.yAxisTicks,s=e.bandSize,c=e.dataKey,l=e.stackedData,u=e.dataStartIndex,d=e.displayedData,f=e.offset,p=t.layout,m=l&&l.length,h=A7.getBaseValue(t,n,r,i),g=p===`horizontal`,_=!1,v=d.map(function(e,t){var n;m?n=l[u+t]:(n=G$(e,c),Array.isArray(n)?_=!0:n=[h,n]);var d=n[1]==null||m&&G$(e,c)==null;return g?{x:h1({axis:r,ticks:a,bandSize:s,entry:e,index:t}),y:d?null:i.scale(n[1]),value:n,payload:e}:{x:d?null:r.scale(n[1]),y:h1({axis:i,ticks:o,bandSize:s,entry:e,index:t}),value:n,payload:e}});return F7({points:v,baseLine:m||_?v.map(function(e){var t=Array.isArray(e.value)?e.value[0]:null;return g?{x:e.x,y:t!=null&&e.y!=null?i.scale(t):null}:{x:t==null?null:r.scale(t),y:e.y}}):g?i.scale(h):r.scale(h),layout:p,isRange:_},f)}),B7(H7,`renderDotItem`,function(e,t){var n;if(_.isValidElement(e))n=_.cloneElement(e,t);else if((0,PR.default)(e))n=e(t);else{var r=Xo(`recharts-area-dot`,typeof e==`boolean`?``:e.className),i=t.key,a=M7(t,qae);n=_.createElement(a6,N7({},a,{key:i,className:r}))}return n});function U7(e){"@babel/helpers - typeof";return U7=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},U7(e)}function noe(e,t){if(!(e instanceof t))throw TypeError(`Cannot call a class as a function`)}function W7(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);n{var n=Object.prototype.hasOwnProperty,r=`~`;function i(){}Object.create&&(i.prototype=Object.create(null),new i().__proto__||(r=!1));function a(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function o(e,t,n,i,o){if(typeof n!=`function`)throw TypeError(`The listener must be a function`);var s=new a(n,i||e,o),c=r?r+t:t;return e._events[c]?e._events[c].fn?e._events[c]=[e._events[c],s]:e._events[c].push(s):(e._events[c]=s,e._eventsCount++),e}function s(e,t){--e._eventsCount===0?e._events=new i:delete e._events[t]}function c(){this._events=new i,this._eventsCount=0}c.prototype.eventNames=function(){var e=[],t,i;if(this._eventsCount===0)return e;for(i in t=this._events)n.call(t,i)&&e.push(r?i.slice(1):i);return Object.getOwnPropertySymbols?e.concat(Object.getOwnPropertySymbols(t)):e},c.prototype.listeners=function(e){var t=r?r+e:e,n=this._events[t];if(!n)return[];if(n.fn)return[n.fn];for(var i=0,a=n.length,o=Array(a);i=0)&&Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}function Loe(e,t){if(e==null)return{};var n={};for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r)){if(t.indexOf(r)>=0)continue;n[r]=e[r]}return n}function Roe(e,t){if(!(e instanceof t))throw TypeError(`Cannot call a class as a function`)}function T9(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);n0?a:e&&e.length&&Q(r)&&Q(i)?e.slice(r,i+1):[]};function R9(e){return e===`number`?[0,`auto`]:void 0}var z9=function(e,t,n,r){var i=e.graphicalItems,a=e.tooltipAxis,o=L9(t,e);return n<0||!i||!i.length||n>=o.length?null:i.reduce(function(i,s){var c=s.props.data??t;c&&e.dataStartIndex+e.dataEndIndex!==0&&e.dataEndIndex-e.dataStartIndex>=n&&(c=c.slice(e.dataStartIndex,e.dataEndIndex+1));var l=a.dataKey&&!a.allowDuplicatedCategory?xR(c===void 0?o:c,a.dataKey,r):c&&c[n]||o[n];return l?[].concat(k9(i),[E1(s,l)]):i},[])},B9=function(e,t,n,r){var i=r||{x:e.chartX,y:e.chartY},a=Xoe(i,n),o=e.orderedTooltipTicks,s=e.tooltipAxis,c=e.tooltipTicks,l=q$(a,o,c,s);if(l>=0&&c){var u=c[l]&&c[l].value;return{activeTooltipIndex:l,activeLabel:u,activePayload:z9(e,t,l,u),activeCoordinate:Zoe(n,o,l,i)}}return null},Qoe=function(e,t){var n=t.axes,r=t.graphicalItems,i=t.axisType,a=t.axisIdKey,o=t.stackGroups,s=t.dataStartIndex,c=t.dataEndIndex,l=e.layout,u=e.children,d=e.stackOffset,f=n1(l,i);return n.reduce(function(t,n){var p=n.type.defaultProps===void 0?n.props:$($({},n.type.defaultProps),n.props),m=p.type,h=p.dataKey,g=p.allowDataOverflow,_=p.allowDuplicatedCategory,v=p.scale,y=p.ticks,b=p.includeHidden,x=p[a];if(t[x])return t;var S=L9(e.data,{graphicalItems:r.filter(function(e){return(a in e.props?e.props[a]:e.type.defaultProps?.[a])===x}),dataStartIndex:s,dataEndIndex:c}),C=S.length,w,T,E;Toe(p.domain,g,m)&&(w=C1(p.domain,null,g),f&&(m===`number`||v!==`auto`)&&(E=K$(S,h,`category`)));var D=R9(m);if(!w||w.length===0){var O=p.domain??D;if(h){if(w=K$(S,h,m),m===`category`&&f){var k=yR(w);_&&k?(T=w,w=(0,x8.default)(0,C)):_||(w=T1(O,w,n).reduce(function(e,t){return e.indexOf(t)>=0?e:[].concat(k9(e),[t])},[]))}else if(m===`category`)w=_?w.filter(function(e){return e!==``&&!(0,uR.default)(e)}):T1(O,w,n).reduce(function(e,t){return e.indexOf(t)>=0||t===``||(0,uR.default)(t)?e:[].concat(k9(e),[t])},[]);else if(m===`number`){var A=e1(S,r.filter(function(e){var t=a in e.props?e.props[a]:e.type.defaultProps?.[a],n=`hide`in e.props?e.props.hide:e.type.defaultProps?.hide;return t===x&&(b||!n)}),h,i,l);A&&(w=A)}f&&(m===`number`||v!==`auto`)&&(E=K$(S,h,`category`))}else w=f?(0,x8.default)(0,C):o&&o[x]&&o[x].hasStack&&m===`number`?d===`expand`?[0,1]:b1(o[x].stackGroups,s,c):t1(S,r.filter(function(e){var t=a in e.props?e.props[a]:e.type.defaultProps[a],n=`hide`in e.props?e.props.hide:e.type.defaultProps.hide;return t===x&&(b||!n)}),m,l,!0);if(m===`number`)w=u9(u,w,x,i,y),O&&(w=C1(O,w,g));else if(m===`category`&&O){var j=O;w.every(function(e){return j.indexOf(e)>=0})&&(w=j)}}return $($({},t),{},N9({},x,$($({},p),{},{axisType:i,domain:w,categoricalDomain:E,duplicateDomain:T,originalDomain:p.domain??D,isCategorical:f,layout:l})))},{})},$oe=function(e,t){var n=t.graphicalItems,r=t.Axis,i=t.axisType,a=t.axisIdKey,o=t.stackGroups,s=t.dataStartIndex,c=t.dataEndIndex,l=e.layout,u=e.children,d=L9(e.data,{graphicalItems:n,dataStartIndex:s,dataEndIndex:c}),f=d.length,p=n1(l,i),m=-1;return n.reduce(function(e,t){var h=(t.type.defaultProps===void 0?t.props:$($({},t.type.defaultProps),t.props))[a],g=R9(`number`);if(!e[h]){m++;var _;return p?_=(0,x8.default)(0,f):o&&o[h]&&o[h].hasStack?(_=b1(o[h].stackGroups,s,c),_=u9(u,_,h,i)):(_=C1(g,t1(d,n.filter(function(e){var t=a in e.props?e.props[a]:e.type.defaultProps?.[a],n=`hide`in e.props?e.props.hide:e.type.defaultProps?.hide;return t===h&&!n}),`number`,l),r.defaultProps.allowDataOverflow),_=u9(u,_,h,i)),$($({},e),{},N9({},h,$($({axisType:i},r.defaultProps),{},{hide:!0,orientation:(0,cR.default)(Joe,`${i}.${m%2}`,null),domain:_,originalDomain:g,isCategorical:p,layout:l})))}return e},{})},ese=function(e,t){var n=t.axisType,r=n===void 0?`xAxis`:n,i=t.AxisComp,a=t.graphicalItems,o=t.stackGroups,s=t.dataStartIndex,c=t.dataEndIndex,l=e.children,u=`${r}Id`,d=KR(l,i),f={};return d&&d.length?f=Qoe(e,{axes:d,graphicalItems:a,axisType:r,axisIdKey:u,stackGroups:o,dataStartIndex:s,dataEndIndex:c}):a&&a.length&&(f=$oe(e,{Axis:i,graphicalItems:a,axisType:r,axisIdKey:u,stackGroups:o,dataStartIndex:s,dataEndIndex:c})),f},tse=function(e){var t=vR(e),n=r1(t,!1,!0);return{tooltipTicks:n,orderedTooltipTicks:(0,BU.default)(n,function(e){return e.coordinate}),tooltipAxis:t,tooltipAxisBandSize:w1(t,n)}},V9=function(e){var t=e.children,n=e.defaultShowTooltip,r=qR(t,N8),i=0,a=0;return e.data&&e.data.length!==0&&(a=e.data.length-1),r&&r.props&&(r.props.startIndex>=0&&(i=r.props.startIndex),r.props.endIndex>=0&&(a=r.props.endIndex)),{chartX:0,chartY:0,dataStartIndex:i,dataEndIndex:a,activeTooltipIndex:-1,isTooltipActive:!!n}},nse=function(e){return!e||!e.length?!1:e.some(function(e){var t=HR(e&&e.type);return t&&t.indexOf(`Bar`)>=0})},H9=function(e){return e===`horizontal`?{numericAxisName:`yAxis`,cateAxisName:`xAxis`}:e===`vertical`?{numericAxisName:`xAxis`,cateAxisName:`yAxis`}:e===`centric`?{numericAxisName:`radiusAxis`,cateAxisName:`angleAxis`}:{numericAxisName:`angleAxis`,cateAxisName:`radiusAxis`}},rse=function(e,t){var n=e.props,r=e.graphicalItems,i=e.xAxisMap,a=i===void 0?{}:i,o=e.yAxisMap,s=o===void 0?{}:o,c=n.width,l=n.height,u=n.children,d=n.margin||{},f=qR(u,N8),p=qR(u,vU),m=Object.keys(s).reduce(function(e,t){var n=s[t],r=n.orientation;return!n.mirror&&!n.hide?$($({},e),{},N9({},r,e[r]+n.width)):e},{left:d.left||0,right:d.right||0}),h=$($({},Object.keys(a).reduce(function(e,t){var n=a[t],r=n.orientation;return!n.mirror&&!n.hide?$($({},e),{},N9({},r,(0,cR.default)(e,`${r}`)+n.height)):e},{top:d.top||0,bottom:d.bottom||0})),m),g=h.bottom;f&&(h.bottom+=f.props.height||N8.defaultProps.height),p&&t&&(h=Z$(h,r,n,t));var _=c-h.left-h.right,v=l-h.top-h.bottom;return $($({brushBottom:g},h),{},{width:Math.max(_,0),height:Math.max(v,0)})},ise=function(e,t){if(t===`xAxis`)return e[t].width;if(t===`yAxis`)return e[t].height},U9=function(e){var t=e.chartName,n=e.GraphicalChild,r=e.defaultTooltipEventType,i=r===void 0?`axis`:r,a=e.validateTooltipEventTypes,o=a===void 0?[`axis`]:a,s=e.axisComponents,c=e.legendContent,l=e.formatAxisMap,u=e.defaultProps,d=function(e,t){var n=t.graphicalItems,r=t.stackGroups,i=t.offset,a=t.updateId,o=t.dataStartIndex,c=t.dataEndIndex,l=e.barSize,u=e.layout,d=e.barGap,f=e.barCategoryGap,p=e.maxBarSize,m=H9(u),h=m.numericAxisName,g=m.cateAxisName,_=nse(n),v=[];return n.forEach(function(n,m){var y=L9(e.data,{graphicalItems:[n],dataStartIndex:o,dataEndIndex:c}),b=n.type.defaultProps===void 0?n.props:$($({},n.type.defaultProps),n.props),x=b.dataKey,S=b.maxBarSize,C=b[`${h}Id`],w=b[`${g}Id`],T=s.reduce(function(e,n){var r=t[`${n.axisType}Map`],i=b[`${n.axisType}Id`];!(r&&r[i]||n.axisType===`zAxis`)&&XQ(!1);var a=r[i];return $($({},e),{},N9(N9({},n.axisType,a),`${n.axisType}Ticks`,r1(a)))},{}),E=T[g],D=T[`${g}Ticks`],O=r&&r[C]&&r[C].hasStack&&v1(n,r[C].stackGroups),k=HR(n.type).indexOf(`Bar`)>=0,A=w1(E,D),j=[],M=_&&Y$({barSize:l,stackGroups:r,totalSize:ise(T,g)});if(k){var N=(0,uR.default)(S)?p:S,P=w1(E,D,!0)??N??0;j=X$({barGap:d,barCategoryGap:f,bandSize:P===A?A:P,sizeList:M[w],maxBarSize:N}),P!==A&&(j=j.map(function(e){return $($({},e),{},{position:$($({},e.position),{},{offset:e.position.offset-P/2})})}))}var F=n&&n.type&&n.type.getComposedData;F&&v.push({props:$($({},F($($({},T),{},{displayedData:y,props:e,dataKey:x,item:n,bandSize:A,barPosition:j,offset:i,stackedData:O,layout:u,dataStartIndex:o,dataEndIndex:c}))),{},N9(N9(N9({key:n.key||`item-${m}`},h,T[h]),g,T[g]),`animationId`,a)),childIndex:iz(n,e.children),item:n})}),v},f=function(e,r){var i=e.props,a=e.dataStartIndex,o=e.dataEndIndex,c=e.updateId;if(!JR({props:i}))return null;var u=i.children,f=i.layout,p=i.stackOffset,m=i.data,h=i.reverseStackOrder,g=H9(f),_=g.numericAxisName,v=g.cateAxisName,y=KR(u,n),b=p1(m,y,`${_}Id`,`${v}Id`,p,h),x=s.reduce(function(e,t){var n=`${t.axisType}Map`;return $($({},e),{},N9({},n,ese(i,$($({},t),{},{graphicalItems:y,stackGroups:t.axisType===_&&b,dataStartIndex:a,dataEndIndex:o}))))},{}),S=rse($($({},x),{},{props:i,graphicalItems:y}),r?.legendBBox);Object.keys(x).forEach(function(e){x[e]=l(i,x[e],S,e.replace(`Map`,``),t)});var C=x[`${v}Map`],w=tse(C);return $($({formattedGraphicalItems:d(i,$($({},x),{},{dataStartIndex:a,dataEndIndex:o,updateId:c,graphicalItems:y,stackGroups:b,offset:S})),graphicalItems:y,offset:S,stackGroups:b},w),x)},p=function(e){function n(e){var r;return Roe(this,n),r=Boe(this,n,[e]),N9(r,`eventEmitterSymbol`,Symbol(`rechartsEventEmitter`)),N9(r,`accessibilityManager`,new woe),N9(r,`handleLegendBBoxUpdate`,function(e){if(e){var t=r.state,n=t.dataStartIndex,i=t.dataEndIndex,a=t.updateId;r.setState($({legendBBox:e},f({props:r.props,dataStartIndex:n,dataEndIndex:i,updateId:a},$($({},r.state),{},{legendBBox:e}))))}}),N9(r,`handleReceiveSyncEvent`,function(e,t,n){if(r.props.syncId===e){if(n===r.eventEmitterSymbol&&typeof r.props.syncMethod!=`function`)return;r.applySyncEvent(t)}}),N9(r,`handleBrushChange`,function(e){var t=e.startIndex,n=e.endIndex;if(t!==r.state.dataStartIndex||n!==r.state.dataEndIndex){var i=r.state.updateId;r.setState(function(){return $({dataStartIndex:t,dataEndIndex:n},f({props:r.props,dataStartIndex:t,dataEndIndex:n,updateId:i},r.state))}),r.triggerSyncEvent({dataStartIndex:t,dataEndIndex:n})}}),N9(r,`handleMouseEnter`,function(e){var t=r.getMouseInfo(e);if(t){var n=$($({},t),{},{isTooltipActive:!0});r.setState(n),r.triggerSyncEvent(n);var i=r.props.onMouseEnter;(0,PR.default)(i)&&i(n,e)}}),N9(r,`triggeredAfterMouseMove`,function(e){var t=r.getMouseInfo(e),n=t?$($({},t),{},{isTooltipActive:!0}):{isTooltipActive:!1};r.setState(n),r.triggerSyncEvent(n);var i=r.props.onMouseMove;(0,PR.default)(i)&&i(n,e)}),N9(r,`handleItemMouseEnter`,function(e){r.setState(function(){return{isTooltipActive:!0,activeItem:e,activePayload:e.tooltipPayload,activeCoordinate:e.tooltipPosition||{x:e.cx,y:e.cy}}})}),N9(r,`handleItemMouseLeave`,function(){r.setState(function(){return{isTooltipActive:!1}})}),N9(r,`handleMouseMove`,function(e){e.persist(),r.throttleTriggeredAfterMouseMove(e)}),N9(r,`handleMouseLeave`,function(e){r.throttleTriggeredAfterMouseMove.cancel();var t={isTooltipActive:!1};r.setState(t),r.triggerSyncEvent(t);var n=r.props.onMouseLeave;(0,PR.default)(n)&&n(t,e)}),N9(r,`handleOuterEvent`,function(e){var t=rz(e),n=(0,cR.default)(r.props,`${t}`);t&&(0,PR.default)(n)&&n((/.*touch.*/i.test(t)?r.getMouseInfo(e.changedTouches[0]):r.getMouseInfo(e))??{},e)}),N9(r,`handleClick`,function(e){var t=r.getMouseInfo(e);if(t){var n=$($({},t),{},{isTooltipActive:!0});r.setState(n),r.triggerSyncEvent(n);var i=r.props.onClick;(0,PR.default)(i)&&i(n,e)}}),N9(r,`handleMouseDown`,function(e){var t=r.props.onMouseDown;(0,PR.default)(t)&&t(r.getMouseInfo(e),e)}),N9(r,`handleMouseUp`,function(e){var t=r.props.onMouseUp;(0,PR.default)(t)&&t(r.getMouseInfo(e),e)}),N9(r,`handleTouchMove`,function(e){e.changedTouches!=null&&e.changedTouches.length>0&&r.throttleTriggeredAfterMouseMove(e.changedTouches[0])}),N9(r,`handleTouchStart`,function(e){e.changedTouches!=null&&e.changedTouches.length>0&&r.handleMouseDown(e.changedTouches[0])}),N9(r,`handleTouchEnd`,function(e){e.changedTouches!=null&&e.changedTouches.length>0&&r.handleMouseUp(e.changedTouches[0])}),N9(r,`handleDoubleClick`,function(e){var t=r.props.onDoubleClick;(0,PR.default)(t)&&t(r.getMouseInfo(e),e)}),N9(r,`handleContextMenu`,function(e){var t=r.props.onContextMenu;(0,PR.default)(t)&&t(r.getMouseInfo(e),e)}),N9(r,`triggerSyncEvent`,function(e){r.props.syncId!==void 0&&d9.emit(f9,r.props.syncId,e,r.eventEmitterSymbol)}),N9(r,`applySyncEvent`,function(e){var t=r.props,n=t.layout,i=t.syncMethod,a=r.state.updateId,o=e.dataStartIndex,s=e.dataEndIndex;if(e.dataStartIndex!==void 0||e.dataEndIndex!==void 0)r.setState($({dataStartIndex:o,dataEndIndex:s},f({props:r.props,dataStartIndex:o,dataEndIndex:s,updateId:a},r.state)));else if(e.activeTooltipIndex!==void 0){var c=e.chartX,l=e.chartY,u=e.activeTooltipIndex,d=r.state,p=d.offset,m=d.tooltipTicks;if(!p)return;if(typeof i==`function`)u=i(m,e);else if(i===`value`){u=-1;for(var h=0;h=0){var D,O;if(c.dataKey&&!c.allowDuplicatedCategory){var k=typeof c.dataKey==`function`?E:`payload.${c.dataKey.toString()}`;D=xR(m,k,u),O=h&&g&&xR(g,k,u)}else D=m?.[l],O=h&&g&&g[l];if(S||x){var A=e.props.activeIndex===void 0?l:e.props.activeIndex;return[(0,_.cloneElement)(e,$($($({},i.props),w),{},{activeIndex:A})),null,null]}if(!(0,uR.default)(D))return[T].concat(k9(r.renderActivePoints({item:i,activePoint:D,basePoint:O,childIndex:l,isRange:h})))}else{var j=(r.getItemByXY(r.state.activeCoordinate)??{graphicalItem:T}).graphicalItem,M=j.item,N=M===void 0?e:M,P=j.childIndex;return[(0,_.cloneElement)(N,$($($({},i.props),w),{},{activeIndex:P})),null,null]}return h?[T,null,null]:[T,null]}),N9(r,`renderCustomized`,function(e,t,n){return(0,_.cloneElement)(e,$($({key:`recharts-customized-${n}`},r.props),r.state))}),N9(r,`renderMap`,{CartesianGrid:{handler:I9,once:!0},ReferenceArea:{handler:r.renderReferenceElement},ReferenceLine:{handler:I9},ReferenceDot:{handler:r.renderReferenceElement},XAxis:{handler:I9},YAxis:{handler:I9},Brush:{handler:r.renderBrush,once:!0},Bar:{handler:r.renderGraphicChild},Line:{handler:r.renderGraphicChild},Area:{handler:r.renderGraphicChild},Radar:{handler:r.renderGraphicChild},RadialBar:{handler:r.renderGraphicChild},Scatter:{handler:r.renderGraphicChild},Pie:{handler:r.renderGraphicChild},Funnel:{handler:r.renderGraphicChild},Tooltip:{handler:r.renderCursor,once:!0},PolarGrid:{handler:r.renderPolarGrid,once:!0},PolarAngleAxis:{handler:r.renderPolarAxis},PolarRadiusAxis:{handler:r.renderPolarAxis},Customized:{handler:r.renderCustomized}}),r.clipPathId=`${e.id??gR(`recharts`)}-clip`,r.throttleTriggeredAfterMouseMove=(0,tG.default)(r.triggeredAfterMouseMove,e.throttleDelay??1e3/60),r.state={},r}return Uoe(n,e),zoe(n,[{key:`componentDidMount`,value:function(){this.addListener(),this.accessibilityManager.setDetails({container:this.container,offset:{left:this.props.margin.left??0,top:this.props.margin.top??0},coordinateList:this.state.tooltipTicks,mouseHandlerCallback:this.triggeredAfterMouseMove,layout:this.props.layout}),this.displayDefaultTooltip()}},{key:`displayDefaultTooltip`,value:function(){var e=this.props,t=e.children,n=e.data,r=e.height,i=e.layout,a=qR(t,YW);if(a){var o=a.props.defaultIndex;if(!(typeof o!=`number`||o<0||o>this.state.tooltipTicks.length-1)){var s=this.state.tooltipTicks[o]&&this.state.tooltipTicks[o].value,c=z9(this.state,n,o,s),l=this.state.tooltipTicks[o].coordinate,u=(this.state.offset.top+r)/2,d=i===`horizontal`?{x:l,y:u}:{y:l,x:u},f=this.state.formattedGraphicalItems.find(function(e){return e.item.type.name===`Scatter`});f&&(d=$($({},d),f.props.points[o].tooltipPosition),c=f.props.points[o].tooltipPayload);var p={activeTooltipIndex:o,isTooltipActive:!0,activeLabel:s,activePayload:c,activeCoordinate:d};this.setState(p),this.renderCursor(a),this.accessibilityManager.setIndex(o)}}}},{key:`getSnapshotBeforeUpdate`,value:function(e,t){return this.props.accessibilityLayer?(this.state.tooltipTicks!==t.tooltipTicks&&this.accessibilityManager.setDetails({coordinateList:this.state.tooltipTicks}),this.props.layout!==e.layout&&this.accessibilityManager.setDetails({layout:this.props.layout}),this.props.margin!==e.margin&&this.accessibilityManager.setDetails({offset:{left:this.props.margin.left??0,top:this.props.margin.top??0}}),null):null}},{key:`componentDidUpdate`,value:function(e){ez([qR(e.children,YW)],[qR(this.props.children,YW)])||this.displayDefaultTooltip()}},{key:`componentWillUnmount`,value:function(){this.removeListener(),this.throttleTriggeredAfterMouseMove.cancel()}},{key:`getTooltipEventType`,value:function(){var e=qR(this.props.children,YW);if(e&&typeof e.props.shared==`boolean`){var t=e.props.shared?`axis`:`item`;return o.indexOf(t)>=0?t:i}return i}},{key:`getMouseInfo`,value:function(e){if(!this.container)return null;var t=this.container,n=t.getBoundingClientRect(),r=OG(n),i={chartX:Math.round(e.pageX-r.left),chartY:Math.round(e.pageY-r.top)},a=n.width/t.offsetWidth||1,o=this.inRange(i.chartX,i.chartY,a);if(!o)return null;var s=this.state,c=s.xAxisMap,l=s.yAxisMap,u=this.getTooltipEventType(),d=B9(this.state,this.props.data,this.props.layout,o);if(u!==`axis`&&c&&l){var f=vR(c).scale,p=vR(l).scale,m=f&&f.invert?f.invert(i.chartX):null,h=p&&p.invert?p.invert(i.chartY):null;return $($({},i),{},{xValue:m,yValue:h},d)}return d?$($({},i),d):null}},{key:`inRange`,value:function(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,r=this.props.layout,i=e/n,a=t/n;if(r===`horizontal`||r===`vertical`){var o=this.state.offset;return i>=o.left&&i<=o.left+o.width&&a>=o.top&&a<=o.top+o.height?{x:i,y:a}:null}var s=this.state,c=s.angleAxisMap,l=s.radiusAxisMap;if(c&&l){var u=vR(c);return B1({x:i,y:a},u)}return null}},{key:`parseEventsOfWrapper`,value:function(){var e=this.props.children,t=this.getTooltipEventType(),n=qR(e,YW),r={};return n&&t===`axis`&&(r=n.props.trigger===`click`?{onClick:this.handleClick}:{onMouseEnter:this.handleMouseEnter,onDoubleClick:this.handleDoubleClick,onMouseMove:this.handleMouseMove,onMouseLeave:this.handleMouseLeave,onTouchMove:this.handleTouchMove,onTouchStart:this.handleTouchStart,onTouchEnd:this.handleTouchEnd,onContextMenu:this.handleContextMenu}),$($({},jR(this.props,this.handleOuterEvent)),r)}},{key:`addListener`,value:function(){d9.on(f9,this.handleReceiveSyncEvent)}},{key:`removeListener`,value:function(){d9.removeListener(f9,this.handleReceiveSyncEvent)}},{key:`filterFormatItem`,value:function(e,t,n){for(var r=this.state.formattedGraphicalItems,i=0,a=r.length;i{let[i,a]=(0,_.useState)([]),[o,s]=(0,_.useState)([]),c=(0,_.useRef)(0),{baseUrl:l,fetchWithHeaders:u}=Tl();(0,_.useEffect)(()=>{let t=!1;return bf(l,u,e).then(e=>{if(t||e.length===0)return;let n=e.filter(e=>e.loss!=null).map(e=>({step:e.step,loss:e.loss})).slice(-2e3),r=e.filter(e=>e.lr!=null).map(e=>({step:e.step,lr:e.lr})).slice(-2e3);a(n),s(r),c.current=e[e.length-1]?.step??0}).catch(()=>{}),()=>{t=!0}},[l,u,e]),(0,_.useEffect)(()=>{let e=t.current_step;if(e0&&t.current_loss!=null){let n=t.current_loss;a(t=>{let r=t[t.length-1];return r&&r.step===e?t:[...t,{step:e,loss:n}].slice(-2e3)})}if(e>0&&t.current_lr!=null){let n=t.current_lr;s(t=>{let r=t[t.length-1];return r&&r.step===e?t:[...t,{step:e,lr:n}].slice(-2e3)})}},[t.current_step,t.current_loss,t.current_lr]);let d=n(),f=t.training_active&&t.total_steps===0,p=f?`Training starting…`:`${t.current_step.toLocaleString()} / ${t.total_steps.toLocaleString()}`,m=t.eta_seconds==null?`—`:r(t.eta_seconds);return(0,V.jsxs)(`div`,{className:`space-y-6`,children:[(0,V.jsx)(_b,{className:`bg-slate-800/50 border-slate-700 rounded-xl`,children:(0,V.jsxs)(xb,{className:`p-6`,children:[(0,V.jsxs)(`div`,{className:`flex items-baseline justify-between mb-3`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,V.jsx)(`div`,{className:`flex h-9 w-9 items-center justify-center rounded-lg bg-blue-500/20 text-blue-400`,children:(0,V.jsx)(is,{className:`w-5 h-5`})}),(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`h3`,{className:`text-sm text-slate-400`,children:`Progress`}),(0,V.jsx)(`div`,{className:`text-base font-semibold text-white`,children:p})]})]}),(0,V.jsxs)(`div`,{className:`flex items-center gap-2 text-slate-300`,children:[(0,V.jsx)(bs,{className:`w-4 h-4 text-purple-400`}),(0,V.jsxs)(`span`,{className:`text-sm`,children:[`ETA `,(0,V.jsx)(`span`,{className:`font-semibold text-white`,children:m})]})]})]}),(0,V.jsxs)(`div`,{className:`relative h-8 w-full overflow-hidden rounded-md bg-slate-900 border border-slate-700`,children:[(0,V.jsx)(`div`,{className:`h-full bg-gradient-to-r from-blue-500 to-sky-400 transition-[width] duration-500`,style:{width:`${d}%`}}),(0,V.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center font-semibold text-white text-sm tabular-nums drop-shadow`,children:f?`warming up…`:`${d.toFixed(1)}%`})]})]})}),(0,V.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-2 gap-6`,children:[(0,V.jsxs)(_b,{className:`bg-slate-800/50 border-slate-700 rounded-xl`,children:[(0,V.jsx)(vb,{className:`pb-2`,children:(0,V.jsxs)(yb,{className:`flex items-center gap-3 text-white text-base`,children:[(0,V.jsx)(`div`,{className:`flex h-8 w-8 items-center justify-center rounded-lg bg-green-500/20 text-green-400`,children:(0,V.jsx)(hs,{className:`w-4 h-4`})}),(0,V.jsxs)(`span`,{children:[`Loss`,` `,(0,V.jsxs)(`span`,{className:`text-slate-400 text-sm font-normal`,children:[`(`,t.current_loss?.toFixed(4)??`—`,`)`]})]})]})}),(0,V.jsx)(xb,{className:`pt-0`,children:(0,V.jsx)(`div`,{className:`h-48`,children:i.length===0?(0,V.jsx)(`div`,{className:`flex h-full items-center justify-center text-slate-500 text-sm`,children:`Waiting for first metric tick…`}):(0,V.jsx)(mG,{width:`100%`,height:`100%`,children:(0,V.jsxs)(W9,{data:i,margin:{top:8,right:12,left:0,bottom:0},children:[(0,V.jsx)(Z7,{dataKey:`step`,tick:{fill:`#94a3b8`,fontSize:11},stroke:`#475569`}),(0,V.jsx)(s9,{tick:{fill:`#94a3b8`,fontSize:11},stroke:`#475569`,width:48}),(0,V.jsx)(YW,{contentStyle:{background:`#1e293b`,border:`1px solid #475569`,borderRadius:8},labelStyle:{color:`#cbd5e1`},itemStyle:{color:`#34d399`},formatter:e=>e.toFixed(4)}),(0,V.jsx)(k7,{type:`monotone`,dataKey:`loss`,stroke:`#34d399`,strokeWidth:2,dot:!1,isAnimationActive:!1})]})})})})]}),(0,V.jsxs)(_b,{className:`bg-slate-800/50 border-slate-700 rounded-xl`,children:[(0,V.jsx)(vb,{className:`pb-2`,children:(0,V.jsxs)(yb,{className:`flex items-center gap-3 text-white text-base`,children:[(0,V.jsx)(`div`,{className:`flex h-8 w-8 items-center justify-center rounded-lg bg-orange-500/20 text-orange-400`,children:(0,V.jsx)(is,{className:`w-4 h-4`})}),(0,V.jsxs)(`span`,{children:[`Learning Rate`,` `,(0,V.jsxs)(`span`,{className:`text-slate-400 text-sm font-normal`,children:[`(`,t.current_lr?.toExponential(2)??`—`,`)`]})]})]})}),(0,V.jsx)(xb,{className:`pt-0`,children:(0,V.jsx)(`div`,{className:`h-48`,children:o.length===0?(0,V.jsx)(`div`,{className:`flex h-full items-center justify-center text-slate-500 text-sm`,children:`Waiting for first metric tick…`}):(0,V.jsx)(mG,{width:`100%`,height:`100%`,children:(0,V.jsxs)(W9,{data:o,margin:{top:8,right:12,left:0,bottom:0},children:[(0,V.jsx)(Z7,{dataKey:`step`,tick:{fill:`#94a3b8`,fontSize:11},stroke:`#475569`}),(0,V.jsx)(s9,{tick:{fill:`#94a3b8`,fontSize:11},stroke:`#475569`,width:48,tickFormatter:e=>e.toExponential(0)}),(0,V.jsx)(YW,{contentStyle:{background:`#1e293b`,border:`1px solid #475569`,borderRadius:8},labelStyle:{color:`#cbd5e1`},itemStyle:{color:`#fb923c`},formatter:e=>e.toExponential(2)}),(0,V.jsx)(k7,{type:`monotone`,dataKey:`lr`,stroke:`#fb923c`,strokeWidth:2,dot:!1,isAnimationActive:!1})]})})})})]})]})]})},sse=({logs:e,logContainerRef:t})=>(0,V.jsxs)(_b,{className:`bg-slate-800/50 border-slate-700 rounded-xl`,children:[(0,V.jsx)(vb,{children:(0,V.jsxs)(yb,{className:`flex items-center gap-3 text-white`,children:[(0,V.jsx)(`div`,{className:`flex h-10 w-10 items-center justify-center rounded-lg bg-slate-700`,children:(0,V.jsx)(ks,{className:`w-5 h-5 text-sky-400`})}),`Training Logs`]})}),(0,V.jsx)(xb,{children:(0,V.jsx)(`div`,{ref:t,className:`bg-slate-900 rounded-lg p-4 h-96 overflow-y-auto font-mono text-sm border border-slate-700`,children:e.length===0?(0,V.jsx)(`div`,{className:`text-slate-500 py-8`,children:`No training logs yet. Start training to see output.`}):e.map((e,t)=>(0,V.jsxs)(`div`,{className:`text-slate-300 break-words whitespace-pre-wrap`,children:[(0,V.jsx)(`span`,{className:`text-slate-500 mr-2 select-none`,children:new Date(e.timestamp*1e3).toLocaleTimeString()}),e.message]},t))})})]}),cse=({installHint:e})=>{let t=uL(`system/training-extra`);return(0,V.jsx)(`div`,{className:`max-w-3xl mx-auto`,children:(0,V.jsxs)(_b,{className:`bg-slate-800/50 border-slate-700 rounded-xl`,children:[(0,V.jsx)(vb,{children:(0,V.jsxs)(yb,{className:`flex items-center gap-3 text-white`,children:[(0,V.jsx)(fL,{state:t.state}),dL(t.state,`Training Extra Not Installed`)]})}),(0,V.jsx)(xb,{className:`space-y-4`,children:(0,V.jsx)(pL,{state:t.state,error:t.error,logs:t.logs,logBoxRef:t.logBoxRef,onInstall:t.handleInstall,onRetry:t.handleRetry,installHint:e,packageName:`accelerate`,idleTitle:`Training Extra Not Installed`,idleDescription:(0,V.jsxs)(V.Fragment,{children:[`Training requires the`,` `,(0,V.jsx)(`code`,{className:`px-1 py-0.5 rounded bg-slate-900 text-sky-300`,children:`accelerate`}),` `,`package, which isn't installed in this environment. Install it to enable the Training page.`]}),doneDescription:(0,V.jsx)(mL,{purpose:`training`})})})]})})},lse=({open:e,onOpenChange:t,policyType:n,packageName:r,installTarget:i,installHint:a})=>{let o=uL(`system/policy-extra/${n}`,e),s=`${n.toUpperCase()} needs an extra package`;return(0,V.jsx)(nf,{open:e,onOpenChange:t,children:(0,V.jsxs)(of,{className:`bg-slate-800 border-slate-700 text-white max-w-2xl`,children:[(0,V.jsxs)(sf,{children:[(0,V.jsxs)(lf,{className:`flex items-center gap-3 text-white`,children:[(0,V.jsx)(fL,{state:o.state}),dL(o.state,s)]}),(0,V.jsxs)(uf,{className:`sr-only`,children:[`Install `,i,` to train `,n,`.`]})]}),(0,V.jsx)(`div`,{className:`space-y-4`,children:(0,V.jsx)(pL,{state:o.state,error:o.error,logs:o.logs,logBoxRef:o.logBoxRef,onInstall:o.handleInstall,onRetry:o.handleRetry,installHint:a,packageName:i,idleTitle:s,idleDescription:(0,V.jsxs)(V.Fragment,{children:[`Training a `,(0,V.jsx)(`span`,{className:`font-semibold`,children:n}),` policy needs the`,` `,(0,V.jsx)(`code`,{className:`px-1 py-0.5 rounded bg-slate-900 text-sky-300`,children:r}),` `,`package (installed via`,` `,(0,V.jsx)(`code`,{className:`px-1 py-0.5 rounded bg-slate-900 text-sky-300`,children:i}),`), which isn't in this environment yet. Install it to train this policy.`]}),doneDescription:(0,V.jsx)(mL,{purpose:`${n} training`})})})]})})},use=()=>{let{auth:e,refetch:t}=Ol(),{baseUrl:n,fetchWithHeaders:r}=Tl(),[i,a]=(0,_.useState)(``),[o,s]=(0,_.useState)(!1),[c,l]=(0,_.useState)(null);if(e.status===`authenticated`||e.status===`loading`)return null;let u=async()=>{let e=i.trim();if(e){s(!0),l(null);try{let i=await r(`${n}/hf-auth/login`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({token:e})});if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(e.detail||`HTTP ${i.status}`)}a(``),await t()}catch(e){l(e instanceof Error?e.message:String(e))}finally{s(!1)}}};return(0,V.jsx)(`div`,{className:`bg-amber-950/40 border border-amber-700/60 rounded-lg p-4 mb-6`,children:(0,V.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,V.jsx)(ms,{className:`w-5 h-5 text-amber-400 flex-shrink-0 mt-0.5`}),(0,V.jsxs)(`div`,{className:`flex-1 space-y-3`,children:[(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`p`,{className:`text-sm text-amber-100 font-medium`,children:`Hugging Face access required for cloud training`}),(0,V.jsxs)(`p`,{className:`text-xs text-amber-200/80 mt-1`,children:[`Create a token at`,` `,(0,V.jsxs)(`a`,{href:`https://huggingface.co/settings/tokens`,target:`_blank`,rel:`noreferrer`,className:`underline hover:text-amber-50 inline-flex items-center gap-1`,children:[`huggingface.co/settings/tokens`,(0,V.jsx)(Es,{className:`w-3 h-3`})]}),` `,`with `,(0,V.jsx)(`span`,{className:`font-mono`,children:`Write`}),` access (so trained policies can upload to your account), then paste it below.`]})]}),(0,V.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),u()},className:`flex gap-2`,children:[(0,V.jsx)(k_,{type:`password`,placeholder:`hf_...`,value:i,onChange:e=>a(e.target.value),className:`bg-slate-900 border-slate-600 text-white placeholder:text-slate-500`,disabled:o,autoComplete:`off`}),(0,V.jsx)(q,{type:`submit`,disabled:o||!i.trim(),className:`bg-amber-600 hover:bg-amber-700 text-white`,children:o?(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Ms,{className:`w-4 h-4 mr-2 animate-spin`}),`Saving…`]}):`Save token`})]}),c&&(0,V.jsx)(`p`,{className:`text-xs text-red-300`,children:c})]})]})})},dse=1e3,G9=5e3;function fse(e,t){return e?{training_active:e.state===`running`,current_step:e.metrics.current_step,total_steps:e.metrics.total_steps,current_loss:e.metrics.current_loss??void 0,current_lr:e.metrics.current_lr??void 0,grad_norm:e.metrics.grad_norm??void 0,eta_seconds:e.metrics.eta_seconds??void 0,available_controls:{stop_training:e.state===`running`,pause_training:!1,resume_training:!1}}:{training_active:t,current_step:0,total_steps:0,available_controls:{stop_training:!1,pause_training:!1,resume_training:!1}}}function pse(e){return{target:e.target,dataset_repo_id:e.dataset_repo_id,policy_type:e.policy_type,steps:e.steps,batch_size:e.batch_size,seed:e.seed,num_workers:e.num_workers,log_freq:e.log_freq,save_freq:e.save_freq,save_checkpoint:e.save_checkpoint,resume:e.resume,wandb_enable:e.wandb_enable,wandb_project:e.wandb_project,wandb_entity:e.wandb_entity,wandb_notes:e.wandb_notes,wandb_mode:e.wandb_mode,wandb_disable_artifact:e.wandb_disable_artifact,policy_device:e.policy_device,policy_use_amp:e.policy_use_amp,optimizer_type:e.optimizer_type,optimizer_lr:e.optimizer_lr,optimizer_weight_decay:e.optimizer_weight_decay,optimizer_grad_clip_norm:e.optimizer_grad_clip_norm,use_policy_training_preset:e.use_policy_training_preset,dataset_image_transforms_enable:e.dataset_image_transforms_enable,...e.policy_type===`groot`?{policy_base_model_path:e.policy_base_model_path,policy_embodiment_tag:e.policy_embodiment_tag,policy_chunk_size:e.policy_chunk_size,policy_n_action_steps:e.policy_n_action_steps,policy_use_relative_actions:e.policy_use_relative_actions,policy_relative_exclude_joints:e.policy_relative_exclude_joints,policy_use_bf16:e.policy_use_bf16}:{}}}var mse=()=>{let{baseUrl:e,fetchWithHeaders:t}=Tl(),{auth:n}=Ol(),{toast:r}=$i(),i=mt(),[a,o]=(0,_.useState)({target:{runner:`local`},dataset_repo_id:dt().state?.datasetRepoId??``,policy_type:`act`,steps:1e4,batch_size:8,seed:1e3,num_workers:4,log_freq:250,save_freq:1e3,save_checkpoint:!0,resume:!1,wandb_enable:!1,wandb_mode:`online`,wandb_disable_artifact:!1,policy_device:`cuda`,policy_use_amp:!1,optimizer_type:`adam`,use_policy_training_preset:!0}),[s,c]=(0,_.useState)([]),[l,u]=(0,_.useState)(!0),[d,f]=(0,_.useState)(null),[p,m]=(0,_.useState)(`pip install accelerate`),[h,g]=(0,_.useState)(!1),[v,y]=(0,_.useState)(!1),[b,x]=(0,_.useState)(null),[S,C]=(0,_.useState)(!1),[w,T]=(0,_.useState)([]),[E,D]=(0,_.useState)(!0);(0,_.useEffect)(()=>{u(!0),mf(e,t).then(c).catch(()=>c([])).finally(()=>u(!1))},[e,t]),(0,_.useEffect)(()=>{t(`${e}/system/training-extra`).then(e=>e.json()).then(e=>{f(e.available),m(e.install_hint)}).catch(()=>f(!0))},[e,t]),(0,_.useEffect)(()=>{gf(e,t,200).then(e=>g(e.some(e=>e.runner===`local`&&e.state===`running`))).catch(()=>g(!1))},[e,t]),(0,_.useEffect)(()=>{D(!0),Ef(e,t).then(e=>{C(e.authenticated),T(e.flavors)}).catch(()=>{C(!1),T([])}).finally(()=>D(!1))},[e,t,n.status]);let O=(e,t)=>{o(n=>({...n,[e]:t}))},k=async()=>{if(!a.dataset_repo_id.trim()){r({title:`Error`,description:`Dataset repository ID is required`,variant:`destructive`});return}if(a.target.runner===`local`)try{let n=await t(`${e}/system/policy-extra/${a.policy_type}`);if(n.ok){let e=await n.json();if(e.needs_extra&&!e.available){x({policyType:a.policy_type,packageName:e.package,installTarget:e.install_target,installHint:e.install_hint});return}}}catch{}y(!0);try{let n=await xf(e,t,pse(a));r({title:`Training Started`,description:n.name}),i(`/training/${n.id}`)}catch(n){r({title:`Error`,description:n instanceof Error?n.message:String(n),variant:`destructive`}),gf(e,t,200).then(e=>g(e.some(e=>e.runner===`local`&&e.state===`running`))).catch(()=>{})}finally{y(!1)}};if(d===null)return(0,V.jsx)(`div`,{className:`min-h-screen bg-slate-900 text-white p-4`,children:(0,V.jsxs)(`div`,{className:`max-w-7xl mx-auto`,children:[(0,V.jsx)(cL,{}),(0,V.jsxs)(`div`,{className:`flex items-center justify-center py-24 text-slate-400`,children:[(0,V.jsx)(Ms,{className:`w-6 h-6 animate-spin mr-3`}),`Checking training environment…`]})]})});if(d===!1)return(0,V.jsx)(`div`,{className:`min-h-screen bg-slate-900 text-white p-4`,children:(0,V.jsxs)(`div`,{className:`max-w-7xl mx-auto`,children:[(0,V.jsx)(cL,{}),(0,V.jsx)(cse,{installHint:p})]})});let A=a.target.runner===`hf_cloud`,j=a.target.runner===`hf_cloud`&&!a.target.flavor,M=a.target.runner===`local`&&h,N=v||!a.dataset_repo_id.trim()||M||A&&!S||j,P=M?`Another local training is already running`:A&&!S?`Log in to Hugging Face to use cloud compute`:j?`Select a hardware flavor`:void 0;return(0,V.jsxs)(`div`,{className:`min-h-screen bg-slate-900 text-white p-4`,children:[(0,V.jsxs)(`div`,{className:`max-w-7xl mx-auto`,children:[(0,V.jsx)(cL,{}),(0,V.jsx)(use,{}),(0,V.jsx)(xre,{config:a,updateConfig:O,datasets:s,datasetsLoading:l,authenticated:S,flavors:w,hardwareLoading:E}),(0,V.jsx)(`div`,{className:`max-w-3xl mx-auto mt-6 flex justify-end`,children:(()=>{let e=(0,V.jsx)(q,{onClick:k,disabled:N,size:`lg`,className:`bg-green-500 hover:bg-green-600 text-white font-semibold px-6`,children:v?(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Ms,{className:`w-5 h-5 mr-2 animate-spin`}),` Starting…`]}):(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Ls,{className:`w-5 h-5 mr-2`}),` Start Training`]})});return P?(0,V.jsxs)(Ih,{children:[(0,V.jsx)(Lh,{asChild:!0,children:(0,V.jsx)(`span`,{tabIndex:0,children:e})}),(0,V.jsx)(Rh,{children:P})]}):e})()})]}),b&&(0,V.jsx)(lse,{open:!!b,onOpenChange:e=>!e&&x(null),policyType:b.policyType,packageName:b.packageName,installTarget:b.installTarget,installHint:b.installHint})]})},hse=({jobId:e})=>{let{baseUrl:t,fetchWithHeaders:n}=Tl(),{toast:r}=$i(),i=mt(),{selectedRecord:a}=Wb(),[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(null),[u,d]=(0,_.useState)([]),f=(0,_.useRef)(null),[p,m]=(0,_.useState)([]),[h,g]=(0,_.useState)(null),[v,y]=(0,_.useState)(!1);(0,_.useEffect)(()=>{let r=!1;return yf(t,n,e).then(e=>{!r&&e.length>0&&d(e)}).catch(()=>{}),()=>{r=!0}},[t,n,e]);let b=(0,_.useRef)(o?.state);b.current=o?.state,(0,_.useEffect)(()=>{let r=!1,i=()=>{Cb(t,n,e).then(e=>{if(!r)if(m(e),e.length>0){let t=e[e.length-1].step;g(n=>n!=null&&e.some(e=>e.step===n)?n:t)}else g(null)}).catch(()=>{r||(m([]),g(null))})};i();let a=setInterval(()=>{r||b.current&&b.current!==`running`||i()},5e3);return()=>{r=!0,clearInterval(a)}},[t,n,e]),(0,_.useEffect)(()=>{let r=!1,i=async()=>{try{let i=await _f(t,n,e);if(r)return;if(s(i),i.state===`running`){let i=await vf(t,n,e);!r&&i.length>0&&d(e=>{let t=[...e,...i];return t.length>G9?t.slice(t.length-G9):t})}}catch(e){r||l(e instanceof Error?e.message:String(e))}};i();let a=setInterval(()=>{r||b.current&&b.current!==`running`||i()},dse);return()=>{r=!0,clearInterval(a)}},[t,n,e]),(0,_.useEffect)(()=>{f.current&&(f.current.scrollTop=f.current.scrollHeight)},[u]);let x=e=>{let t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=Math.floor(e%60);return`${t.toString().padStart(2,`0`)}:${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`},S=()=>!o||o.metrics.total_steps===0?0:o.metrics.current_step/o.metrics.total_steps*100,C=async()=>{if(o&&window.confirm(`Stop this run?`))try{s(await Cf(t,n,o.id)),r({title:`Stopping…`})}catch(e){r({title:`Stop failed`,description:e instanceof Error?e.message:String(e),variant:`destructive`})}},w=async()=>{if(o&&window.confirm(`Delete this run? This wipes the output directory.`))try{await wf(t,n,o.id),r({title:`Job removed`}),i(`/`)}catch(e){r({title:`Delete failed`,description:e instanceof Error?e.message:String(e),variant:`destructive`})}};if(c&&!o)return(0,V.jsx)(`div`,{className:`min-h-screen bg-slate-900 text-white p-4`,children:(0,V.jsxs)(`div`,{className:`max-w-7xl mx-auto space-y-4`,children:[(0,V.jsxs)(q,{variant:`ghost`,onClick:()=>i(`/`),className:`text-slate-400`,children:[(0,V.jsx)(as,{className:`w-4 h-4 mr-2`}),` Back to Jobs`]}),(0,V.jsxs)(`p`,{className:`text-red-300`,children:[`Couldn't load job `,e,`: `,c]})]})});if(!o)return(0,V.jsx)(`div`,{className:`min-h-screen bg-slate-900 text-white p-4`,children:(0,V.jsxs)(`div`,{className:`max-w-7xl mx-auto flex items-center justify-center py-24 text-slate-400`,children:[(0,V.jsx)(Ms,{className:`w-6 h-6 animate-spin mr-3`}),` Loading job…`]})});let T=o.state===`running`;return(0,V.jsx)(`div`,{className:`min-h-screen bg-slate-900 text-white p-4`,children:(0,V.jsxs)(`div`,{className:`max-w-7xl mx-auto space-y-6`,children:[(0,V.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,V.jsxs)(q,{variant:`ghost`,onClick:()=>i(`/`),className:`text-slate-400 hover:text-white`,children:[(0,V.jsx)(as,{className:`w-4 h-4 mr-2`}),` Jobs`]}),(0,V.jsxs)(`div`,{children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,V.jsx)(`h1`,{className:`text-xl font-semibold text-white`,children:o.name}),o.runner===`hf_cloud`?(0,V.jsxs)(`span`,{className:`text-xs px-2 py-0.5 rounded bg-amber-900/40 text-amber-200 border border-amber-700`,children:[`HF · `,o.hf_flavor??`cloud`]}):(0,V.jsx)(`span`,{className:`text-xs px-2 py-0.5 rounded bg-slate-700 text-slate-200 border border-slate-600`,children:`Local`}),o.runner===`hf_cloud`&&o.hf_repo_id&&o.state===`done`&&(0,V.jsx)(`a`,{href:`https://huggingface.co/${o.hf_repo_id}`,target:`_blank`,rel:`noreferrer`,className:`text-xs text-amber-300 hover:text-amber-200 underline`,children:`View on Hub ↗`}),o.wandb_run_url&&(0,V.jsx)(`a`,{href:o.wandb_run_url,target:`_blank`,rel:`noreferrer`,className:`text-xs text-yellow-300 hover:text-yellow-200 underline`,children:`View on W&B ↗`})]}),(0,V.jsxs)(`p`,{className:`text-xs text-slate-400`,children:[o.state,o.error_message?` — ${o.error_message}`:``]})]})]}),T?(0,V.jsxs)(q,{onClick:C,className:`bg-red-500 hover:bg-red-600 text-white`,children:[(0,V.jsx)(Js,{className:`w-4 h-4 mr-2`}),` Stop`]}):(0,V.jsxs)(q,{onClick:w,variant:`ghost`,className:`text-slate-400 hover:text-white`,children:[(0,V.jsx)(Xs,{className:`w-4 h-4 mr-2`}),` Delete`]})]}),(0,V.jsx)(ose,{jobId:e,trainingStatus:fse(o,!1),getProgressPercentage:S,formatTime:x}),(0,V.jsxs)(`div`,{className:`bg-slate-800/40 border border-slate-700 rounded-lg p-4 flex items-center gap-3`,children:[(0,V.jsx)(`span`,{className:`text-sm font-semibold text-slate-300`,children:`Run inference`}),p.length===0?(0,V.jsx)(`span`,{className:`text-xs text-slate-500`,children:`No checkpoints yet — wait for the first save.`}):(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Tb,{checkpoints:p,selectedStep:h,onChange:g}),(0,V.jsxs)(q,{onClick:()=>y(!0),disabled:h==null,className:`bg-green-500 hover:bg-green-600 text-white`,children:[(0,V.jsx)(Ls,{className:`w-4 h-4 mr-2`}),`Run on robot`]})]})]}),(0,V.jsx)(zb,{open:v,onOpenChange:y,robot:a,jobId:e,initialStep:h}),(0,V.jsx)(sse,{logs:u,logContainerRef:f})]})})},K9=()=>{let{jobId:e}=gt();return e?(0,V.jsx)(hse,{jobId:e}):(0,V.jsx)(mse,{})},gse=1e3;function q9(e){let t=Math.max(0,Math.floor(e)),n=Math.floor(t/60),r=t%60;return`${String(n).padStart(2,`0`)}:${String(r).padStart(2,`0`)}`}var _se=()=>{let e=mt(),{baseUrl:t,fetchWithHeaders:n}=Tl(),{toast:r}=$i(),[i,a]=(0,_.useState)(null),[o,s]=(0,_.useState)(!1),c=(0,_.useRef)(!1),l=(0,_.useRef)(!1);(0,_.useEffect)(()=>{let i=!1,o=async()=>{try{await Fb(t,n)}catch{}},s=async()=>{try{let s=await Ib(t,n);if(i)return;if(a(s),!s.inference_active&&!c.current){c.current=!0,s.exited&&r({title:`Inference finished`,description:s.exit_code===0?`Run completed.`:`Exit code ${s.exit_code}. See ${s.log_path}.`,variant:s.exit_code===0?`default`:`destructive`}),e(`/`);return}s.inference_active&&s.rollout_started_at!=null&&s.duration_s!=null&&s.duration_s>0&&s.rollout_elapsed_s>s.duration_s+10&&!l.current&&(l.current=!0,r({title:`Inference seems hung`,description:`Rollout past duration by ${Math.round(s.rollout_elapsed_s-s.duration_s)}s. Stopping.`,variant:`destructive`}),o())}catch(e){i||r({title:`Lost connection to backend`,description:e instanceof Error?e.message:String(e),variant:`destructive`})}};s();let u=setInterval(s,gse);return()=>{i=!0,clearInterval(u)}},[t,n,e,r]);let u=async()=>{s(!1);try{await Fb(t,n)}catch(e){r({title:`Stop failed`,description:e instanceof Error?e.message:String(e),variant:`destructive`})}};if(!i)return(0,V.jsxs)(`div`,{className:`min-h-screen bg-black text-white flex items-center justify-center`,children:[(0,V.jsx)(Ms,{className:`w-6 h-6 animate-spin mr-3`}),` Connecting to inference…`]});let d=i.elapsed_s??0,f=i.rollout_elapsed_s??0,p=i.duration_s??0,m=i.inference_active&&i.rollout_started_at==null,h=i.inference_active&&i.rollout_started_at!=null,g=h&&p>0?Math.min(100,f/p*100):0;return(0,V.jsxs)(`div`,{className:`min-h-screen bg-black text-white flex flex-col p-4 sm:p-6 lg:p-8`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-4 mb-8`,children:[(0,V.jsx)(q,{variant:`ghost`,size:`icon`,onClick:()=>e(`/`),className:`text-slate-400 hover:bg-slate-800 hover:text-white rounded-lg`,children:(0,V.jsx)(as,{className:`w-5 h-5`})}),(0,V.jsx)($M,{}),(0,V.jsx)(`h1`,{className:`font-bold text-white text-2xl`,children:`Inference`})]}),(0,V.jsx)(`div`,{className:`flex-1 flex items-center justify-center`,children:(0,V.jsxs)(`div`,{className:`bg-gray-900 rounded-lg border border-gray-700 p-8 w-full max-w-xl`,children:[(0,V.jsx)(`div`,{className:`text-center mb-6`,children:(0,V.jsxs)(`div`,{className:`inline-flex items-center gap-2 px-3 py-1 rounded-full text-xs font-bold tracking-widest ${m?`bg-amber-500/15 text-amber-300`:`bg-green-500/15 text-green-300`}`,children:[(0,V.jsx)(`span`,{className:`w-2 h-2 rounded-full ${m?`bg-amber-500`:`bg-green-500`} animate-pulse`}),m?`SETTING UP`:h?`RUNNING`:`FINISHED`]})}),(0,V.jsxs)(`div`,{className:`text-center mb-4`,children:[(0,V.jsx)(`div`,{className:`text-7xl font-mono font-bold leading-none ${m?`text-amber-400`:`text-green-400`}`,children:q9(h?f:d)}),(0,V.jsx)(`div`,{className:`text-sm text-gray-500 mt-2`,children:m?`Loading policy & connecting hardware…`:`/ ${q9(p)}`})]}),(0,V.jsx)(`div`,{className:`w-full bg-gray-800 rounded-full h-1.5 mb-8`,children:(0,V.jsx)(`div`,{className:`h-1.5 rounded-full transition-all duration-500 ${m?`bg-amber-500/40 animate-pulse w-full`:`bg-green-500`}`,style:m?void 0:{width:`${g}%`}})}),(0,V.jsxs)(`div`,{className:`text-xs text-slate-500 break-all mb-6`,children:[`policy: `,i.policy_ref??`(unknown)`]}),(0,V.jsxs)(q,{onClick:()=>s(!0),disabled:!i.inference_active,className:`w-full bg-red-500 hover:bg-red-600 text-white font-semibold py-6 text-lg disabled:opacity-50`,children:[(0,V.jsx)(Js,{className:`w-5 h-5 mr-2`}),`Stop`]})]})}),(0,V.jsx)($I,{open:o,onOpenChange:s,children:(0,V.jsxs)(tL,{className:`bg-gray-900 border-gray-700 text-white`,children:[(0,V.jsxs)(nL,{children:[(0,V.jsx)(iL,{children:`Stop inference?`}),(0,V.jsx)(aL,{className:`text-gray-400`,children:`The follower will hold its current pose. You can launch another run from the job tile.`})]}),(0,V.jsxs)(rL,{children:[(0,V.jsx)(sL,{className:`bg-gray-800 border-gray-700 text-white hover:bg-gray-700`,children:`Keep running`}),(0,V.jsx)(oL,{onClick:u,className:`bg-red-500 hover:bg-red-600 text-white`,children:`Stop`})]})]})})]})};async function vse(e,t,n,r){return pf(e,t,`/dataset-episodes?${new URLSearchParams({repo_id:n})}`,{signal:r,action:`List episodes`})}async function yse(e,t,n,r,i){return pf(e,t,`/dataset-episode?${new URLSearchParams({repo_id:n,episode_index:String(r)})}`,{signal:i,action:`Load episode`})}async function bse(e,t,n,r,i){return pf(e,t,`/dataset-motion?${new URLSearchParams({repo_id:n,episode_index:String(r)})}`,{signal:i,action:`Load motion trace`})}async function xse(e,t,n,r,i,a,o){return pf(e,t,`/dataset-thumbnails?${new URLSearchParams({repo_id:n,episode_index:String(r),camera:i,count:String(a)})}`,{signal:o,action:`Load thumbnails`})}function J9(e,t,n,r,i){return`${e}/dataset-video?${new URLSearchParams({repo_id:t,camera:n,chunk:String(r),file:String(i)})}`}function Y9(e,t,n,r,i,a){let o=new URLSearchParams({repo_id:t,episode_index:String(n),camera:r,frame_index:String(i)});return a&&o.set(`max_width`,String(a)),`${e}/dataset-frame?${o}`}function X9(e){if(e==null)return`—`;if(e<60)return`${e.toFixed(1)}s`;let t=Math.floor(e/60),n=Math.round(e%60);return`${t}m ${String(n).padStart(2,`0`)}s`}var Sse=({episodes:e,selected:t,onSelect:n})=>{let r=(0,_.useRef)(null);return(0,_.useEffect)(()=>{r.current?.scrollIntoView({block:`nearest`})},[t]),e.length===0?(0,V.jsx)(`div`,{className:`rounded-lg border border-gray-800 bg-gray-950 p-4 text-xs text-gray-500`,children:`No episodes in this dataset.`}):(0,V.jsxs)(`div`,{className:`overflow-hidden rounded-lg border border-gray-800 bg-gray-950`,children:[(0,V.jsxs)(`div`,{className:`flex items-center justify-between border-b border-gray-800 px-3 py-2`,children:[(0,V.jsx)(`span`,{className:`text-[11px] font-medium uppercase tracking-wider text-gray-500`,children:`Episodes`}),(0,V.jsx)(`span`,{className:`text-[11px] tabular-nums text-gray-600`,children:e.length})]}),(0,V.jsx)(`div`,{className:`max-h-[calc(100vh_-_280px)] overflow-y-auto`,children:e.map(e=>{let i=e.episode_index===t;return(0,V.jsxs)(`button`,{ref:i?r:void 0,type:`button`,onClick:()=>n(e.episode_index),className:`flex w-full items-center gap-2 border-b border-gray-900 px-3 py-2 text-left transition last:border-b-0 ${i?`bg-gray-800/80`:`hover:bg-gray-900`} focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-orange-500`,children:[(0,V.jsx)(`span`,{className:`w-8 text-xs tabular-nums ${i?`font-semibold text-orange-400`:`text-gray-500`}`,children:e.episode_index}),(0,V.jsx)(`span`,{className:`flex-1 truncate text-xs text-gray-300`,children:e.tasks.length>0?e.tasks.join(`, `):`—`}),(0,V.jsx)(`span`,{className:`text-[11px] tabular-nums text-gray-500`,children:X9(e.duration_s)})]},e.episode_index)})})]})},Cse=({repoId:e,episodeIndex:t,camera:n,currentFrame:r,onSeekFrame:i,count:a=12})=>{let{baseUrl:o,fetchWithHeaders:s}=Tl(),[c,l]=(0,_.useState)([]),[u,d]=(0,_.useState)(!1);(0,_.useEffect)(()=>{let r=new AbortController;return d(!0),xse(o,s,e,t,n,a,r.signal).then(e=>{r.signal.aborted||l(e.success?e.thumbnails:[])}).catch(()=>{r.signal.aborted||l([])}).finally(()=>{r.signal.aborted||d(!1)}),()=>r.abort()},[o,s,e,t,n,a]);let f=c.reduce((e,t,n)=>Math.abs(t.frame_index-r)(0,V.jsxs)(`button`,{type:`button`,onClick:()=>i(e.frame_index),title:`Frame ${e.frame_index}`,className:`group relative flex-none overflow-hidden rounded transition ${t===f?`ring-2 ring-orange-500`:`ring-1 ring-gray-800 hover:ring-gray-600`} focus:outline-none focus-visible:ring-2 focus-visible:ring-orange-400`,children:[(0,V.jsx)(`img`,{src:e.data_uri,alt:`Frame ${e.frame_index}`,className:`h-14 w-auto`,draggable:!1}),(0,V.jsx)(`span`,{className:`absolute bottom-0 right-0 bg-black/70 px-1 text-[10px] tabular-nums text-gray-300 opacity-0 transition group-hover:opacity-100`,children:e.frame_index})]},e.frame_index))})},wse=({repoId:e,episodeIndex:t,currentFrame:n,onSeekFrame:r})=>{let{baseUrl:i,fetchWithHeaders:a}=Tl(),[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(null);(0,_.useEffect)(()=>{let n=new AbortController;return l(null),bse(i,a,e,t,n.signal).then(e=>{if(!n.signal.aborted){if(!e.success){s(null),l(e.message??`No action stream`);return}s(e.motion)}}).catch(e=>{n.signal.aborted||(s(null),l(e instanceof Error?e.message:`No action stream`))}),()=>n.abort()},[i,a,e,t]);let u=(0,_.useMemo)(()=>(o??[]).map((e,t)=>({frame:t,motion:e})),[o]);return c?(0,V.jsxs)(`div`,{className:`flex h-[64px] items-center justify-center rounded-md border border-gray-800 bg-gray-950 text-[11px] text-gray-600`,children:[`Joint motion unavailable — `,c]}):o?(0,V.jsxs)(`div`,{className:`rounded-md border border-gray-800 bg-gray-950 px-1 pb-1 pt-1.5`,children:[(0,V.jsxs)(`div`,{className:`flex items-center justify-between px-2 pb-1`,children:[(0,V.jsx)(`span`,{className:`text-[10px] uppercase tracking-wider text-gray-600`,children:`Joint motion`}),(0,V.jsxs)(`span`,{className:`text-[10px] tabular-nums text-gray-600`,children:[`frame `,n]})]}),(0,V.jsx)(`div`,{className:`h-[52px] w-full cursor-pointer`,children:(0,V.jsx)(mG,{width:`100%`,height:`100%`,children:(0,V.jsxs)(ase,{data:u,margin:{top:2,right:4,bottom:0,left:4},onClick:e=>{let t=e?.activeLabel;t!=null&&r(Number(t))},children:[(0,V.jsx)(`defs`,{children:(0,V.jsxs)(`linearGradient`,{id:`motionFill`,x1:`0`,y1:`0`,x2:`0`,y2:`1`,children:[(0,V.jsx)(`stop`,{offset:`0%`,stopColor:`#f97316`,stopOpacity:.5}),(0,V.jsx)(`stop`,{offset:`100%`,stopColor:`#f97316`,stopOpacity:.04})]})}),(0,V.jsx)(s9,{hide:!0,domain:[0,`dataMax`]}),(0,V.jsx)(YW,{contentStyle:{background:`#0a0a0a`,border:`1px solid #1f2937`,borderRadius:6,fontSize:11,padding:`4px 8px`},labelStyle:{color:`#9ca3af`},itemStyle:{color:`#fb923c`},formatter:e=>[e.toFixed(2),`motion`],labelFormatter:e=>`Frame ${e}`}),(0,V.jsx)(H7,{type:`monotone`,dataKey:`motion`,stroke:`#f97316`,strokeWidth:1.25,fill:`url(#motionFill)`,isAnimationActive:!1,dot:!1}),(0,V.jsx)(A5,{x:n,stroke:`#e5e7eb`,strokeWidth:1})]})})})]}):(0,V.jsx)(`div`,{className:`h-[64px] rounded-md border border-gray-800 bg-gray-950`})},Tse=[.5,1,2],Ese=.2,Dse=({repoId:e,detail:t,onNavigate:n})=>{let{baseUrl:r}=Tl(),i=t.cameras,[a,o]=(0,_.useState)(i[0]?.name??``),[s,c]=(0,_.useState)(!1),[l,u]=(0,_.useState)(!1),[d,f]=(0,_.useState)(1),[p,m]=(0,_.useState)(0),h=(0,_.useRef)(null),g=(0,_.useRef)({});(0,_.useEffect)(()=>{i.some(e=>e.name===a)||o(i[0]?.name??``)},[i,a]);let v=(0,_.useMemo)(()=>i.find(e=>e.name===a)??i[0]??null,[i,a]),y=t.fps??20,b=v?.from_timestamp??0,x=v?.to_timestamp??b+(t.duration_s??0),S=(0,_.useCallback)(e=>{let n=h.current;if(!n)return;let r=Math.max(0,Math.min(e,Math.max(t.length-1,0)));n.currentTime=b+(r+.5)/y,m(r)},[b,y,t.length]),C=(0,_.useCallback)(()=>{let e=h.current;e&&(e.currentTime=b,e.playbackRate=d,m(0))},[b,d]);(0,_.useEffect)(()=>{let e=h.current;if(!e)return;let t=!e.paused,n=()=>{e.currentTime=b,e.playbackRate=d,m(0),(t||l)&&e.play().catch(()=>u(!1))};if(e.readyState>=1)n();else return e.addEventListener(`loadedmetadata`,n,{once:!0}),()=>e.removeEventListener(`loadedmetadata`,n)},[t.episode_index,a,b]);let w=(0,_.useCallback)(()=>{let e=h.current;if(e&&!e.ended){if(e.currentTime>=x){e.currentTime=b,m(0);return}if(m(Math.max(0,Math.floor((e.currentTime-b)*y))),s)for(let t of i){if(t.name===a)continue;let n=g.current[t.name];if(!n)continue;let r=(t.from_timestamp??0)+(e.currentTime-b);Math.abs(n.currentTime-r)>Ese&&(n.currentTime=r),n.playbackRate=e.playbackRate,l&&n.paused&&n.play().catch(()=>void 0),!l&&!n.paused&&n.pause()}}},[x,b,y,s,i,a,l]),T=(0,_.useCallback)(()=>{let e=h.current;e&&(e.paused?e.play().then(()=>u(!0),()=>u(!1)):(e.pause(),u(!1)))},[]);if((0,_.useEffect)(()=>{h.current&&(h.current.playbackRate=d)},[d,a]),(0,_.useEffect)(()=>{let e=e=>{let t=e.target;t&&[`INPUT`,`TEXTAREA`,`SELECT`].includes(t.tagName)||(e.code===`Space`?(e.preventDefault(),T()):e.code===`ArrowLeft`?S(p-1):e.code===`ArrowRight`&&S(p+1))};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[T,S,p]),!v)return(0,V.jsx)(`div`,{className:`flex h-64 items-center justify-center rounded-lg border border-gray-800 bg-gray-950 text-sm text-gray-500`,children:`This episode has no camera videos on disk.`});let E=i.filter(e=>e.name!==a);return(0,V.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,V.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,V.jsx)(`div`,{className:`flex rounded-md border border-gray-800 bg-gray-950 p-0.5`,children:i.map(e=>(0,V.jsx)(`button`,{type:`button`,onClick:()=>o(e.name),className:`rounded px-3 py-1 text-xs font-medium transition ${e.name===a?`bg-gray-800 text-white`:`text-gray-400 hover:text-gray-200`}`,children:e.name},e.name))}),i.length>1&&(0,V.jsxs)(q,{variant:`outline`,size:`sm`,onClick:()=>c(e=>!e),className:`h-7 gap-1.5 border-gray-800 bg-gray-950 text-xs hover:bg-gray-900 ${s?`text-orange-400`:`text-gray-400`}`,children:[(0,V.jsx)(js,{className:`h-3.5 w-3.5`}),`All cameras`]}),(0,V.jsx)(`div`,{className:`ml-auto flex rounded-md border border-gray-800 bg-gray-950 p-0.5`,children:Tse.map(e=>(0,V.jsxs)(`button`,{type:`button`,onClick:()=>f(e),className:`rounded px-2.5 py-1 text-xs font-medium tabular-nums transition ${e===d?`bg-gray-800 text-white`:`text-gray-400 hover:text-gray-200`}`,children:[e,`x`]},e))})]}),(0,V.jsxs)(`div`,{className:s&&i.length>1?`grid grid-cols-1 gap-2 sm:grid-cols-2`:`grid grid-cols-1`,children:[(0,V.jsxs)(`div`,{className:`relative flex items-center justify-center overflow-hidden rounded-lg border border-gray-800 bg-black`,children:[(0,V.jsx)(`video`,{ref:h,src:J9(r,e,a,v.chunk,v.file_index),poster:Y9(r,e,t.episode_index,a,0,640),className:`w-auto max-w-full bg-black object-contain ${s&&i.length>1?`max-h-[22vh]`:`max-h-[42vh]`}`,preload:`auto`,playsInline:!0,muted:!0,onLoadedMetadata:C,onTimeUpdate:w,onEnded:e=>{let t=e.currentTarget;t.currentTime=b,m(0),t.play().catch(()=>u(!1))},onPlay:()=>u(!0),onPause:()=>u(!1)},`${a}-${v.chunk}-${v.file_index}`),(0,V.jsx)(`span`,{className:`absolute left-2 top-2 rounded bg-black/70 px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-gray-300`,children:a})]}),s&&E.map(n=>(0,V.jsxs)(`div`,{className:`relative flex items-center justify-center overflow-hidden rounded-lg border border-gray-800 bg-black`,children:[(0,V.jsx)(`video`,{ref:e=>{g.current[n.name]=e},src:J9(r,e,n.name,n.chunk,n.file_index),poster:Y9(r,e,t.episode_index,n.name,0,640),className:`max-h-[22vh] w-auto max-w-full bg-black object-contain`,preload:`auto`,playsInline:!0,muted:!0,onLoadedMetadata:e=>{e.currentTarget.currentTime=n.from_timestamp??0}},`${n.name}-${n.chunk}-${n.file_index}`),(0,V.jsx)(`span`,{className:`absolute left-2 top-2 rounded bg-black/70 px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-gray-300`,children:n.name})]},n.name))]}),(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,V.jsx)(q,{size:`sm`,onClick:T,className:`h-8 w-8 bg-orange-600 p-0 hover:bg-orange-500`,title:`Play / pause (Space)`,children:l?(0,V.jsx)(Fs,{className:`h-4 w-4`}):(0,V.jsx)(Ls,{className:`h-4 w-4`})}),(0,V.jsx)(q,{variant:`outline`,size:`sm`,onClick:()=>S(p-1),className:`h-8 w-8 border-gray-800 bg-gray-950 p-0 text-gray-300 hover:bg-gray-900`,title:`Previous frame (←)`,children:(0,V.jsx)(Gs,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(q,{variant:`outline`,size:`sm`,onClick:()=>S(p+1),className:`h-8 w-8 border-gray-800 bg-gray-950 p-0 text-gray-300 hover:bg-gray-900`,title:`Next frame (→)`,children:(0,V.jsx)(Ks,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(`input`,{type:`range`,min:0,max:Math.max(t.length-1,0),value:p,onChange:e=>S(Number(e.target.value)),className:`mx-2 h-1 flex-1 cursor-pointer appearance-none rounded bg-gray-800 accent-orange-500`,"aria-label":`Scrub episode`}),(0,V.jsxs)(`span`,{className:`w-28 text-right text-xs tabular-nums text-gray-400`,children:[p,` / `,Math.max(t.length-1,0)]})]}),(0,V.jsx)(wse,{repoId:e,episodeIndex:t.episode_index,currentFrame:p,onSeekFrame:S}),(0,V.jsx)(Cse,{repoId:e,episodeIndex:t.episode_index,camera:a,currentFrame:p,onSeekFrame:S}),(0,V.jsxs)(`div`,{className:`flex items-center justify-between border-t border-gray-800 pt-3`,children:[(0,V.jsxs)(q,{variant:`outline`,size:`sm`,disabled:t.prev_episode===null,onClick:()=>t.prev_episode!==null&&n(t.prev_episode),className:`h-7 gap-1 border-gray-800 bg-gray-950 text-xs text-gray-300 hover:bg-gray-900 disabled:opacity-40`,children:[(0,V.jsx)(us,{className:`h-3.5 w-3.5`}),`Previous`]}),(0,V.jsxs)(`span`,{className:`text-xs text-gray-500`,children:[`Episode `,t.episode_index,` of `,t.total_episodes]}),(0,V.jsxs)(q,{variant:`outline`,size:`sm`,disabled:t.next_episode===null,onClick:()=>t.next_episode!==null&&n(t.next_episode),className:`h-7 gap-1 border-gray-800 bg-gray-950 text-xs text-gray-300 hover:bg-gray-900 disabled:opacity-40`,children:[`Next`,(0,V.jsx)(ds,{className:`h-3.5 w-3.5`})]})]})]})};function Ose({datasets:e,open:t,onOpenChange:n,onMerge:r}){let[i,a]=(0,_.useState)([]),[o,s]=(0,_.useState)(``),[c,l]=(0,_.useState)(!1),[u,d]=(0,_.useState)(null),f=(0,_.useMemo)(()=>e.filter(e=>e.source===`local`||e.source===`both`),[e]),p=i.length>=2&&/^[A-Za-z0-9._-]+$/.test(o)&&!c,m=(e,t)=>{d(null),a(n=>t?[...n,e]:n.filter(t=>t!==e))},h=()=>{a([]),s(``),l(!1),d(null)},g=e=>{!c&&!e&&h(),n(e)};return(0,V.jsx)(nf,{open:t,onOpenChange:g,children:(0,V.jsxs)(of,{className:`border-gray-700 bg-gray-900 text-gray-300 sm:max-w-lg`,children:[(0,V.jsxs)(sf,{children:[(0,V.jsx)(lf,{className:`text-white`,children:`Merge local datasets`}),(0,V.jsx)(uf,{children:`Select two or more local datasets. Their source files stay unchanged; the merged dataset is saved locally.`})]}),(0,V.jsxs)(`div`,{className:`space-y-3`,children:[(0,V.jsx)(J,{className:`text-gray-300`,children:`Source datasets`}),(0,V.jsx)(`div`,{className:`max-h-52 space-y-2 overflow-y-auto rounded-md border border-gray-700 p-3`,children:f.map(e=>(0,V.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-3 text-sm text-gray-200`,children:[(0,V.jsx)(J_,{checked:i.includes(e.repo_id),onCheckedChange:t=>m(e.repo_id,t===!0),disabled:c}),e.repo_id]},e.repo_id))}),(0,V.jsx)(`p`,{className:`text-xs text-gray-500`,children:`Select at least two datasets.`}),(0,V.jsxs)(`div`,{className:`space-y-2`,children:[(0,V.jsx)(J,{htmlFor:`merged-dataset-name`,className:`text-gray-300`,children:`Merged dataset name`}),(0,V.jsx)(k_,{id:`merged-dataset-name`,value:o,onChange:e=>{d(null),s(e.target.value.replace(/[^A-Za-z0-9._-]/g,`_`))},placeholder:`combined_pick_place`,disabled:c,className:`border-gray-700 bg-gray-800 text-white`}),(0,V.jsxs)(`p`,{className:`text-xs text-gray-500`,children:[`Saved locally as `,(0,V.jsxs)(`code`,{children:[`local/`,o||`name`]}),`.`]})]}),u&&(0,V.jsx)(`p`,{className:`text-sm text-red-400`,children:u})]}),(0,V.jsxs)(cf,{children:[(0,V.jsx)(q,{variant:`outline`,onClick:()=>g(!1),disabled:c,children:`Cancel`}),(0,V.jsxs)(q,{onClick:async()=>{if(p){l(!0);try{await r(i,o),h(),n(!1)}catch(e){d(e instanceof Error?e.message:`Could not merge the selected datasets.`)}finally{l(!1)}}},disabled:!p,children:[c&&(0,V.jsx)(Ms,{className:`mr-2 h-4 w-4 animate-spin`}),c?`Merging…`:`Merge datasets`]})]})]})})}var kse=e=>{let{baseUrl:t,fetchWithHeaders:n}=Tl(),[r,i]=(0,_.useState)(null),[a,o]=(0,_.useState)(!1),[s,c]=(0,_.useState)(null);return(0,_.useEffect)(()=>{if(i(null),c(null),!e){o(!1);return}let r=new AbortController;return o(!0),vse(t,n,e,r.signal).then(e=>{if(!r.signal.aborted){if(!e.success){i(null),c(e.message??`Could not read dataset`);return}i(e)}}).catch(e=>{r.signal.aborted||(i(null),c(e instanceof Error?e.message:`Could not read dataset`))}).finally(()=>{r.signal.aborted||o(!1)}),()=>r.abort()},[t,n,e]),{data:r?.repo_id===e?r:null,loading:a,error:s}},Ase=(e,t)=>{let{baseUrl:n,fetchWithHeaders:r}=Tl(),[i,a]=(0,_.useState)(null),[o,s]=(0,_.useState)(!1),[c,l]=(0,_.useState)(null);return(0,_.useEffect)(()=>{if(!e||t===null){a(null);return}let i=new AbortController;return s(!0),l(null),yse(n,r,e,t,i.signal).then(e=>{if(!i.signal.aborted){if(!e.success){a(null),l(e.message??`Could not load episode`);return}a(e)}}).catch(e=>{i.signal.aborted||(a(null),l(e instanceof Error?e.message:`Could not load episode`))}).finally(()=>{i.signal.aborted||s(!1)}),()=>i.abort()},[n,r,e,t]),{detail:i,loading:o,error:c}},Z9=({label:e,value:t})=>(0,V.jsxs)(`span`,{className:`flex items-baseline gap-1.5`,children:[(0,V.jsx)(`span`,{className:`text-[10px] uppercase tracking-wider text-gray-600`,children:e}),(0,V.jsx)(`span`,{className:`font-medium tabular-nums text-gray-200`,children:t})]}),jse=()=>{let e=mt(),[t,n]=Vn(),{datasets:r,loading:i,refresh:a}=$b(),{baseUrl:o,fetchWithHeaders:s}=Tl(),{toast:c}=$i(),[l,u]=(0,_.useState)(!1),d=(0,_.useMemo)(()=>r.filter(e=>e.source===`local`||e.source===`both`),[r]),f=t.get(`dataset`),p=t.get(`episode`),m=p===null?null:Number(p),h=r.find(e=>e.repo_id===f)?.source,{data:g,loading:v,error:y}=kse(f),{detail:b,loading:x,error:S}=Ase(f,m),C=e=>{let n=t.get(`api`);return n?{...e,api:n}:e},w=e=>n(C({dataset:e})),T=async(e,t)=>{let n=await hf(o,s,e,t);a(),w(n.repo_id),c({title:`Datasets merged`,description:`${n.num_episodes} episodes are ready to browse.`})},E=e=>{f&&n(C({dataset:f,episode:String(e)}))};return(0,_.useEffect)(()=>{f&&g?.success&&p===null&&g.episodes.length>0&&n(C({dataset:f,episode:String(g.episodes[0].episode_index)}),{replace:!0})},[f,g,p,n]),(0,V.jsxs)(`div`,{className:`min-h-screen bg-black p-6 pb-24 text-white`,children:[(0,V.jsxs)(`div`,{className:`mx-auto max-w-[1400px]`,children:[(0,V.jsxs)(`div`,{className:`mb-5 flex flex-wrap items-center gap-3`,children:[(0,V.jsxs)(q,{variant:`ghost`,size:`sm`,onClick:()=>e(`/`),className:`h-8 gap-1.5 px-2 text-gray-400 hover:bg-gray-900 hover:text-white`,children:[(0,V.jsx)(as,{className:`h-4 w-4`}),`Back`]}),(0,V.jsxs)(`h1`,{className:`flex items-center gap-2 text-xl font-semibold tracking-tight`,children:[(0,V.jsx)(Cs,{className:`h-5 w-5 text-orange-500`}),`Browse dataset`]}),(0,V.jsxs)(`div`,{className:`ml-auto flex w-full items-center gap-2 sm:w-auto`,children:[(0,V.jsx)(`div`,{className:`w-full sm:w-[380px]`,children:(0,V.jsxs)(Gy,{value:f??void 0,onValueChange:w,children:[(0,V.jsx)(qy,{className:`h-9 border-gray-800 bg-gray-950 text-sm text-white`,children:(0,V.jsx)(Ky,{placeholder:i?`Loading datasets…`:`Select a local dataset`})}),(0,V.jsx)(Xy,{className:`border-gray-800 bg-gray-950 text-white`,children:d.map(e=>(0,V.jsx)(Qy,{value:e.repo_id,className:`text-sm`,children:e.repo_id},e.repo_id))})]})}),(0,V.jsxs)(q,{variant:`outline`,size:`sm`,onClick:()=>u(!0),className:`h-9 gap-1.5 border-gray-800 bg-gray-950 text-xs text-gray-300 hover:bg-gray-900`,children:[(0,V.jsx)(Ps,{className:`h-3.5 w-3.5`}),`Merge`]}),f&&(0,V.jsxs)(q,{variant:`outline`,size:`sm`,onClick:()=>e(`/upload`,{state:{datasetInfo:{dataset_repo_id:f,source:h??`local`}}}),className:`h-9 gap-1.5 border-gray-800 bg-gray-950 text-xs text-gray-300 hover:bg-gray-900`,children:[(0,V.jsx)(Qs,{className:`h-3.5 w-3.5`}),`Upload`]})]})]}),!f&&(0,V.jsxs)(`div`,{className:`rounded-lg border border-gray-800 bg-gray-950 p-10 text-center`,children:[(0,V.jsx)(Cs,{className:`mx-auto mb-3 h-8 w-8 text-gray-700`}),(0,V.jsx)(`p`,{className:`text-sm text-gray-400`,children:`Select a dataset to browse its episodes.`}),!i&&d.length===0&&(0,V.jsx)(`p`,{className:`mt-2 text-xs text-gray-600`,children:`No datasets in the local LeRobot cache. Record one, or download it from the Hub first.`})]}),f&&v&&(0,V.jsxs)(`div`,{className:`flex items-center justify-center gap-2 rounded-lg border border-gray-800 bg-gray-950 p-10 text-sm text-gray-500`,children:[(0,V.jsx)(Ms,{className:`h-4 w-4 animate-spin`}),`Reading dataset…`]}),f&&y&&(0,V.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-red-900/50 bg-red-950/30 p-4`,children:[(0,V.jsx)(ms,{className:`mt-0.5 h-4 w-4 flex-none text-red-400`}),(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`p`,{className:`text-sm font-medium text-red-300`,children:`Could not read this dataset`}),(0,V.jsx)(`p`,{className:`mt-0.5 text-xs text-red-400/80`,children:y})]})]}),f&&g?.success&&(0,V.jsxs)(V.Fragment,{children:[(0,V.jsxs)(`div`,{className:`mb-4 flex flex-wrap items-center gap-x-5 gap-y-1 rounded-lg border border-gray-800 bg-gray-950 px-4 py-2.5 text-xs`,children:[(0,V.jsx)(Z9,{label:`Episodes`,value:String(g.total_episodes)}),(0,V.jsx)(Z9,{label:`Frames`,value:g.total_frames?.toLocaleString()??`—`}),(0,V.jsx)(Z9,{label:`FPS`,value:String(g.fps??`—`)}),(0,V.jsx)(Z9,{label:`Robot`,value:g.robot_type??`—`}),(0,V.jsx)(Z9,{label:`Cameras`,value:g.cameras.join(`, `)||`—`}),b&&(0,V.jsx)(Z9,{label:`This episode`,value:X9(b.duration_s)})]}),(0,V.jsxs)(`div`,{className:`grid grid-cols-1 gap-4 lg:grid-cols-[260px_1fr]`,children:[(0,V.jsx)(Sse,{episodes:g.episodes,selected:m,onSelect:E}),(0,V.jsxs)(`div`,{children:[x&&!b&&(0,V.jsxs)(`div`,{className:`flex h-64 items-center justify-center gap-2 rounded-lg border border-gray-800 bg-gray-950 text-sm text-gray-500`,children:[(0,V.jsx)(Ms,{className:`h-4 w-4 animate-spin`}),`Loading episode…`]}),S&&(0,V.jsx)(`div`,{className:`rounded-lg border border-red-900/50 bg-red-950/30 p-4 text-xs text-red-400`,children:S}),b&&(0,V.jsx)(Dse,{repoId:f,detail:b,onNavigate:E})]})]})]})]}),(0,V.jsx)(Ose,{datasets:r,open:l,onOpenChange:u,onMerge:T})]})},Mse=()=>{let e=dt(),t=mt(),{toast:n}=$i(),{baseUrl:r,fetchWithHeaders:i}=Tl(),a=e.state?.datasetInfo,[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(!0),[u,d]=(0,_.useState)({tags:[`robotics`,`lerobot`],private:!1}),[f,p]=(0,_.useState)(u.tags.join(`, `)),[m,h]=(0,_.useState)(!1),[g,v]=(0,_.useState)(!1),[y,b]=(0,_.useState)(!1),[x,S]=(0,_.useState)(!1);_.useEffect(()=>{(async()=>{if(!a?.dataset_repo_id){n({title:`No Dataset Information`,description:`Please complete a recording session first.`,variant:`destructive`}),t(`/`);return}try{let e=await i(`${r}/dataset-info`,{method:`POST`,body:JSON.stringify({dataset_repo_id:a.dataset_repo_id})}),t=await e.json();e.ok&&t.success?s({...t,saved_episodes:t.num_episodes,session_elapsed_seconds:a.session_elapsed_seconds||0,source:a.source}):(n({title:`Warning`,description:`Could not load complete dataset information. Using session data.`,variant:`destructive`}),s(a))}catch(e){console.error(`Error loading dataset info:`,e),n({title:`Warning`,description:`Could not connect to backend. Using session data.`,variant:`destructive`}),s(a)}finally{l(!1)}})()},[a,t,n]);let C=e=>{let t=`/spaces/lerobot/visualize_dataset?path=${encodeURIComponent(`/${e}`)}`,n=`https://huggingface.co/login?next=${encodeURIComponent(t)}`;window.open(n,`_blank`,`noopener,noreferrer`)},w=e=>{let t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=e%60;return t>0?`${t}h ${n}m ${r}s`:n>0?`${n}m ${r}s`:`${r}s`},T=async()=>{if(o){h(!0);try{let e=f.split(`,`).map(e=>e.trim()).filter(e=>e.length>0),t=await i(`${r}/upload-dataset`,{method:`POST`,body:JSON.stringify({dataset_repo_id:o.dataset_repo_id,tags:e,private:u.private})}),a=await t.json();if(t.ok&&a.success)v(!0),n({title:`Upload Successful!`,description:`Dataset ${o.dataset_repo_id} has been uploaded to HuggingFace Hub.`});else{let e=`Failed to upload dataset to HuggingFace Hub.`;n({title:`Upload Failed`,description:a.docs_url?(0,V.jsxs)(`span`,{children:[a.message||e,` `,(0,V.jsx)(`a`,{href:a.docs_url,target:`_blank`,rel:`noopener noreferrer`,className:`underline font-medium`,children:`Open setup guide`})]}):a.message||e,variant:`destructive`})}}catch(e){console.error(`Error uploading dataset:`,e),n({title:`Connection Error`,description:`Could not connect to the backend server.`,variant:`destructive`})}finally{h(!1)}}},E=()=>{n({title:`Upload Skipped`,description:`Dataset saved locally. You can upload it manually later.`}),t(`/`)},D=async()=>{if(o){S(!0);try{let e=await i(`${r}/delete-dataset`,{method:`POST`,body:JSON.stringify({dataset_repo_id:o.dataset_repo_id})}),a=await e.json();e.ok&&a.success?(n({title:`Dataset Deleted`,description:`${o.dataset_repo_id} has been removed from disk.`}),t(`/`)):n({title:`Delete Failed`,description:a.message||`Could not delete the dataset.`,variant:`destructive`})}catch{n({title:`Connection Error`,description:`Could not connect to the backend server.`,variant:`destructive`})}finally{S(!1),b(!1)}}};if(c||!o)return(0,V.jsx)(`div`,{className:`min-h-screen bg-black text-white flex items-center justify-center`,children:(0,V.jsxs)(`div`,{className:`text-center`,children:[(0,V.jsx)(`div`,{className:`animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500 mx-auto mb-4`}),(0,V.jsx)(`p`,{className:`text-lg`,children:`Loading dataset information...`})]})});let O=o.source===`both`;return(0,V.jsxs)(`div`,{className:`min-h-screen bg-black text-white p-8`,children:[(0,V.jsxs)(`div`,{className:`max-w-4xl mx-auto`,children:[(0,V.jsxs)(`div`,{className:`flex items-center justify-between mb-8`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,V.jsxs)(q,{onClick:()=>t(`/`),variant:`outline`,className:`border-gray-500 hover:border-gray-200 text-gray-300 hover:text-white`,children:[(0,V.jsx)(as,{className:`w-4 h-4 mr-2`}),`Back to Home`]}),(0,V.jsx)(q,{onClick:()=>b(!0),variant:`outline`,size:`icon`,disabled:x,"aria-label":`Delete dataset from disk`,className:`border-red-500/40 text-red-400 hover:border-red-400 hover:text-red-300 hover:bg-red-500/10`,children:(0,V.jsx)(Xs,{className:`w-4 h-4`})})]}),(0,V.jsxs)(`div`,{className:`flex items-center gap-3`,children:[g?(0,V.jsx)(hs,{className:`w-8 h-8 text-green-500`}):(0,V.jsx)(Cs,{className:`w-8 h-8 text-blue-500`}),(0,V.jsx)(`h1`,{className:`text-3xl font-bold`,children:g?`Upload Complete`:`Dataset Upload`})]})]}),g&&(0,V.jsxs)(`div`,{className:`bg-green-900/20 border border-green-600 rounded-lg p-6 mb-8`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-3 mb-4`,children:[(0,V.jsx)(hs,{className:`w-6 h-6 text-green-500`}),(0,V.jsx)(`h2`,{className:`text-xl font-semibold text-green-400`,children:`Successfully Uploaded!`})]}),(0,V.jsx)(`p`,{className:`text-gray-300 mb-4`,children:`Your dataset has been uploaded to HuggingFace Hub and is now available for training and sharing.`}),(0,V.jsxs)(`div`,{className:`flex flex-col sm:flex-row gap-4`,children:[(0,V.jsxs)(q,{onClick:()=>{let e=`/spaces/lerobot/visualize_dataset?path=${encodeURIComponent(`/${o.dataset_repo_id}`)}`,t=u.private?`https://huggingface.co/login?next=${encodeURIComponent(e)}`:`https://huggingface.co${e}`;window.open(t,`_blank`,`noopener,noreferrer`)},className:`bg-blue-500 hover:bg-blue-600 text-white`,children:[(0,V.jsx)(Es,{className:`w-4 h-4 mr-2`}),`View on HuggingFace Hub`]}),(0,V.jsx)(q,{onClick:()=>t(`/training`,{state:{datasetRepoId:o.dataset_repo_id}}),className:`bg-purple-500 hover:bg-purple-600 text-white`,children:`Start Training`})]})]}),!g&&(0,V.jsxs)(V.Fragment,{children:[(0,V.jsxs)(`div`,{className:`bg-gray-900 rounded-lg p-6 border border-gray-700 mb-8`,children:[(0,V.jsx)(`h2`,{className:`text-xl font-semibold text-white mb-4`,children:`Dataset Summary`}),(0,V.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,V.jsxs)(`div`,{className:`space-y-3`,children:[(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`span`,{className:`text-gray-400`,children:`Repository ID:`}),(0,V.jsx)(`p`,{className:`text-white font-mono text-lg`,children:o.dataset_repo_id})]}),(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`span`,{className:`text-gray-400`,children:`Task:`}),(0,V.jsx)(`p`,{className:`text-white`,children:o.single_task})]})]}),(0,V.jsxs)(`div`,{className:`space-y-3`,children:[(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`span`,{className:`text-gray-400`,children:`Episodes Recorded:`}),(0,V.jsx)(`p`,{className:`text-white text-2xl font-bold text-green-400`,children:o.saved_episodes||o.num_episodes}),o.total_frames&&(0,V.jsxs)(`p`,{className:`text-gray-400 text-sm`,children:[o.total_frames,` total frames`]})]}),(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`span`,{className:`text-gray-400`,children:`Session Duration:`}),(0,V.jsx)(`p`,{className:`text-white`,children:w(o.session_elapsed_seconds||0)}),o.fps&&(0,V.jsxs)(`p`,{className:`text-gray-400 text-sm`,children:[o.fps,` FPS`]})]})]})]})]}),!O&&(0,V.jsxs)(`div`,{className:`bg-gray-900 rounded-lg p-6 border border-gray-700 mb-8`,children:[(0,V.jsx)(`h2`,{className:`text-xl font-semibold text-white mb-6`,children:`Upload Configuration`}),(0,V.jsxs)(`div`,{className:`space-y-6`,children:[(0,V.jsxs)(`div`,{children:[(0,V.jsx)(J,{htmlFor:`tags`,className:`text-gray-300 mb-2 block`,children:`Tags (comma-separated)`}),(0,V.jsx)(k_,{id:`tags`,value:f,onChange:e=>p(e.target.value),placeholder:`robotics, lerobot, manipulation`,className:`bg-gray-800 border-gray-600 text-white`}),(0,V.jsx)(`p`,{className:`text-sm text-gray-500 mt-1`,children:`Tags help others discover your dataset on HuggingFace Hub`})]}),(0,V.jsxs)(`div`,{className:`flex items-center space-x-3`,children:[(0,V.jsx)(J_,{id:`private`,checked:u.private,onCheckedChange:e=>d({...u,private:e})}),(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[u.private?(0,V.jsx)(Ds,{className:`w-4 h-4 text-gray-400`}):(0,V.jsx)(Os,{className:`w-4 h-4 text-gray-400`}),(0,V.jsx)(J,{htmlFor:`private`,className:`text-gray-300`,children:`Make dataset private`})]})]}),(0,V.jsx)(`p`,{className:`text-sm text-gray-500 ml-6`,children:u.private?`Only you will be able to access this dataset`:`Dataset will be publicly accessible on HuggingFace Hub`})]})]}),(0,V.jsx)(`div`,{className:`flex flex-col sm:flex-row gap-4 justify-center`,children:O?(0,V.jsxs)(q,{onClick:()=>C(o.dataset_repo_id),className:`bg-blue-500 hover:bg-blue-600 text-white font-semibold py-4 px-8 text-lg`,children:[(0,V.jsx)(Es,{className:`w-5 h-5 mr-2`}),`View on Hugging Face Hub`]}):(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(q,{onClick:T,disabled:m,className:`bg-blue-500 hover:bg-blue-600 text-white font-semibold py-4 px-8 text-lg`,children:m?(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Ms,{className:`w-5 h-5 mr-2 animate-spin`}),`Uploading to Hub...`]}):(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Qs,{className:`w-5 h-5 mr-2`}),`Upload to HuggingFace Hub`]})}),(0,V.jsx)(q,{onClick:E,disabled:m,variant:`outline`,className:`border-gray-600 text-gray-300 hover:bg-gray-800 hover:text-white py-4 px-8 text-lg`,children:`Skip Upload`})]})}),!O&&(0,V.jsx)(`div`,{className:`mt-8 p-4 bg-blue-900/20 border border-blue-600 rounded-lg`,children:(0,V.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,V.jsx)(ms,{className:`w-5 h-5 text-blue-400 mt-0.5`}),(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`h3`,{className:`font-semibold text-blue-400 mb-2`,children:`About HuggingFace Hub Upload`}),(0,V.jsxs)(`ul`,{className:`text-sm text-gray-300 space-y-1`,children:[(0,V.jsx)(`li`,{children:`• Your dataset will be uploaded to HuggingFace Hub for sharing and collaboration`}),(0,V.jsx)(`li`,{children:`• You need to be logged in to HuggingFace CLI on the server`}),(0,V.jsx)(`li`,{children:`• Uploaded datasets can be used for training models and sharing with the community`}),(0,V.jsx)(`li`,{children:`• You can always upload manually later using the HuggingFace CLI`})]})]})]})})]})]}),(0,V.jsx)($I,{open:y,onOpenChange:b,children:(0,V.jsxs)(tL,{className:`bg-gray-900 border-gray-700 text-white`,children:[(0,V.jsxs)(nL,{children:[(0,V.jsx)(iL,{children:`Delete dataset from disk?`}),(0,V.jsxs)(aL,{className:`text-gray-400`,children:[`This permanently removes `,(0,V.jsx)(`span`,{className:`font-mono text-white`,children:o.dataset_repo_id}),` from your local cache. This action cannot be undone.`]})]}),(0,V.jsxs)(rL,{children:[(0,V.jsx)(sL,{className:`bg-gray-800 border-gray-700 text-white hover:bg-gray-700`,children:`Keep dataset`}),(0,V.jsx)(oL,{onClick:D,disabled:x,className:`bg-red-500 hover:bg-red-600 text-white`,children:x?`Deleting…`:`Delete`})]})]})})]})},Nse=()=>{let e=dt();return(0,_.useEffect)(()=>{console.error(`404 Error: User attempted to access non-existent route:`,e.pathname)},[e.pathname]),(0,V.jsx)(`div`,{className:`min-h-screen flex items-center justify-center bg-gray-100`,children:(0,V.jsxs)(`div`,{className:`text-center`,children:[(0,V.jsx)(`h1`,{className:`text-4xl font-bold mb-4`,children:`404`}),(0,V.jsx)(`p`,{className:`text-xl text-gray-600 mb-4`,children:`Oops! Page not found`}),(0,V.jsx)(`a`,{href:`/`,className:`text-blue-500 hover:text-blue-700 underline`,children:`Return to Home`})]})})},Pse=`lelab-tabs-v1`,Fse=1e3,Ise=3e3,Lse=({children:e})=>{let[t,n]=(0,_.useState)(!0),r=(0,_.useRef)(new Map),i=(0,_.useRef)(``),a=(0,_.useRef)(0),o=(0,_.useRef)(null),s=(0,_.useCallback)(()=>{let e=r.current,t=Date.now()-Ise;for(let[n,r]of e)r.lastSeen{if(typeof window>`u`||typeof BroadcastChannel>`u`)return;i.current=crypto.randomUUID(),a.current=Date.now();let e=new BroadcastChannel(Pse);o.current=e;let t=t=>{e.postMessage({type:t,id:i.current,openedAt:a.current})};e.onmessage=e=>{let t=e.data;if(!t||t.id===i.current)return;let n=r.current;t.type===`HEARTBEAT`?n.set(t.id,{id:t.id,openedAt:t.openedAt,lastSeen:Date.now()}):t.type===`RELEASE`?n.delete(t.id):t.type===`TAKEOVER`&&(n.set(t.id,{id:t.id,openedAt:t.openedAt,lastSeen:Date.now()}),a.current<=t.openedAt&&(a.current=t.openedAt+1)),s()},t(`HEARTBEAT`);let n=setInterval(()=>{t(`HEARTBEAT`),s()},Fse),c=()=>t(`RELEASE`);return window.addEventListener(`beforeunload`,c),()=>{window.removeEventListener(`beforeunload`,c),clearInterval(n),t(`RELEASE`),e.close(),o.current=null}},[s]);let c=(0,_.useCallback)(()=>{a.current=0,o.current?.postMessage({type:`TAKEOVER`,id:i.current,openedAt:0}),s()},[s]);return(0,V.jsxs)(V.Fragment,{children:[t&&e,!t&&(0,V.jsx)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center bg-black/80 backdrop-blur-sm`,role:`dialog`,"aria-modal":`true`,children:(0,V.jsxs)(`div`,{className:`mx-4 max-w-md space-y-4 rounded-lg border bg-background p-6 text-center shadow-lg`,children:[(0,V.jsx)(`h2`,{className:`text-lg font-semibold`,children:`LeLab is already open in another tab`}),(0,V.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Only one tab can control the robot at a time. Switch back to the original tab, or take over here — the other tab will lock.`}),(0,V.jsx)(q,{onClick:c,children:`Use this tab`})]})})]})},Q9=`lelab:teleop-stopped`,Rse=()=>{let{toast:e}=$i();return(0,_.useEffect)(()=>{let t=!1;try{t=sessionStorage.getItem(Q9)===`1`,t&&sessionStorage.removeItem(Q9)}catch{}t&&e({title:`Teleoperation stopped`,description:`The arm was disconnected cleanly when you left the page.`})},[e]),null},$9=`lelab:update-dismissed-sha`;function zse(){let{baseUrl:e,fetchWithHeaders:t}=Tl(),[n,r]=(0,_.useState)(null),[i,a]=(0,_.useState)(!1);return(0,_.useEffect)(()=>{if(Nf())return;let n=!1;return t(`${e}/system/update-check`).then(e=>e.ok?e.json():null).then(e=>{if(n||!e||!e.update_available)return;let t=null;try{t=localStorage.getItem($9)}catch{}t&&t===e.latest_commit||(r(e),a(!0))}).catch(()=>{}),()=>{n=!0}},[e,t]),{status:n,open:i,dismiss:(0,_.useCallback)(e=>{if(e&&n?.latest_commit)try{localStorage.setItem($9,n.latest_commit)}catch{}a(!1)},[n])}}var Bse=()=>{let{status:e,open:t,dismiss:n}=zse(),{baseUrl:r,fetchWithHeaders:i}=Tl(),{toast:a}=$i(),[o,s]=(0,_.useState)(!1),[c,l]=(0,_.useState)(!1),[u,d]=(0,_.useState)(null);if(!e)return null;let f=typeof e.commits_behind==`number`&&e.commits_behind>0?`${e.commits_behind} commit${e.commits_behind===1?``:`s`} behind`:`A new version is available`;return(0,V.jsx)(nf,{open:t,onOpenChange:e=>{!e&&!c&&n(o)},children:(0,V.jsxs)(of,{className:`bg-slate-800 border-slate-700 text-white max-w-lg`,onOpenAutoFocus:e=>e.preventDefault(),children:[(0,V.jsxs)(sf,{children:[(0,V.jsxs)(lf,{className:`flex items-center gap-3 text-white`,children:[(0,V.jsx)(qs,{className:`w-5 h-5 text-amber-400`}),`LeLab update available`]}),(0,V.jsxs)(uf,{className:`text-slate-300`,children:[`You're `,f,` 😱.`,(0,V.jsx)(`br`,{}),`Update to get the latest fixes and features 🤗.`,e.compare_url&&(0,V.jsxs)(V.Fragment,{children:[` `,(0,V.jsx)(`a`,{href:e.compare_url,target:`_blank`,rel:`noreferrer`,className:`text-sky-300 underline hover:text-sky-200`,children:`See what changed`}),`.`]})]})]}),(0,V.jsxs)(`div`,{className:`space-y-4`,children:[(0,V.jsxs)(rv,{children:[(0,V.jsxs)(iv,{className:`group flex items-center gap-1.5 text-xs font-medium text-slate-300 hover:text-white transition-colors`,children:[(0,V.jsx)(ds,{className:`w-3.5 h-3.5 transition-transform group-data-[state=open]:rotate-90`}),`Or update manually`]}),(0,V.jsx)(av,{className:`pt-2`,children:(0,V.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,V.jsx)(`code`,{className:`min-w-0 flex-1 px-2 py-1.5 rounded bg-slate-900 text-sky-300 text-xs break-all whitespace-pre-wrap`,children:e.update_command}),(0,V.jsx)(q,{variant:`outline`,size:`icon`,onClick:async()=>{if(e.update_command)try{await navigator.clipboard.writeText(e.update_command),a({title:`Copied`,description:`Update command copied to clipboard.`})}catch{a({title:`Copy failed`,description:`Select and copy the command manually.`,variant:`destructive`})}},title:`Copy command`,className:`shrink-0 bg-slate-900 border-slate-600 text-white hover:bg-slate-700`,children:(0,V.jsx)(Ss,{className:`w-4 h-4`})})]})})]}),u&&(0,V.jsx)(`pre`,{className:`max-h-40 overflow-auto rounded bg-slate-900 p-2 text-xs text-slate-300 whitespace-pre-wrap`,children:u}),(0,V.jsxs)(`div`,{className:`flex items-center justify-between gap-3 pt-1`,children:[(0,V.jsxs)(`label`,{className:`flex items-center gap-2 text-sm text-slate-300`,children:[(0,V.jsx)(J_,{checked:o,onCheckedChange:e=>s(e===!0),className:`border-slate-300 data-[state=checked]:bg-slate-300 data-[state=checked]:text-slate-900`}),`Don't ask me again`]}),(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,V.jsx)(q,{variant:`ghost`,onClick:()=>n(o),disabled:c,className:`text-slate-300 hover:bg-slate-700 hover:text-white`,children:`Later`}),e.can_auto_update&&(0,V.jsx)(q,{onClick:async()=>{l(!0),d(null);try{let e=await(await i(`${r}/system/update`,{method:`POST`})).json();e.success?(a({title:`Updated`,description:e.message}),n(!1)):(d(e.output||e.message),a({title:`Update failed`,description:e.message,variant:`destructive`}))}catch(e){a({title:`Update failed`,description:e instanceof Error?e.message:String(e),variant:`destructive`})}finally{l(!1)}},disabled:c,children:c?(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Ms,{className:`w-4 h-4 mr-2 animate-spin`}),`Updating…`]}):`Update now`})]})]})]})]})})},Vse=new Xr;function Hse(){return(0,V.jsx)($r,{client:Vse,children:(0,V.jsx)(uh,{children:(0,V.jsx)(ti,{children:(0,V.jsx)(wl,{children:(0,V.jsx)(Dl,{children:(0,V.jsx)(Ri,{children:(0,V.jsx)(Vi,{children:(0,V.jsxs)(jn,{children:[(0,V.jsx)(Lse,{children:(0,V.jsxs)(Yf,{children:[(0,V.jsx)(Rse,{}),(0,V.jsx)(Bse,{}),(0,V.jsxs)(Vt,{children:[(0,V.jsx)(B,{path:`/`,element:(0,V.jsx)(tx,{})}),(0,V.jsx)(B,{path:`/teleoperation`,element:(0,V.jsx)(gN,{})}),(0,V.jsx)(B,{path:`/recording`,element:(0,V.jsx)(ure,{})}),(0,V.jsx)(B,{path:`/upload`,element:(0,V.jsx)(Mse,{})}),(0,V.jsx)(B,{path:`/training`,element:(0,V.jsx)(K9,{})}),(0,V.jsx)(B,{path:`/training/:jobId`,element:(0,V.jsx)(K9,{})}),(0,V.jsx)(B,{path:`/inference`,element:(0,V.jsx)(_se,{})}),(0,V.jsx)(B,{path:`/calibration`,element:(0,V.jsx)(PN,{})}),(0,V.jsx)(B,{path:`/edit-dataset`,element:(0,V.jsx)(jse,{})}),(0,V.jsx)(B,{path:`*`,element:(0,V.jsx)(Nse,{})})]})]})}),(0,V.jsx)(ol,{})]})})})})})})})})}(0,y.createRoot)(document.getElementById(`root`)).render((0,V.jsx)(Hse,{})); \ No newline at end of file +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function A9(e,t){if(e){if(typeof e==`string`)return j9(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if(n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`)return Array.from(e);if(n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return j9(e,t)}}function Goe(e){if(typeof Symbol<`u`&&e[Symbol.iterator]!=null||e[`@@iterator`]!=null)return Array.from(e)}function Koe(e){if(Array.isArray(e))return j9(e)}function j9(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n0?a:e&&e.length&&Q(r)&&Q(i)?e.slice(r,i+1):[]};function R9(e){return e===`number`?[0,`auto`]:void 0}var z9=function(e,t,n,r){var i=e.graphicalItems,a=e.tooltipAxis,o=L9(t,e);return n<0||!i||!i.length||n>=o.length?null:i.reduce(function(i,s){var c=s.props.data??t;c&&e.dataStartIndex+e.dataEndIndex!==0&&e.dataEndIndex-e.dataStartIndex>=n&&(c=c.slice(e.dataStartIndex,e.dataEndIndex+1));var l=a.dataKey&&!a.allowDuplicatedCategory?xR(c===void 0?o:c,a.dataKey,r):c&&c[n]||o[n];return l?[].concat(k9(i),[E1(s,l)]):i},[])},B9=function(e,t,n,r){var i=r||{x:e.chartX,y:e.chartY},a=Xoe(i,n),o=e.orderedTooltipTicks,s=e.tooltipAxis,c=e.tooltipTicks,l=q$(a,o,c,s);if(l>=0&&c){var u=c[l]&&c[l].value;return{activeTooltipIndex:l,activeLabel:u,activePayload:z9(e,t,l,u),activeCoordinate:Zoe(n,o,l,i)}}return null},Qoe=function(e,t){var n=t.axes,r=t.graphicalItems,i=t.axisType,a=t.axisIdKey,o=t.stackGroups,s=t.dataStartIndex,c=t.dataEndIndex,l=e.layout,u=e.children,d=e.stackOffset,f=n1(l,i);return n.reduce(function(t,n){var p=n.type.defaultProps===void 0?n.props:$($({},n.type.defaultProps),n.props),m=p.type,h=p.dataKey,g=p.allowDataOverflow,_=p.allowDuplicatedCategory,v=p.scale,y=p.ticks,b=p.includeHidden,x=p[a];if(t[x])return t;var S=L9(e.data,{graphicalItems:r.filter(function(e){return(a in e.props?e.props[a]:e.type.defaultProps?.[a])===x}),dataStartIndex:s,dataEndIndex:c}),C=S.length,w,T,E;Toe(p.domain,g,m)&&(w=C1(p.domain,null,g),f&&(m===`number`||v!==`auto`)&&(E=K$(S,h,`category`)));var D=R9(m);if(!w||w.length===0){var O=p.domain??D;if(h){if(w=K$(S,h,m),m===`category`&&f){var k=yR(w);_&&k?(T=w,w=(0,x8.default)(0,C)):_||(w=T1(O,w,n).reduce(function(e,t){return e.indexOf(t)>=0?e:[].concat(k9(e),[t])},[]))}else if(m===`category`)w=_?w.filter(function(e){return e!==``&&!(0,uR.default)(e)}):T1(O,w,n).reduce(function(e,t){return e.indexOf(t)>=0||t===``||(0,uR.default)(t)?e:[].concat(k9(e),[t])},[]);else if(m===`number`){var A=e1(S,r.filter(function(e){var t=a in e.props?e.props[a]:e.type.defaultProps?.[a],n=`hide`in e.props?e.props.hide:e.type.defaultProps?.hide;return t===x&&(b||!n)}),h,i,l);A&&(w=A)}f&&(m===`number`||v!==`auto`)&&(E=K$(S,h,`category`))}else w=f?(0,x8.default)(0,C):o&&o[x]&&o[x].hasStack&&m===`number`?d===`expand`?[0,1]:b1(o[x].stackGroups,s,c):t1(S,r.filter(function(e){var t=a in e.props?e.props[a]:e.type.defaultProps[a],n=`hide`in e.props?e.props.hide:e.type.defaultProps.hide;return t===x&&(b||!n)}),m,l,!0);if(m===`number`)w=u9(u,w,x,i,y),O&&(w=C1(O,w,g));else if(m===`category`&&O){var j=O;w.every(function(e){return j.indexOf(e)>=0})&&(w=j)}}return $($({},t),{},N9({},x,$($({},p),{},{axisType:i,domain:w,categoricalDomain:E,duplicateDomain:T,originalDomain:p.domain??D,isCategorical:f,layout:l})))},{})},$oe=function(e,t){var n=t.graphicalItems,r=t.Axis,i=t.axisType,a=t.axisIdKey,o=t.stackGroups,s=t.dataStartIndex,c=t.dataEndIndex,l=e.layout,u=e.children,d=L9(e.data,{graphicalItems:n,dataStartIndex:s,dataEndIndex:c}),f=d.length,p=n1(l,i),m=-1;return n.reduce(function(e,t){var h=(t.type.defaultProps===void 0?t.props:$($({},t.type.defaultProps),t.props))[a],g=R9(`number`);if(!e[h]){m++;var _;return p?_=(0,x8.default)(0,f):o&&o[h]&&o[h].hasStack?(_=b1(o[h].stackGroups,s,c),_=u9(u,_,h,i)):(_=C1(g,t1(d,n.filter(function(e){var t=a in e.props?e.props[a]:e.type.defaultProps?.[a],n=`hide`in e.props?e.props.hide:e.type.defaultProps?.hide;return t===h&&!n}),`number`,l),r.defaultProps.allowDataOverflow),_=u9(u,_,h,i)),$($({},e),{},N9({},h,$($({axisType:i},r.defaultProps),{},{hide:!0,orientation:(0,cR.default)(Joe,`${i}.${m%2}`,null),domain:_,originalDomain:g,isCategorical:p,layout:l})))}return e},{})},ese=function(e,t){var n=t.axisType,r=n===void 0?`xAxis`:n,i=t.AxisComp,a=t.graphicalItems,o=t.stackGroups,s=t.dataStartIndex,c=t.dataEndIndex,l=e.children,u=`${r}Id`,d=KR(l,i),f={};return d&&d.length?f=Qoe(e,{axes:d,graphicalItems:a,axisType:r,axisIdKey:u,stackGroups:o,dataStartIndex:s,dataEndIndex:c}):a&&a.length&&(f=$oe(e,{Axis:i,graphicalItems:a,axisType:r,axisIdKey:u,stackGroups:o,dataStartIndex:s,dataEndIndex:c})),f},tse=function(e){var t=vR(e),n=r1(t,!1,!0);return{tooltipTicks:n,orderedTooltipTicks:(0,BU.default)(n,function(e){return e.coordinate}),tooltipAxis:t,tooltipAxisBandSize:w1(t,n)}},V9=function(e){var t=e.children,n=e.defaultShowTooltip,r=qR(t,N8),i=0,a=0;return e.data&&e.data.length!==0&&(a=e.data.length-1),r&&r.props&&(r.props.startIndex>=0&&(i=r.props.startIndex),r.props.endIndex>=0&&(a=r.props.endIndex)),{chartX:0,chartY:0,dataStartIndex:i,dataEndIndex:a,activeTooltipIndex:-1,isTooltipActive:!!n}},nse=function(e){return!e||!e.length?!1:e.some(function(e){var t=HR(e&&e.type);return t&&t.indexOf(`Bar`)>=0})},H9=function(e){return e===`horizontal`?{numericAxisName:`yAxis`,cateAxisName:`xAxis`}:e===`vertical`?{numericAxisName:`xAxis`,cateAxisName:`yAxis`}:e===`centric`?{numericAxisName:`radiusAxis`,cateAxisName:`angleAxis`}:{numericAxisName:`angleAxis`,cateAxisName:`radiusAxis`}},rse=function(e,t){var n=e.props,r=e.graphicalItems,i=e.xAxisMap,a=i===void 0?{}:i,o=e.yAxisMap,s=o===void 0?{}:o,c=n.width,l=n.height,u=n.children,d=n.margin||{},f=qR(u,N8),p=qR(u,vU),m=Object.keys(s).reduce(function(e,t){var n=s[t],r=n.orientation;return!n.mirror&&!n.hide?$($({},e),{},N9({},r,e[r]+n.width)):e},{left:d.left||0,right:d.right||0}),h=$($({},Object.keys(a).reduce(function(e,t){var n=a[t],r=n.orientation;return!n.mirror&&!n.hide?$($({},e),{},N9({},r,(0,cR.default)(e,`${r}`)+n.height)):e},{top:d.top||0,bottom:d.bottom||0})),m),g=h.bottom;f&&(h.bottom+=f.props.height||N8.defaultProps.height),p&&t&&(h=Z$(h,r,n,t));var _=c-h.left-h.right,v=l-h.top-h.bottom;return $($({brushBottom:g},h),{},{width:Math.max(_,0),height:Math.max(v,0)})},ise=function(e,t){if(t===`xAxis`)return e[t].width;if(t===`yAxis`)return e[t].height},U9=function(e){var t=e.chartName,n=e.GraphicalChild,r=e.defaultTooltipEventType,i=r===void 0?`axis`:r,a=e.validateTooltipEventTypes,o=a===void 0?[`axis`]:a,s=e.axisComponents,c=e.legendContent,l=e.formatAxisMap,u=e.defaultProps,d=function(e,t){var n=t.graphicalItems,r=t.stackGroups,i=t.offset,a=t.updateId,o=t.dataStartIndex,c=t.dataEndIndex,l=e.barSize,u=e.layout,d=e.barGap,f=e.barCategoryGap,p=e.maxBarSize,m=H9(u),h=m.numericAxisName,g=m.cateAxisName,_=nse(n),v=[];return n.forEach(function(n,m){var y=L9(e.data,{graphicalItems:[n],dataStartIndex:o,dataEndIndex:c}),b=n.type.defaultProps===void 0?n.props:$($({},n.type.defaultProps),n.props),x=b.dataKey,S=b.maxBarSize,C=b[`${h}Id`],w=b[`${g}Id`],T=s.reduce(function(e,n){var r=t[`${n.axisType}Map`],i=b[`${n.axisType}Id`];!(r&&r[i]||n.axisType===`zAxis`)&&XQ(!1);var a=r[i];return $($({},e),{},N9(N9({},n.axisType,a),`${n.axisType}Ticks`,r1(a)))},{}),E=T[g],D=T[`${g}Ticks`],O=r&&r[C]&&r[C].hasStack&&v1(n,r[C].stackGroups),k=HR(n.type).indexOf(`Bar`)>=0,A=w1(E,D),j=[],M=_&&Y$({barSize:l,stackGroups:r,totalSize:ise(T,g)});if(k){var N=(0,uR.default)(S)?p:S,P=w1(E,D,!0)??N??0;j=X$({barGap:d,barCategoryGap:f,bandSize:P===A?A:P,sizeList:M[w],maxBarSize:N}),P!==A&&(j=j.map(function(e){return $($({},e),{},{position:$($({},e.position),{},{offset:e.position.offset-P/2})})}))}var F=n&&n.type&&n.type.getComposedData;F&&v.push({props:$($({},F($($({},T),{},{displayedData:y,props:e,dataKey:x,item:n,bandSize:A,barPosition:j,offset:i,stackedData:O,layout:u,dataStartIndex:o,dataEndIndex:c}))),{},N9(N9(N9({key:n.key||`item-${m}`},h,T[h]),g,T[g]),`animationId`,a)),childIndex:iz(n,e.children),item:n})}),v},f=function(e,r){var i=e.props,a=e.dataStartIndex,o=e.dataEndIndex,c=e.updateId;if(!JR({props:i}))return null;var u=i.children,f=i.layout,p=i.stackOffset,m=i.data,h=i.reverseStackOrder,g=H9(f),_=g.numericAxisName,v=g.cateAxisName,y=KR(u,n),b=p1(m,y,`${_}Id`,`${v}Id`,p,h),x=s.reduce(function(e,t){var n=`${t.axisType}Map`;return $($({},e),{},N9({},n,ese(i,$($({},t),{},{graphicalItems:y,stackGroups:t.axisType===_&&b,dataStartIndex:a,dataEndIndex:o}))))},{}),S=rse($($({},x),{},{props:i,graphicalItems:y}),r?.legendBBox);Object.keys(x).forEach(function(e){x[e]=l(i,x[e],S,e.replace(`Map`,``),t)});var C=x[`${v}Map`],w=tse(C);return $($({formattedGraphicalItems:d(i,$($({},x),{},{dataStartIndex:a,dataEndIndex:o,updateId:c,graphicalItems:y,stackGroups:b,offset:S})),graphicalItems:y,offset:S,stackGroups:b},w),x)},p=function(e){function n(e){var r;return Roe(this,n),r=Boe(this,n,[e]),N9(r,`eventEmitterSymbol`,Symbol(`rechartsEventEmitter`)),N9(r,`accessibilityManager`,new woe),N9(r,`handleLegendBBoxUpdate`,function(e){if(e){var t=r.state,n=t.dataStartIndex,i=t.dataEndIndex,a=t.updateId;r.setState($({legendBBox:e},f({props:r.props,dataStartIndex:n,dataEndIndex:i,updateId:a},$($({},r.state),{},{legendBBox:e}))))}}),N9(r,`handleReceiveSyncEvent`,function(e,t,n){if(r.props.syncId===e){if(n===r.eventEmitterSymbol&&typeof r.props.syncMethod!=`function`)return;r.applySyncEvent(t)}}),N9(r,`handleBrushChange`,function(e){var t=e.startIndex,n=e.endIndex;if(t!==r.state.dataStartIndex||n!==r.state.dataEndIndex){var i=r.state.updateId;r.setState(function(){return $({dataStartIndex:t,dataEndIndex:n},f({props:r.props,dataStartIndex:t,dataEndIndex:n,updateId:i},r.state))}),r.triggerSyncEvent({dataStartIndex:t,dataEndIndex:n})}}),N9(r,`handleMouseEnter`,function(e){var t=r.getMouseInfo(e);if(t){var n=$($({},t),{},{isTooltipActive:!0});r.setState(n),r.triggerSyncEvent(n);var i=r.props.onMouseEnter;(0,PR.default)(i)&&i(n,e)}}),N9(r,`triggeredAfterMouseMove`,function(e){var t=r.getMouseInfo(e),n=t?$($({},t),{},{isTooltipActive:!0}):{isTooltipActive:!1};r.setState(n),r.triggerSyncEvent(n);var i=r.props.onMouseMove;(0,PR.default)(i)&&i(n,e)}),N9(r,`handleItemMouseEnter`,function(e){r.setState(function(){return{isTooltipActive:!0,activeItem:e,activePayload:e.tooltipPayload,activeCoordinate:e.tooltipPosition||{x:e.cx,y:e.cy}}})}),N9(r,`handleItemMouseLeave`,function(){r.setState(function(){return{isTooltipActive:!1}})}),N9(r,`handleMouseMove`,function(e){e.persist(),r.throttleTriggeredAfterMouseMove(e)}),N9(r,`handleMouseLeave`,function(e){r.throttleTriggeredAfterMouseMove.cancel();var t={isTooltipActive:!1};r.setState(t),r.triggerSyncEvent(t);var n=r.props.onMouseLeave;(0,PR.default)(n)&&n(t,e)}),N9(r,`handleOuterEvent`,function(e){var t=rz(e),n=(0,cR.default)(r.props,`${t}`);t&&(0,PR.default)(n)&&n((/.*touch.*/i.test(t)?r.getMouseInfo(e.changedTouches[0]):r.getMouseInfo(e))??{},e)}),N9(r,`handleClick`,function(e){var t=r.getMouseInfo(e);if(t){var n=$($({},t),{},{isTooltipActive:!0});r.setState(n),r.triggerSyncEvent(n);var i=r.props.onClick;(0,PR.default)(i)&&i(n,e)}}),N9(r,`handleMouseDown`,function(e){var t=r.props.onMouseDown;(0,PR.default)(t)&&t(r.getMouseInfo(e),e)}),N9(r,`handleMouseUp`,function(e){var t=r.props.onMouseUp;(0,PR.default)(t)&&t(r.getMouseInfo(e),e)}),N9(r,`handleTouchMove`,function(e){e.changedTouches!=null&&e.changedTouches.length>0&&r.throttleTriggeredAfterMouseMove(e.changedTouches[0])}),N9(r,`handleTouchStart`,function(e){e.changedTouches!=null&&e.changedTouches.length>0&&r.handleMouseDown(e.changedTouches[0])}),N9(r,`handleTouchEnd`,function(e){e.changedTouches!=null&&e.changedTouches.length>0&&r.handleMouseUp(e.changedTouches[0])}),N9(r,`handleDoubleClick`,function(e){var t=r.props.onDoubleClick;(0,PR.default)(t)&&t(r.getMouseInfo(e),e)}),N9(r,`handleContextMenu`,function(e){var t=r.props.onContextMenu;(0,PR.default)(t)&&t(r.getMouseInfo(e),e)}),N9(r,`triggerSyncEvent`,function(e){r.props.syncId!==void 0&&d9.emit(f9,r.props.syncId,e,r.eventEmitterSymbol)}),N9(r,`applySyncEvent`,function(e){var t=r.props,n=t.layout,i=t.syncMethod,a=r.state.updateId,o=e.dataStartIndex,s=e.dataEndIndex;if(e.dataStartIndex!==void 0||e.dataEndIndex!==void 0)r.setState($({dataStartIndex:o,dataEndIndex:s},f({props:r.props,dataStartIndex:o,dataEndIndex:s,updateId:a},r.state)));else if(e.activeTooltipIndex!==void 0){var c=e.chartX,l=e.chartY,u=e.activeTooltipIndex,d=r.state,p=d.offset,m=d.tooltipTicks;if(!p)return;if(typeof i==`function`)u=i(m,e);else if(i===`value`){u=-1;for(var h=0;h=0){var D,O;if(c.dataKey&&!c.allowDuplicatedCategory){var k=typeof c.dataKey==`function`?E:`payload.${c.dataKey.toString()}`;D=xR(m,k,u),O=h&&g&&xR(g,k,u)}else D=m?.[l],O=h&&g&&g[l];if(S||x){var A=e.props.activeIndex===void 0?l:e.props.activeIndex;return[(0,_.cloneElement)(e,$($($({},i.props),w),{},{activeIndex:A})),null,null]}if(!(0,uR.default)(D))return[T].concat(k9(r.renderActivePoints({item:i,activePoint:D,basePoint:O,childIndex:l,isRange:h})))}else{var j=(r.getItemByXY(r.state.activeCoordinate)??{graphicalItem:T}).graphicalItem,M=j.item,N=M===void 0?e:M,P=j.childIndex;return[(0,_.cloneElement)(N,$($($({},i.props),w),{},{activeIndex:P})),null,null]}return h?[T,null,null]:[T,null]}),N9(r,`renderCustomized`,function(e,t,n){return(0,_.cloneElement)(e,$($({key:`recharts-customized-${n}`},r.props),r.state))}),N9(r,`renderMap`,{CartesianGrid:{handler:I9,once:!0},ReferenceArea:{handler:r.renderReferenceElement},ReferenceLine:{handler:I9},ReferenceDot:{handler:r.renderReferenceElement},XAxis:{handler:I9},YAxis:{handler:I9},Brush:{handler:r.renderBrush,once:!0},Bar:{handler:r.renderGraphicChild},Line:{handler:r.renderGraphicChild},Area:{handler:r.renderGraphicChild},Radar:{handler:r.renderGraphicChild},RadialBar:{handler:r.renderGraphicChild},Scatter:{handler:r.renderGraphicChild},Pie:{handler:r.renderGraphicChild},Funnel:{handler:r.renderGraphicChild},Tooltip:{handler:r.renderCursor,once:!0},PolarGrid:{handler:r.renderPolarGrid,once:!0},PolarAngleAxis:{handler:r.renderPolarAxis},PolarRadiusAxis:{handler:r.renderPolarAxis},Customized:{handler:r.renderCustomized}}),r.clipPathId=`${e.id??gR(`recharts`)}-clip`,r.throttleTriggeredAfterMouseMove=(0,tG.default)(r.triggeredAfterMouseMove,e.throttleDelay??1e3/60),r.state={},r}return Uoe(n,e),zoe(n,[{key:`componentDidMount`,value:function(){this.addListener(),this.accessibilityManager.setDetails({container:this.container,offset:{left:this.props.margin.left??0,top:this.props.margin.top??0},coordinateList:this.state.tooltipTicks,mouseHandlerCallback:this.triggeredAfterMouseMove,layout:this.props.layout}),this.displayDefaultTooltip()}},{key:`displayDefaultTooltip`,value:function(){var e=this.props,t=e.children,n=e.data,r=e.height,i=e.layout,a=qR(t,YW);if(a){var o=a.props.defaultIndex;if(!(typeof o!=`number`||o<0||o>this.state.tooltipTicks.length-1)){var s=this.state.tooltipTicks[o]&&this.state.tooltipTicks[o].value,c=z9(this.state,n,o,s),l=this.state.tooltipTicks[o].coordinate,u=(this.state.offset.top+r)/2,d=i===`horizontal`?{x:l,y:u}:{y:l,x:u},f=this.state.formattedGraphicalItems.find(function(e){return e.item.type.name===`Scatter`});f&&(d=$($({},d),f.props.points[o].tooltipPosition),c=f.props.points[o].tooltipPayload);var p={activeTooltipIndex:o,isTooltipActive:!0,activeLabel:s,activePayload:c,activeCoordinate:d};this.setState(p),this.renderCursor(a),this.accessibilityManager.setIndex(o)}}}},{key:`getSnapshotBeforeUpdate`,value:function(e,t){return this.props.accessibilityLayer?(this.state.tooltipTicks!==t.tooltipTicks&&this.accessibilityManager.setDetails({coordinateList:this.state.tooltipTicks}),this.props.layout!==e.layout&&this.accessibilityManager.setDetails({layout:this.props.layout}),this.props.margin!==e.margin&&this.accessibilityManager.setDetails({offset:{left:this.props.margin.left??0,top:this.props.margin.top??0}}),null):null}},{key:`componentDidUpdate`,value:function(e){ez([qR(e.children,YW)],[qR(this.props.children,YW)])||this.displayDefaultTooltip()}},{key:`componentWillUnmount`,value:function(){this.removeListener(),this.throttleTriggeredAfterMouseMove.cancel()}},{key:`getTooltipEventType`,value:function(){var e=qR(this.props.children,YW);if(e&&typeof e.props.shared==`boolean`){var t=e.props.shared?`axis`:`item`;return o.indexOf(t)>=0?t:i}return i}},{key:`getMouseInfo`,value:function(e){if(!this.container)return null;var t=this.container,n=t.getBoundingClientRect(),r=OG(n),i={chartX:Math.round(e.pageX-r.left),chartY:Math.round(e.pageY-r.top)},a=n.width/t.offsetWidth||1,o=this.inRange(i.chartX,i.chartY,a);if(!o)return null;var s=this.state,c=s.xAxisMap,l=s.yAxisMap,u=this.getTooltipEventType(),d=B9(this.state,this.props.data,this.props.layout,o);if(u!==`axis`&&c&&l){var f=vR(c).scale,p=vR(l).scale,m=f&&f.invert?f.invert(i.chartX):null,h=p&&p.invert?p.invert(i.chartY):null;return $($({},i),{},{xValue:m,yValue:h},d)}return d?$($({},i),d):null}},{key:`inRange`,value:function(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,r=this.props.layout,i=e/n,a=t/n;if(r===`horizontal`||r===`vertical`){var o=this.state.offset;return i>=o.left&&i<=o.left+o.width&&a>=o.top&&a<=o.top+o.height?{x:i,y:a}:null}var s=this.state,c=s.angleAxisMap,l=s.radiusAxisMap;if(c&&l){var u=vR(c);return B1({x:i,y:a},u)}return null}},{key:`parseEventsOfWrapper`,value:function(){var e=this.props.children,t=this.getTooltipEventType(),n=qR(e,YW),r={};return n&&t===`axis`&&(r=n.props.trigger===`click`?{onClick:this.handleClick}:{onMouseEnter:this.handleMouseEnter,onDoubleClick:this.handleDoubleClick,onMouseMove:this.handleMouseMove,onMouseLeave:this.handleMouseLeave,onTouchMove:this.handleTouchMove,onTouchStart:this.handleTouchStart,onTouchEnd:this.handleTouchEnd,onContextMenu:this.handleContextMenu}),$($({},jR(this.props,this.handleOuterEvent)),r)}},{key:`addListener`,value:function(){d9.on(f9,this.handleReceiveSyncEvent)}},{key:`removeListener`,value:function(){d9.removeListener(f9,this.handleReceiveSyncEvent)}},{key:`filterFormatItem`,value:function(e,t,n){for(var r=this.state.formattedGraphicalItems,i=0,a=r.length;i{let[i,a]=(0,_.useState)([]),[o,s]=(0,_.useState)([]),c=(0,_.useRef)(0),{baseUrl:l,fetchWithHeaders:u}=Tl();(0,_.useEffect)(()=>{let t=!1;return bf(l,u,e).then(e=>{if(t||e.length===0)return;let n=e.filter(e=>e.loss!=null).map(e=>({step:e.step,loss:e.loss})).slice(-2e3),r=e.filter(e=>e.lr!=null).map(e=>({step:e.step,lr:e.lr})).slice(-2e3);a(n),s(r),c.current=e[e.length-1]?.step??0}).catch(()=>{}),()=>{t=!0}},[l,u,e]),(0,_.useEffect)(()=>{let e=t.current_step;if(e0&&t.current_loss!=null){let n=t.current_loss;a(t=>{let r=t[t.length-1];return r&&r.step===e?t:[...t,{step:e,loss:n}].slice(-2e3)})}if(e>0&&t.current_lr!=null){let n=t.current_lr;s(t=>{let r=t[t.length-1];return r&&r.step===e?t:[...t,{step:e,lr:n}].slice(-2e3)})}},[t.current_step,t.current_loss,t.current_lr]);let d=n(),f=t.training_active&&t.total_steps===0,p=f?`Training starting…`:`${t.current_step.toLocaleString()} / ${t.total_steps.toLocaleString()}`,m=t.eta_seconds==null?`—`:r(t.eta_seconds);return(0,V.jsxs)(`div`,{className:`space-y-6`,children:[(0,V.jsx)(_b,{className:`bg-slate-800/50 border-slate-700 rounded-xl`,children:(0,V.jsxs)(xb,{className:`p-6`,children:[(0,V.jsxs)(`div`,{className:`flex items-baseline justify-between mb-3`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,V.jsx)(`div`,{className:`flex h-9 w-9 items-center justify-center rounded-lg bg-blue-500/20 text-blue-400`,children:(0,V.jsx)(is,{className:`w-5 h-5`})}),(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`h3`,{className:`text-sm text-slate-400`,children:`Progress`}),(0,V.jsx)(`div`,{className:`text-base font-semibold text-white`,children:p})]})]}),(0,V.jsxs)(`div`,{className:`flex items-center gap-2 text-slate-300`,children:[(0,V.jsx)(bs,{className:`w-4 h-4 text-purple-400`}),(0,V.jsxs)(`span`,{className:`text-sm`,children:[`ETA `,(0,V.jsx)(`span`,{className:`font-semibold text-white`,children:m})]})]})]}),(0,V.jsxs)(`div`,{className:`relative h-8 w-full overflow-hidden rounded-md bg-slate-900 border border-slate-700`,children:[(0,V.jsx)(`div`,{className:`h-full bg-gradient-to-r from-blue-500 to-sky-400 transition-[width] duration-500`,style:{width:`${d}%`}}),(0,V.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center font-semibold text-white text-sm tabular-nums drop-shadow`,children:f?`warming up…`:`${d.toFixed(1)}%`})]})]})}),(0,V.jsxs)(`div`,{className:`grid grid-cols-1 lg:grid-cols-2 gap-6`,children:[(0,V.jsxs)(_b,{className:`bg-slate-800/50 border-slate-700 rounded-xl`,children:[(0,V.jsx)(vb,{className:`pb-2`,children:(0,V.jsxs)(yb,{className:`flex items-center gap-3 text-white text-base`,children:[(0,V.jsx)(`div`,{className:`flex h-8 w-8 items-center justify-center rounded-lg bg-green-500/20 text-green-400`,children:(0,V.jsx)(hs,{className:`w-4 h-4`})}),(0,V.jsxs)(`span`,{children:[`Loss`,` `,(0,V.jsxs)(`span`,{className:`text-slate-400 text-sm font-normal`,children:[`(`,t.current_loss?.toFixed(4)??`—`,`)`]})]})]})}),(0,V.jsx)(xb,{className:`pt-0`,children:(0,V.jsx)(`div`,{className:`h-48`,children:i.length===0?(0,V.jsx)(`div`,{className:`flex h-full items-center justify-center text-slate-500 text-sm`,children:`Waiting for first metric tick…`}):(0,V.jsx)(mG,{width:`100%`,height:`100%`,children:(0,V.jsxs)(W9,{data:i,margin:{top:8,right:12,left:0,bottom:0},children:[(0,V.jsx)(Z7,{dataKey:`step`,tick:{fill:`#94a3b8`,fontSize:11},stroke:`#475569`}),(0,V.jsx)(s9,{tick:{fill:`#94a3b8`,fontSize:11},stroke:`#475569`,width:48}),(0,V.jsx)(YW,{contentStyle:{background:`#1e293b`,border:`1px solid #475569`,borderRadius:8},labelStyle:{color:`#cbd5e1`},itemStyle:{color:`#34d399`},formatter:e=>e.toFixed(4)}),(0,V.jsx)(k7,{type:`monotone`,dataKey:`loss`,stroke:`#34d399`,strokeWidth:2,dot:!1,isAnimationActive:!1})]})})})})]}),(0,V.jsxs)(_b,{className:`bg-slate-800/50 border-slate-700 rounded-xl`,children:[(0,V.jsx)(vb,{className:`pb-2`,children:(0,V.jsxs)(yb,{className:`flex items-center gap-3 text-white text-base`,children:[(0,V.jsx)(`div`,{className:`flex h-8 w-8 items-center justify-center rounded-lg bg-orange-500/20 text-orange-400`,children:(0,V.jsx)(is,{className:`w-4 h-4`})}),(0,V.jsxs)(`span`,{children:[`Learning Rate`,` `,(0,V.jsxs)(`span`,{className:`text-slate-400 text-sm font-normal`,children:[`(`,t.current_lr?.toExponential(2)??`—`,`)`]})]})]})}),(0,V.jsx)(xb,{className:`pt-0`,children:(0,V.jsx)(`div`,{className:`h-48`,children:o.length===0?(0,V.jsx)(`div`,{className:`flex h-full items-center justify-center text-slate-500 text-sm`,children:`Waiting for first metric tick…`}):(0,V.jsx)(mG,{width:`100%`,height:`100%`,children:(0,V.jsxs)(W9,{data:o,margin:{top:8,right:12,left:0,bottom:0},children:[(0,V.jsx)(Z7,{dataKey:`step`,tick:{fill:`#94a3b8`,fontSize:11},stroke:`#475569`}),(0,V.jsx)(s9,{tick:{fill:`#94a3b8`,fontSize:11},stroke:`#475569`,width:48,tickFormatter:e=>e.toExponential(0)}),(0,V.jsx)(YW,{contentStyle:{background:`#1e293b`,border:`1px solid #475569`,borderRadius:8},labelStyle:{color:`#cbd5e1`},itemStyle:{color:`#fb923c`},formatter:e=>e.toExponential(2)}),(0,V.jsx)(k7,{type:`monotone`,dataKey:`lr`,stroke:`#fb923c`,strokeWidth:2,dot:!1,isAnimationActive:!1})]})})})})]})]})]})},sse=({logs:e,logContainerRef:t})=>(0,V.jsxs)(_b,{className:`bg-slate-800/50 border-slate-700 rounded-xl`,children:[(0,V.jsx)(vb,{children:(0,V.jsxs)(yb,{className:`flex items-center gap-3 text-white`,children:[(0,V.jsx)(`div`,{className:`flex h-10 w-10 items-center justify-center rounded-lg bg-slate-700`,children:(0,V.jsx)(ks,{className:`w-5 h-5 text-sky-400`})}),`Training Logs`]})}),(0,V.jsx)(xb,{children:(0,V.jsx)(`div`,{ref:t,className:`bg-slate-900 rounded-lg p-4 h-96 overflow-y-auto font-mono text-sm border border-slate-700`,children:e.length===0?(0,V.jsx)(`div`,{className:`text-slate-500 py-8`,children:`No training logs yet. Start training to see output.`}):e.map((e,t)=>(0,V.jsxs)(`div`,{className:`text-slate-300 break-words whitespace-pre-wrap`,children:[(0,V.jsx)(`span`,{className:`text-slate-500 mr-2 select-none`,children:new Date(e.timestamp*1e3).toLocaleTimeString()}),e.message]},t))})})]}),cse=({installHint:e})=>{let t=uL(`system/training-extra`);return(0,V.jsx)(`div`,{className:`max-w-3xl mx-auto`,children:(0,V.jsxs)(_b,{className:`bg-slate-800/50 border-slate-700 rounded-xl`,children:[(0,V.jsx)(vb,{children:(0,V.jsxs)(yb,{className:`flex items-center gap-3 text-white`,children:[(0,V.jsx)(fL,{state:t.state}),dL(t.state,`Training Extra Not Installed`)]})}),(0,V.jsx)(xb,{className:`space-y-4`,children:(0,V.jsx)(pL,{state:t.state,error:t.error,logs:t.logs,logBoxRef:t.logBoxRef,onInstall:t.handleInstall,onRetry:t.handleRetry,installHint:e,packageName:`accelerate`,idleTitle:`Training Extra Not Installed`,idleDescription:(0,V.jsxs)(V.Fragment,{children:[`Training requires the`,` `,(0,V.jsx)(`code`,{className:`px-1 py-0.5 rounded bg-slate-900 text-sky-300`,children:`accelerate`}),` `,`package, which isn't installed in this environment. Install it to enable the Training page.`]}),doneDescription:(0,V.jsx)(mL,{purpose:`training`})})})]})})},lse=({open:e,onOpenChange:t,policyType:n,packageName:r,installTarget:i,installHint:a})=>{let o=uL(`system/policy-extra/${n}`,e),s=`${n.toUpperCase()} needs an extra package`;return(0,V.jsx)(nf,{open:e,onOpenChange:t,children:(0,V.jsxs)(of,{className:`bg-slate-800 border-slate-700 text-white max-w-2xl`,children:[(0,V.jsxs)(sf,{children:[(0,V.jsxs)(lf,{className:`flex items-center gap-3 text-white`,children:[(0,V.jsx)(fL,{state:o.state}),dL(o.state,s)]}),(0,V.jsxs)(uf,{className:`sr-only`,children:[`Install `,i,` to train `,n,`.`]})]}),(0,V.jsx)(`div`,{className:`space-y-4`,children:(0,V.jsx)(pL,{state:o.state,error:o.error,logs:o.logs,logBoxRef:o.logBoxRef,onInstall:o.handleInstall,onRetry:o.handleRetry,installHint:a,packageName:i,idleTitle:s,idleDescription:(0,V.jsxs)(V.Fragment,{children:[`Training a `,(0,V.jsx)(`span`,{className:`font-semibold`,children:n}),` policy needs the`,` `,(0,V.jsx)(`code`,{className:`px-1 py-0.5 rounded bg-slate-900 text-sky-300`,children:r}),` `,`package (installed via`,` `,(0,V.jsx)(`code`,{className:`px-1 py-0.5 rounded bg-slate-900 text-sky-300`,children:i}),`), which isn't in this environment yet. Install it to train this policy.`]}),doneDescription:(0,V.jsx)(mL,{purpose:`${n} training`})})})]})})},use=()=>{let{auth:e,refetch:t}=Ol(),{baseUrl:n,fetchWithHeaders:r}=Tl(),[i,a]=(0,_.useState)(``),[o,s]=(0,_.useState)(!1),[c,l]=(0,_.useState)(null);if(e.status===`authenticated`||e.status===`loading`)return null;let u=async()=>{let e=i.trim();if(e){s(!0),l(null);try{let i=await r(`${n}/hf-auth/login`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({token:e})});if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(e.detail||`HTTP ${i.status}`)}a(``),await t()}catch(e){l(e instanceof Error?e.message:String(e))}finally{s(!1)}}};return(0,V.jsx)(`div`,{className:`bg-amber-950/40 border border-amber-700/60 rounded-lg p-4 mb-6`,children:(0,V.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,V.jsx)(ms,{className:`w-5 h-5 text-amber-400 flex-shrink-0 mt-0.5`}),(0,V.jsxs)(`div`,{className:`flex-1 space-y-3`,children:[(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`p`,{className:`text-sm text-amber-100 font-medium`,children:`Hugging Face access required for cloud training`}),(0,V.jsxs)(`p`,{className:`text-xs text-amber-200/80 mt-1`,children:[`Create a token at`,` `,(0,V.jsxs)(`a`,{href:`https://huggingface.co/settings/tokens`,target:`_blank`,rel:`noreferrer`,className:`underline hover:text-amber-50 inline-flex items-center gap-1`,children:[`huggingface.co/settings/tokens`,(0,V.jsx)(Es,{className:`w-3 h-3`})]}),` `,`with `,(0,V.jsx)(`span`,{className:`font-mono`,children:`Write`}),` access (so trained policies can upload to your account), then paste it below.`]})]}),(0,V.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),u()},className:`flex gap-2`,children:[(0,V.jsx)(k_,{type:`password`,placeholder:`hf_...`,value:i,onChange:e=>a(e.target.value),className:`bg-slate-900 border-slate-600 text-white placeholder:text-slate-500`,disabled:o,autoComplete:`off`}),(0,V.jsx)(q,{type:`submit`,disabled:o||!i.trim(),className:`bg-amber-600 hover:bg-amber-700 text-white`,children:o?(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Ms,{className:`w-4 h-4 mr-2 animate-spin`}),`Saving…`]}):`Save token`})]}),c&&(0,V.jsx)(`p`,{className:`text-xs text-red-300`,children:c})]})]})})},dse=1e3,G9=5e3;function fse(e,t){return e?{training_active:e.state===`running`,current_step:e.metrics.current_step,total_steps:e.metrics.total_steps,current_loss:e.metrics.current_loss??void 0,current_lr:e.metrics.current_lr??void 0,grad_norm:e.metrics.grad_norm??void 0,eta_seconds:e.metrics.eta_seconds??void 0,available_controls:{stop_training:e.state===`running`,pause_training:!1,resume_training:!1}}:{training_active:t,current_step:0,total_steps:0,available_controls:{stop_training:!1,pause_training:!1,resume_training:!1}}}function pse(e){return{target:e.target,dataset_repo_id:e.dataset_repo_id,policy_type:e.policy_type,steps:e.steps,batch_size:e.batch_size,seed:e.seed,num_workers:e.num_workers,log_freq:e.log_freq,save_freq:e.save_freq,save_checkpoint:e.save_checkpoint,resume:e.resume,wandb_enable:e.wandb_enable,wandb_project:e.wandb_project,wandb_entity:e.wandb_entity,wandb_notes:e.wandb_notes,wandb_mode:e.wandb_mode,wandb_disable_artifact:e.wandb_disable_artifact,policy_device:e.policy_device,policy_use_amp:e.policy_use_amp,optimizer_type:e.optimizer_type,optimizer_lr:e.optimizer_lr,optimizer_weight_decay:e.optimizer_weight_decay,optimizer_grad_clip_norm:e.optimizer_grad_clip_norm,use_policy_training_preset:e.use_policy_training_preset,dataset_image_transforms_enable:e.dataset_image_transforms_enable,...e.policy_type===`groot`?{policy_base_model_path:e.policy_base_model_path,policy_embodiment_tag:e.policy_embodiment_tag,policy_chunk_size:e.policy_chunk_size,policy_n_action_steps:e.policy_n_action_steps,policy_use_relative_actions:e.policy_use_relative_actions,policy_relative_exclude_joints:e.policy_relative_exclude_joints,policy_use_bf16:e.policy_use_bf16}:{}}}var mse=()=>{let{baseUrl:e,fetchWithHeaders:t}=Tl(),{auth:n}=Ol(),{toast:r}=$i(),i=mt(),[a,o]=(0,_.useState)({target:{runner:`local`},dataset_repo_id:dt().state?.datasetRepoId??``,policy_type:`act`,steps:1e4,batch_size:8,seed:1e3,num_workers:4,log_freq:250,save_freq:1e3,save_checkpoint:!0,resume:!1,wandb_enable:!1,wandb_mode:`online`,wandb_disable_artifact:!1,policy_device:`cuda`,policy_use_amp:!1,optimizer_type:`adam`,use_policy_training_preset:!0}),[s,c]=(0,_.useState)([]),[l,u]=(0,_.useState)(!0),[d,f]=(0,_.useState)(null),[p,m]=(0,_.useState)(`pip install accelerate`),[h,g]=(0,_.useState)(!1),[v,y]=(0,_.useState)(!1),[b,x]=(0,_.useState)(null),[S,C]=(0,_.useState)(!1),[w,T]=(0,_.useState)([]),[E,D]=(0,_.useState)(!0);(0,_.useEffect)(()=>{u(!0),mf(e,t).then(c).catch(()=>c([])).finally(()=>u(!1))},[e,t]),(0,_.useEffect)(()=>{t(`${e}/system/training-extra`).then(e=>e.json()).then(e=>{f(e.available),m(e.install_hint)}).catch(()=>f(!0))},[e,t]),(0,_.useEffect)(()=>{gf(e,t,200).then(e=>g(e.some(e=>e.runner===`local`&&e.state===`running`))).catch(()=>g(!1))},[e,t]),(0,_.useEffect)(()=>{D(!0),Ef(e,t).then(e=>{C(e.authenticated),T(e.flavors)}).catch(()=>{C(!1),T([])}).finally(()=>D(!1))},[e,t,n.status]);let O=(e,t)=>{o(n=>({...n,[e]:t}))},k=async()=>{if(!a.dataset_repo_id.trim()){r({title:`Error`,description:`Dataset repository ID is required`,variant:`destructive`});return}if(a.target.runner===`local`)try{let n=await t(`${e}/system/policy-extra/${a.policy_type}`);if(n.ok){let e=await n.json();if(e.needs_extra&&!e.available){x({policyType:a.policy_type,packageName:e.package,installTarget:e.install_target,installHint:e.install_hint});return}}}catch{}y(!0);try{let n=await xf(e,t,pse(a));r({title:`Training Started`,description:n.name}),i(`/training/${n.id}`)}catch(n){r({title:`Error`,description:n instanceof Error?n.message:String(n),variant:`destructive`}),gf(e,t,200).then(e=>g(e.some(e=>e.runner===`local`&&e.state===`running`))).catch(()=>{})}finally{y(!1)}};if(d===null)return(0,V.jsx)(`div`,{className:`min-h-screen bg-slate-900 text-white p-4`,children:(0,V.jsxs)(`div`,{className:`max-w-7xl mx-auto`,children:[(0,V.jsx)(cL,{}),(0,V.jsxs)(`div`,{className:`flex items-center justify-center py-24 text-slate-400`,children:[(0,V.jsx)(Ms,{className:`w-6 h-6 animate-spin mr-3`}),`Checking training environment…`]})]})});if(d===!1)return(0,V.jsx)(`div`,{className:`min-h-screen bg-slate-900 text-white p-4`,children:(0,V.jsxs)(`div`,{className:`max-w-7xl mx-auto`,children:[(0,V.jsx)(cL,{}),(0,V.jsx)(cse,{installHint:p})]})});let A=a.target.runner===`hf_cloud`,j=a.target.runner===`hf_cloud`&&!a.target.flavor,M=a.target.runner===`local`&&h,N=v||!a.dataset_repo_id.trim()||M||A&&!S||j,P=M?`Another local training is already running`:A&&!S?`Log in to Hugging Face to use cloud compute`:j?`Select a hardware flavor`:void 0;return(0,V.jsxs)(`div`,{className:`min-h-screen bg-slate-900 text-white p-4`,children:[(0,V.jsxs)(`div`,{className:`max-w-7xl mx-auto`,children:[(0,V.jsx)(cL,{}),(0,V.jsx)(use,{}),(0,V.jsx)(xre,{config:a,updateConfig:O,datasets:s,datasetsLoading:l,authenticated:S,flavors:w,hardwareLoading:E}),(0,V.jsx)(`div`,{className:`max-w-3xl mx-auto mt-6 flex justify-end`,children:(()=>{let e=(0,V.jsx)(q,{onClick:k,disabled:N,size:`lg`,className:`bg-green-500 hover:bg-green-600 text-white font-semibold px-6`,children:v?(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Ms,{className:`w-5 h-5 mr-2 animate-spin`}),` Starting…`]}):(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Ls,{className:`w-5 h-5 mr-2`}),` Start Training`]})});return P?(0,V.jsxs)(Ih,{children:[(0,V.jsx)(Lh,{asChild:!0,children:(0,V.jsx)(`span`,{tabIndex:0,children:e})}),(0,V.jsx)(Rh,{children:P})]}):e})()})]}),b&&(0,V.jsx)(lse,{open:!!b,onOpenChange:e=>!e&&x(null),policyType:b.policyType,packageName:b.packageName,installTarget:b.installTarget,installHint:b.installHint})]})},hse=({jobId:e})=>{let{baseUrl:t,fetchWithHeaders:n}=Tl(),{toast:r}=$i(),i=mt(),{selectedRecord:a}=Wb(),[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(null),[u,d]=(0,_.useState)([]),f=(0,_.useRef)(null),[p,m]=(0,_.useState)([]),[h,g]=(0,_.useState)(null),[v,y]=(0,_.useState)(!1);(0,_.useEffect)(()=>{let r=!1;return yf(t,n,e).then(e=>{!r&&e.length>0&&d(e)}).catch(()=>{}),()=>{r=!0}},[t,n,e]);let b=(0,_.useRef)(o?.state);b.current=o?.state,(0,_.useEffect)(()=>{let r=!1,i=()=>{Cb(t,n,e).then(e=>{if(!r)if(m(e),e.length>0){let t=e[e.length-1].step;g(n=>n!=null&&e.some(e=>e.step===n)?n:t)}else g(null)}).catch(()=>{r||(m([]),g(null))})};i();let a=setInterval(()=>{r||b.current&&b.current!==`running`||i()},5e3);return()=>{r=!0,clearInterval(a)}},[t,n,e]),(0,_.useEffect)(()=>{let r=!1,i=async()=>{try{let i=await _f(t,n,e);if(r)return;if(s(i),i.state===`running`){let i=await vf(t,n,e);!r&&i.length>0&&d(e=>{let t=[...e,...i];return t.length>G9?t.slice(t.length-G9):t})}}catch(e){r||l(e instanceof Error?e.message:String(e))}};i();let a=setInterval(()=>{r||b.current&&b.current!==`running`||i()},dse);return()=>{r=!0,clearInterval(a)}},[t,n,e]),(0,_.useEffect)(()=>{f.current&&(f.current.scrollTop=f.current.scrollHeight)},[u]);let x=e=>{let t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=Math.floor(e%60);return`${t.toString().padStart(2,`0`)}:${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`},S=()=>!o||o.metrics.total_steps===0?0:o.metrics.current_step/o.metrics.total_steps*100,C=async()=>{if(o&&window.confirm(`Stop this run?`))try{s(await Cf(t,n,o.id)),r({title:`Stopping…`})}catch(e){r({title:`Stop failed`,description:e instanceof Error?e.message:String(e),variant:`destructive`})}},w=async()=>{if(o&&window.confirm(`Delete this run? This wipes the output directory.`))try{await wf(t,n,o.id),r({title:`Job removed`}),i(`/`)}catch(e){r({title:`Delete failed`,description:e instanceof Error?e.message:String(e),variant:`destructive`})}};if(c&&!o)return(0,V.jsx)(`div`,{className:`min-h-screen bg-slate-900 text-white p-4`,children:(0,V.jsxs)(`div`,{className:`max-w-7xl mx-auto space-y-4`,children:[(0,V.jsxs)(q,{variant:`ghost`,onClick:()=>i(`/`),className:`text-slate-400`,children:[(0,V.jsx)(as,{className:`w-4 h-4 mr-2`}),` Back to Jobs`]}),(0,V.jsxs)(`p`,{className:`text-red-300`,children:[`Couldn't load job `,e,`: `,c]})]})});if(!o)return(0,V.jsx)(`div`,{className:`min-h-screen bg-slate-900 text-white p-4`,children:(0,V.jsxs)(`div`,{className:`max-w-7xl mx-auto flex items-center justify-center py-24 text-slate-400`,children:[(0,V.jsx)(Ms,{className:`w-6 h-6 animate-spin mr-3`}),` Loading job…`]})});let T=o.state===`running`;return(0,V.jsx)(`div`,{className:`min-h-screen bg-slate-900 text-white p-4`,children:(0,V.jsxs)(`div`,{className:`max-w-7xl mx-auto space-y-6`,children:[(0,V.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,V.jsxs)(q,{variant:`ghost`,onClick:()=>i(`/`),className:`text-slate-400 hover:text-white`,children:[(0,V.jsx)(as,{className:`w-4 h-4 mr-2`}),` Jobs`]}),(0,V.jsxs)(`div`,{children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,V.jsx)(`h1`,{className:`text-xl font-semibold text-white`,children:o.name}),o.runner===`hf_cloud`?(0,V.jsxs)(`span`,{className:`text-xs px-2 py-0.5 rounded bg-amber-900/40 text-amber-200 border border-amber-700`,children:[`HF · `,o.hf_flavor??`cloud`]}):(0,V.jsx)(`span`,{className:`text-xs px-2 py-0.5 rounded bg-slate-700 text-slate-200 border border-slate-600`,children:`Local`}),o.runner===`hf_cloud`&&o.hf_repo_id&&o.state===`done`&&(0,V.jsx)(`a`,{href:`https://huggingface.co/${o.hf_repo_id}`,target:`_blank`,rel:`noreferrer`,className:`text-xs text-amber-300 hover:text-amber-200 underline`,children:`View on Hub ↗`}),o.wandb_run_url&&(0,V.jsx)(`a`,{href:o.wandb_run_url,target:`_blank`,rel:`noreferrer`,className:`text-xs text-yellow-300 hover:text-yellow-200 underline`,children:`View on W&B ↗`})]}),(0,V.jsxs)(`p`,{className:`text-xs text-slate-400`,children:[o.state,o.error_message?` — ${o.error_message}`:``]})]})]}),T?(0,V.jsxs)(q,{onClick:C,className:`bg-red-500 hover:bg-red-600 text-white`,children:[(0,V.jsx)(Js,{className:`w-4 h-4 mr-2`}),` Stop`]}):(0,V.jsxs)(q,{onClick:w,variant:`ghost`,className:`text-slate-400 hover:text-white`,children:[(0,V.jsx)(Xs,{className:`w-4 h-4 mr-2`}),` Delete`]})]}),(0,V.jsx)(ose,{jobId:e,trainingStatus:fse(o,!1),getProgressPercentage:S,formatTime:x}),(0,V.jsxs)(`div`,{className:`bg-slate-800/40 border border-slate-700 rounded-lg p-4 flex items-center gap-3`,children:[(0,V.jsx)(`span`,{className:`text-sm font-semibold text-slate-300`,children:`Run inference`}),p.length===0?(0,V.jsx)(`span`,{className:`text-xs text-slate-500`,children:`No checkpoints yet — wait for the first save.`}):(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Tb,{checkpoints:p,selectedStep:h,onChange:g}),(0,V.jsxs)(q,{onClick:()=>y(!0),disabled:h==null,className:`bg-green-500 hover:bg-green-600 text-white`,children:[(0,V.jsx)(Ls,{className:`w-4 h-4 mr-2`}),`Run on robot`]})]})]}),(0,V.jsx)(zb,{open:v,onOpenChange:y,robot:a,jobId:e,initialStep:h}),(0,V.jsx)(sse,{logs:u,logContainerRef:f})]})})},K9=()=>{let{jobId:e}=gt();return e?(0,V.jsx)(hse,{jobId:e}):(0,V.jsx)(mse,{})},gse=1e3;function q9(e){let t=Math.max(0,Math.floor(e)),n=Math.floor(t/60),r=t%60;return`${String(n).padStart(2,`0`)}:${String(r).padStart(2,`0`)}`}var _se=()=>{let e=mt(),{baseUrl:t,fetchWithHeaders:n}=Tl(),{toast:r}=$i(),[i,a]=(0,_.useState)(null),[o,s]=(0,_.useState)(!1),c=(0,_.useRef)(!1),l=(0,_.useRef)(!1);(0,_.useEffect)(()=>{let i=!1,o=async()=>{try{await Fb(t,n)}catch{}},s=async()=>{try{let s=await Ib(t,n);if(i)return;if(a(s),!s.inference_active&&!c.current){c.current=!0,s.exited&&r({title:`Inference finished`,description:s.exit_code===0?`Run completed.`:`Exit code ${s.exit_code}. See ${s.log_path}.`,variant:s.exit_code===0?`default`:`destructive`}),e(`/`);return}s.inference_active&&s.rollout_started_at!=null&&s.duration_s!=null&&s.duration_s>0&&s.rollout_elapsed_s>s.duration_s+10&&!l.current&&(l.current=!0,r({title:`Inference seems hung`,description:`Rollout past duration by ${Math.round(s.rollout_elapsed_s-s.duration_s)}s. Stopping.`,variant:`destructive`}),o())}catch(e){i||r({title:`Lost connection to backend`,description:e instanceof Error?e.message:String(e),variant:`destructive`})}};s();let u=setInterval(s,gse);return()=>{i=!0,clearInterval(u)}},[t,n,e,r]);let u=async()=>{s(!1);try{await Fb(t,n)}catch(e){r({title:`Stop failed`,description:e instanceof Error?e.message:String(e),variant:`destructive`})}};if(!i)return(0,V.jsxs)(`div`,{className:`min-h-screen bg-black text-white flex items-center justify-center`,children:[(0,V.jsx)(Ms,{className:`w-6 h-6 animate-spin mr-3`}),` Connecting to inference…`]});let d=i.elapsed_s??0,f=i.rollout_elapsed_s??0,p=i.duration_s??0,m=i.inference_active&&i.rollout_started_at==null,h=i.inference_active&&i.rollout_started_at!=null,g=h&&p>0?Math.min(100,f/p*100):0;return(0,V.jsxs)(`div`,{className:`min-h-screen bg-black text-white flex flex-col p-4 sm:p-6 lg:p-8`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-4 mb-8`,children:[(0,V.jsx)(q,{variant:`ghost`,size:`icon`,onClick:()=>e(`/`),className:`text-slate-400 hover:bg-slate-800 hover:text-white rounded-lg`,children:(0,V.jsx)(as,{className:`w-5 h-5`})}),(0,V.jsx)($M,{}),(0,V.jsx)(`h1`,{className:`font-bold text-white text-2xl`,children:`Inference`})]}),(0,V.jsx)(`div`,{className:`flex-1 flex items-center justify-center`,children:(0,V.jsxs)(`div`,{className:`bg-gray-900 rounded-lg border border-gray-700 p-8 w-full max-w-xl`,children:[(0,V.jsx)(`div`,{className:`text-center mb-6`,children:(0,V.jsxs)(`div`,{className:`inline-flex items-center gap-2 px-3 py-1 rounded-full text-xs font-bold tracking-widest ${m?`bg-amber-500/15 text-amber-300`:`bg-green-500/15 text-green-300`}`,children:[(0,V.jsx)(`span`,{className:`w-2 h-2 rounded-full ${m?`bg-amber-500`:`bg-green-500`} animate-pulse`}),m?`SETTING UP`:h?`RUNNING`:`FINISHED`]})}),(0,V.jsxs)(`div`,{className:`text-center mb-4`,children:[(0,V.jsx)(`div`,{className:`text-7xl font-mono font-bold leading-none ${m?`text-amber-400`:`text-green-400`}`,children:q9(h?f:d)}),(0,V.jsx)(`div`,{className:`text-sm text-gray-500 mt-2`,children:m?`Loading policy & connecting hardware…`:`/ ${q9(p)}`})]}),(0,V.jsx)(`div`,{className:`w-full bg-gray-800 rounded-full h-1.5 mb-8`,children:(0,V.jsx)(`div`,{className:`h-1.5 rounded-full transition-all duration-500 ${m?`bg-amber-500/40 animate-pulse w-full`:`bg-green-500`}`,style:m?void 0:{width:`${g}%`}})}),(0,V.jsxs)(`div`,{className:`text-xs text-slate-500 break-all mb-6`,children:[`policy: `,i.policy_ref??`(unknown)`]}),(0,V.jsxs)(q,{onClick:()=>s(!0),disabled:!i.inference_active,className:`w-full bg-red-500 hover:bg-red-600 text-white font-semibold py-6 text-lg disabled:opacity-50`,children:[(0,V.jsx)(Js,{className:`w-5 h-5 mr-2`}),`Stop`]})]})}),(0,V.jsx)($I,{open:o,onOpenChange:s,children:(0,V.jsxs)(tL,{className:`bg-gray-900 border-gray-700 text-white`,children:[(0,V.jsxs)(nL,{children:[(0,V.jsx)(iL,{children:`Stop inference?`}),(0,V.jsx)(aL,{className:`text-gray-400`,children:`The follower will hold its current pose. You can launch another run from the job tile.`})]}),(0,V.jsxs)(rL,{children:[(0,V.jsx)(sL,{className:`bg-gray-800 border-gray-700 text-white hover:bg-gray-700`,children:`Keep running`}),(0,V.jsx)(oL,{onClick:u,className:`bg-red-500 hover:bg-red-600 text-white`,children:`Stop`})]})]})})]})};async function vse(e,t,n,r){return pf(e,t,`/dataset-episodes?${new URLSearchParams({repo_id:n})}`,{signal:r,action:`List episodes`})}async function yse(e,t,n,r,i){return pf(e,t,`/dataset-episode?${new URLSearchParams({repo_id:n,episode_index:String(r)})}`,{signal:i,action:`Load episode`})}async function bse(e,t,n,r,i){return pf(e,t,`/dataset-motion?${new URLSearchParams({repo_id:n,episode_index:String(r)})}`,{signal:i,action:`Load motion trace`})}async function xse(e,t,n,r,i,a,o){return pf(e,t,`/dataset-thumbnails?${new URLSearchParams({repo_id:n,episode_index:String(r),camera:i,count:String(a)})}`,{signal:o,action:`Load thumbnails`})}function J9(e,t,n,r,i){return`${e}/dataset-video?${new URLSearchParams({repo_id:t,camera:n,chunk:String(r),file:String(i)})}`}function Y9(e,t,n,r,i,a){let o=new URLSearchParams({repo_id:t,episode_index:String(n),camera:r,frame_index:String(i)});return a&&o.set(`max_width`,String(a)),`${e}/dataset-frame?${o}`}function X9(e){if(e==null)return`—`;if(e<60)return`${e.toFixed(1)}s`;let t=Math.floor(e/60),n=Math.round(e%60);return`${t}m ${String(n).padStart(2,`0`)}s`}var Sse=({episodes:e,selected:t,onSelect:n})=>{let r=(0,_.useRef)(null);return(0,_.useEffect)(()=>{r.current?.scrollIntoView({block:`nearest`})},[t]),e.length===0?(0,V.jsx)(`div`,{className:`rounded-lg border border-gray-800 bg-gray-950 p-4 text-xs text-gray-500`,children:`No episodes in this dataset.`}):(0,V.jsxs)(`div`,{className:`overflow-hidden rounded-lg border border-gray-800 bg-gray-950`,children:[(0,V.jsxs)(`div`,{className:`flex items-center justify-between border-b border-gray-800 px-3 py-2`,children:[(0,V.jsx)(`span`,{className:`text-[11px] font-medium uppercase tracking-wider text-gray-500`,children:`Episodes`}),(0,V.jsx)(`span`,{className:`text-[11px] tabular-nums text-gray-600`,children:e.length})]}),(0,V.jsx)(`div`,{className:`max-h-[calc(100vh_-_280px)] overflow-y-auto`,children:e.map(e=>{let i=e.episode_index===t;return(0,V.jsxs)(`button`,{ref:i?r:void 0,type:`button`,onClick:()=>n(e.episode_index),className:`flex w-full items-center gap-2 border-b border-gray-900 px-3 py-2 text-left transition last:border-b-0 ${i?`bg-gray-800/80`:`hover:bg-gray-900`} focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-orange-500`,children:[(0,V.jsx)(`span`,{className:`w-8 text-xs tabular-nums ${i?`font-semibold text-orange-400`:`text-gray-500`}`,children:e.episode_index}),(0,V.jsx)(`span`,{className:`flex-1 truncate text-xs text-gray-300`,children:e.tasks.length>0?e.tasks.join(`, `):`—`}),(0,V.jsx)(`span`,{className:`text-[11px] tabular-nums text-gray-500`,children:X9(e.duration_s)})]},e.episode_index)})})]})},Cse=({repoId:e,episodeIndex:t,camera:n,currentFrame:r,onSeekFrame:i,count:a=12})=>{let{baseUrl:o,fetchWithHeaders:s}=Tl(),[c,l]=(0,_.useState)([]),[u,d]=(0,_.useState)(!1);(0,_.useEffect)(()=>{let r=new AbortController;return d(!0),xse(o,s,e,t,n,a,r.signal).then(e=>{r.signal.aborted||l(e.success?e.thumbnails:[])}).catch(()=>{r.signal.aborted||l([])}).finally(()=>{r.signal.aborted||d(!1)}),()=>r.abort()},[o,s,e,t,n,a]);let f=c.reduce((e,t,n)=>Math.abs(t.frame_index-r)(0,V.jsxs)(`button`,{type:`button`,onClick:()=>i(e.frame_index),title:`Frame ${e.frame_index}`,className:`group relative flex-none overflow-hidden rounded transition ${t===f?`ring-2 ring-orange-500`:`ring-1 ring-gray-800 hover:ring-gray-600`} focus:outline-none focus-visible:ring-2 focus-visible:ring-orange-400`,children:[(0,V.jsx)(`img`,{src:e.data_uri,alt:`Frame ${e.frame_index}`,className:`h-14 w-auto`,draggable:!1}),(0,V.jsx)(`span`,{className:`absolute bottom-0 right-0 bg-black/70 px-1 text-[10px] tabular-nums text-gray-300 opacity-0 transition group-hover:opacity-100`,children:e.frame_index})]},e.frame_index))})},wse=({repoId:e,episodeIndex:t,currentFrame:n,onSeekFrame:r})=>{let{baseUrl:i,fetchWithHeaders:a}=Tl(),[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(null);(0,_.useEffect)(()=>{let n=new AbortController;return l(null),bse(i,a,e,t,n.signal).then(e=>{if(!n.signal.aborted){if(!e.success){s(null),l(e.message??`No action stream`);return}s(e.motion)}}).catch(e=>{n.signal.aborted||(s(null),l(e instanceof Error?e.message:`No action stream`))}),()=>n.abort()},[i,a,e,t]);let u=(0,_.useMemo)(()=>(o??[]).map((e,t)=>({frame:t,motion:e})),[o]);return c?(0,V.jsxs)(`div`,{className:`flex h-[64px] items-center justify-center rounded-md border border-gray-800 bg-gray-950 text-[11px] text-gray-600`,children:[`Joint motion unavailable — `,c]}):o?(0,V.jsxs)(`div`,{className:`rounded-md border border-gray-800 bg-gray-950 px-1 pb-1 pt-1.5`,children:[(0,V.jsxs)(`div`,{className:`flex items-center justify-between px-2 pb-1`,children:[(0,V.jsx)(`span`,{className:`text-[10px] uppercase tracking-wider text-gray-600`,children:`Joint motion`}),(0,V.jsxs)(`span`,{className:`text-[10px] tabular-nums text-gray-600`,children:[`frame `,n]})]}),(0,V.jsx)(`div`,{className:`h-[52px] w-full cursor-pointer`,children:(0,V.jsx)(mG,{width:`100%`,height:`100%`,children:(0,V.jsxs)(ase,{data:u,margin:{top:2,right:4,bottom:0,left:4},onClick:e=>{let t=e?.activeLabel;t!=null&&r(Number(t))},children:[(0,V.jsx)(`defs`,{children:(0,V.jsxs)(`linearGradient`,{id:`motionFill`,x1:`0`,y1:`0`,x2:`0`,y2:`1`,children:[(0,V.jsx)(`stop`,{offset:`0%`,stopColor:`#f97316`,stopOpacity:.5}),(0,V.jsx)(`stop`,{offset:`100%`,stopColor:`#f97316`,stopOpacity:.04})]})}),(0,V.jsx)(s9,{hide:!0,domain:[0,`dataMax`]}),(0,V.jsx)(YW,{contentStyle:{background:`#0a0a0a`,border:`1px solid #1f2937`,borderRadius:6,fontSize:11,padding:`4px 8px`},labelStyle:{color:`#9ca3af`},itemStyle:{color:`#fb923c`},formatter:e=>[e.toFixed(2),`motion`],labelFormatter:e=>`Frame ${e}`}),(0,V.jsx)(H7,{type:`monotone`,dataKey:`motion`,stroke:`#f97316`,strokeWidth:1.25,fill:`url(#motionFill)`,isAnimationActive:!1,dot:!1}),(0,V.jsx)(A5,{x:n,stroke:`#e5e7eb`,strokeWidth:1})]})})})]}):(0,V.jsx)(`div`,{className:`h-[64px] rounded-md border border-gray-800 bg-gray-950`})},Tse=[.5,1,2],Ese=.2,Dse=({repoId:e,detail:t,onNavigate:n})=>{let{baseUrl:r}=Tl(),i=t.cameras,[a,o]=(0,_.useState)(i[0]?.name??``),[s,c]=(0,_.useState)(!1),[l,u]=(0,_.useState)(!1),[d,f]=(0,_.useState)(1),[p,m]=(0,_.useState)(0),h=(0,_.useRef)(null),g=(0,_.useRef)({});(0,_.useEffect)(()=>{i.some(e=>e.name===a)||o(i[0]?.name??``)},[i,a]);let v=(0,_.useMemo)(()=>i.find(e=>e.name===a)??i[0]??null,[i,a]),y=t.fps??20,b=v?.from_timestamp??0,x=v?.to_timestamp??b+(t.duration_s??0),S=(0,_.useCallback)(e=>{let n=h.current;if(!n)return;let r=Math.max(0,Math.min(e,Math.max(t.length-1,0)));n.currentTime=b+(r+.5)/y,m(r)},[b,y,t.length]),C=(0,_.useCallback)(()=>{let e=h.current;e&&(e.currentTime=b,e.playbackRate=d,m(0))},[b,d]);(0,_.useEffect)(()=>{let e=h.current;if(!e)return;let t=!e.paused,n=()=>{e.currentTime=b,e.playbackRate=d,m(0),(t||l)&&e.play().catch(()=>u(!1))};if(e.readyState>=1)n();else return e.addEventListener(`loadedmetadata`,n,{once:!0}),()=>e.removeEventListener(`loadedmetadata`,n)},[t.episode_index,a,b]);let w=(0,_.useCallback)(()=>{let e=h.current;if(e&&!e.ended){if(e.currentTime>=x){e.currentTime=b,m(0);return}if(m(Math.max(0,Math.floor((e.currentTime-b)*y))),s)for(let t of i){if(t.name===a)continue;let n=g.current[t.name];if(!n)continue;let r=(t.from_timestamp??0)+(e.currentTime-b);Math.abs(n.currentTime-r)>Ese&&(n.currentTime=r),n.playbackRate=e.playbackRate,l&&n.paused&&n.play().catch(()=>void 0),!l&&!n.paused&&n.pause()}}},[x,b,y,s,i,a,l]),T=(0,_.useCallback)(()=>{let e=h.current;e&&(e.paused?e.play().then(()=>u(!0),()=>u(!1)):(e.pause(),u(!1)))},[]);if((0,_.useEffect)(()=>{h.current&&(h.current.playbackRate=d)},[d,a]),(0,_.useEffect)(()=>{let e=e=>{let t=e.target;t&&[`INPUT`,`TEXTAREA`,`SELECT`].includes(t.tagName)||(e.code===`Space`?(e.preventDefault(),T()):e.code===`ArrowLeft`?S(p-1):e.code===`ArrowRight`&&S(p+1))};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[T,S,p]),!v)return(0,V.jsx)(`div`,{className:`flex h-64 items-center justify-center rounded-lg border border-gray-800 bg-gray-950 text-sm text-gray-500`,children:`This episode has no camera videos on disk.`});let E=i.filter(e=>e.name!==a);return(0,V.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,V.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,V.jsx)(`div`,{className:`flex rounded-md border border-gray-800 bg-gray-950 p-0.5`,children:i.map(e=>(0,V.jsx)(`button`,{type:`button`,onClick:()=>o(e.name),className:`rounded px-3 py-1 text-xs font-medium transition ${e.name===a?`bg-gray-800 text-white`:`text-gray-400 hover:text-gray-200`}`,children:e.name},e.name))}),i.length>1&&(0,V.jsxs)(q,{variant:`outline`,size:`sm`,onClick:()=>c(e=>!e),className:`h-7 gap-1.5 border-gray-800 bg-gray-950 text-xs hover:bg-gray-900 ${s?`text-orange-400`:`text-gray-400`}`,children:[(0,V.jsx)(js,{className:`h-3.5 w-3.5`}),`All cameras`]}),(0,V.jsx)(`div`,{className:`ml-auto flex rounded-md border border-gray-800 bg-gray-950 p-0.5`,children:Tse.map(e=>(0,V.jsxs)(`button`,{type:`button`,onClick:()=>f(e),className:`rounded px-2.5 py-1 text-xs font-medium tabular-nums transition ${e===d?`bg-gray-800 text-white`:`text-gray-400 hover:text-gray-200`}`,children:[e,`x`]},e))})]}),(0,V.jsxs)(`div`,{className:s&&i.length>1?`grid grid-cols-1 gap-2 sm:grid-cols-2`:`grid grid-cols-1`,children:[(0,V.jsxs)(`div`,{className:`relative flex items-center justify-center overflow-hidden rounded-lg border border-gray-800 bg-black`,children:[(0,V.jsx)(`video`,{ref:h,src:J9(r,e,a,v.chunk,v.file_index),poster:Y9(r,e,t.episode_index,a,0,640),className:`w-auto max-w-full bg-black object-contain ${s&&i.length>1?`max-h-[22vh]`:`max-h-[42vh]`}`,preload:`auto`,playsInline:!0,muted:!0,onLoadedMetadata:C,onTimeUpdate:w,onEnded:e=>{let t=e.currentTarget;t.currentTime=b,m(0),t.play().catch(()=>u(!1))},onPlay:()=>u(!0),onPause:()=>u(!1)},`${a}-${v.chunk}-${v.file_index}`),(0,V.jsx)(`span`,{className:`absolute left-2 top-2 rounded bg-black/70 px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-gray-300`,children:a})]}),s&&E.map(n=>(0,V.jsxs)(`div`,{className:`relative flex items-center justify-center overflow-hidden rounded-lg border border-gray-800 bg-black`,children:[(0,V.jsx)(`video`,{ref:e=>{g.current[n.name]=e},src:J9(r,e,n.name,n.chunk,n.file_index),poster:Y9(r,e,t.episode_index,n.name,0,640),className:`max-h-[22vh] w-auto max-w-full bg-black object-contain`,preload:`auto`,playsInline:!0,muted:!0,onLoadedMetadata:e=>{e.currentTarget.currentTime=n.from_timestamp??0}},`${n.name}-${n.chunk}-${n.file_index}`),(0,V.jsx)(`span`,{className:`absolute left-2 top-2 rounded bg-black/70 px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-gray-300`,children:n.name})]},n.name))]}),(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,V.jsx)(q,{size:`sm`,onClick:T,className:`h-8 w-8 bg-orange-600 p-0 hover:bg-orange-500`,title:`Play / pause (Space)`,children:l?(0,V.jsx)(Fs,{className:`h-4 w-4`}):(0,V.jsx)(Ls,{className:`h-4 w-4`})}),(0,V.jsx)(q,{variant:`outline`,size:`sm`,onClick:()=>S(p-1),className:`h-8 w-8 border-gray-800 bg-gray-950 p-0 text-gray-300 hover:bg-gray-900`,title:`Previous frame (←)`,children:(0,V.jsx)(Gs,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(q,{variant:`outline`,size:`sm`,onClick:()=>S(p+1),className:`h-8 w-8 border-gray-800 bg-gray-950 p-0 text-gray-300 hover:bg-gray-900`,title:`Next frame (→)`,children:(0,V.jsx)(Ks,{className:`h-3.5 w-3.5`})}),(0,V.jsx)(`input`,{type:`range`,min:0,max:Math.max(t.length-1,0),value:p,onChange:e=>S(Number(e.target.value)),className:`mx-2 h-1 flex-1 cursor-pointer appearance-none rounded bg-gray-800 accent-orange-500`,"aria-label":`Scrub episode`}),(0,V.jsxs)(`span`,{className:`w-28 text-right text-xs tabular-nums text-gray-400`,children:[p,` / `,Math.max(t.length-1,0)]})]}),(0,V.jsx)(wse,{repoId:e,episodeIndex:t.episode_index,currentFrame:p,onSeekFrame:S}),(0,V.jsx)(Cse,{repoId:e,episodeIndex:t.episode_index,camera:a,currentFrame:p,onSeekFrame:S}),(0,V.jsxs)(`div`,{className:`flex items-center justify-between border-t border-gray-800 pt-3`,children:[(0,V.jsxs)(q,{variant:`outline`,size:`sm`,disabled:t.prev_episode===null,onClick:()=>t.prev_episode!==null&&n(t.prev_episode),className:`h-7 gap-1 border-gray-800 bg-gray-950 text-xs text-gray-300 hover:bg-gray-900 disabled:opacity-40`,children:[(0,V.jsx)(us,{className:`h-3.5 w-3.5`}),`Previous`]}),(0,V.jsxs)(`span`,{className:`text-xs text-gray-500`,children:[`Episode `,t.episode_index,` of `,t.total_episodes]}),(0,V.jsxs)(q,{variant:`outline`,size:`sm`,disabled:t.next_episode===null,onClick:()=>t.next_episode!==null&&n(t.next_episode),className:`h-7 gap-1 border-gray-800 bg-gray-950 text-xs text-gray-300 hover:bg-gray-900 disabled:opacity-40`,children:[`Next`,(0,V.jsx)(ds,{className:`h-3.5 w-3.5`})]})]})]})};function Ose({datasets:e,selectedRepoId:t,open:n,onOpenChange:r,onMerge:i}){let[a,o]=(0,_.useState)([t]),[s,c]=(0,_.useState)(``),[l,u]=(0,_.useState)(!1),[d,f]=(0,_.useState)(null),p=(0,_.useMemo)(()=>e.filter(e=>e.repo_id!==t&&(e.source===`local`||e.source===`both`)),[e,t]),m=a.length>=2&&/^[A-Za-z0-9._-]+$/.test(s)&&!l,h=(e,t)=>{f(null),o(n=>t?[...n,e]:n.filter(t=>t!==e))},g=()=>{o([t]),c(``),u(!1),f(null)};(0,_.useEffect)(()=>{n&&(o([t]),c(``),u(!1),f(null))},[n,t]);let v=e=>{!l&&!e&&g(),r(e)};return(0,V.jsx)(nf,{open:n,onOpenChange:v,children:(0,V.jsxs)(of,{className:`border-gray-700 bg-gray-900 text-gray-300 sm:max-w-lg`,children:[(0,V.jsxs)(sf,{children:[(0,V.jsx)(lf,{className:`text-white`,children:`Merge local datasets`}),(0,V.jsxs)(uf,{children:[(0,V.jsx)(`code`,{children:t}),` is included. Select at least one more local dataset. Their source files stay unchanged; the merged dataset is saved locally.`]})]}),(0,V.jsxs)(`div`,{className:`space-y-3`,children:[(0,V.jsx)(J,{className:`text-gray-300`,children:`Source datasets`}),(0,V.jsxs)(`div`,{className:`max-h-52 space-y-2 overflow-y-auto rounded-md border border-gray-700 p-3`,children:[(0,V.jsx)(`p`,{className:`text-sm text-gray-200`,children:t}),p.map(e=>(0,V.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-3 text-sm text-gray-200`,children:[(0,V.jsx)(J_,{checked:a.includes(e.repo_id),onCheckedChange:t=>h(e.repo_id,t===!0),disabled:l}),e.repo_id]},e.repo_id))]}),(0,V.jsx)(`p`,{className:`text-xs text-gray-500`,children:`Select at least one additional dataset.`}),(0,V.jsxs)(`div`,{className:`space-y-2`,children:[(0,V.jsx)(J,{htmlFor:`merged-dataset-name`,className:`text-gray-300`,children:`Merged dataset name`}),(0,V.jsx)(k_,{id:`merged-dataset-name`,value:s,onChange:e=>{f(null),c(e.target.value.replace(/[^A-Za-z0-9._-]/g,`_`))},placeholder:`combined_pick_place`,disabled:l,className:`border-gray-700 bg-gray-800 text-white`}),(0,V.jsxs)(`p`,{className:`text-xs text-gray-500`,children:[`Saved locally as `,(0,V.jsxs)(`code`,{children:[`local/`,s||`name`]}),`.`]})]}),d&&(0,V.jsx)(`p`,{className:`text-sm text-red-400`,children:d})]}),(0,V.jsxs)(cf,{children:[(0,V.jsx)(q,{variant:`outline`,onClick:()=>v(!1),disabled:l,children:`Cancel`}),(0,V.jsxs)(q,{onClick:async()=>{if(m){u(!0);try{await i(a,s),g(),r(!1)}catch(e){f(e instanceof Error?e.message:`Could not merge the selected datasets.`)}finally{u(!1)}}},disabled:!m,children:[l&&(0,V.jsx)(Ms,{className:`mr-2 h-4 w-4 animate-spin`}),l?`Merging…`:`Merge datasets`]})]})]})})}var kse=e=>{let{baseUrl:t,fetchWithHeaders:n}=Tl(),[r,i]=(0,_.useState)(null),[a,o]=(0,_.useState)(!1),[s,c]=(0,_.useState)(null);return(0,_.useEffect)(()=>{if(i(null),c(null),!e){o(!1);return}let r=new AbortController;return o(!0),vse(t,n,e,r.signal).then(e=>{if(!r.signal.aborted){if(!e.success){i(null),c(e.message??`Could not read dataset`);return}i(e)}}).catch(e=>{r.signal.aborted||(i(null),c(e instanceof Error?e.message:`Could not read dataset`))}).finally(()=>{r.signal.aborted||o(!1)}),()=>r.abort()},[t,n,e]),{data:r?.repo_id===e?r:null,loading:a,error:s}},Ase=(e,t)=>{let{baseUrl:n,fetchWithHeaders:r}=Tl(),[i,a]=(0,_.useState)(null),[o,s]=(0,_.useState)(!1),[c,l]=(0,_.useState)(null);return(0,_.useEffect)(()=>{if(!e||t===null){a(null);return}let i=new AbortController;return s(!0),l(null),yse(n,r,e,t,i.signal).then(e=>{if(!i.signal.aborted){if(!e.success){a(null),l(e.message??`Could not load episode`);return}a(e)}}).catch(e=>{i.signal.aborted||(a(null),l(e instanceof Error?e.message:`Could not load episode`))}).finally(()=>{i.signal.aborted||s(!1)}),()=>i.abort()},[n,r,e,t]),{detail:i,loading:o,error:c}},Z9=({label:e,value:t})=>(0,V.jsxs)(`span`,{className:`flex items-baseline gap-1.5`,children:[(0,V.jsx)(`span`,{className:`text-[10px] uppercase tracking-wider text-gray-600`,children:e}),(0,V.jsx)(`span`,{className:`font-medium tabular-nums text-gray-200`,children:t})]}),jse=()=>{let e=mt(),[t,n]=Vn(),{datasets:r,loading:i,refresh:a}=$b(),{baseUrl:o,fetchWithHeaders:s}=Tl(),{toast:c}=$i(),[l,u]=(0,_.useState)(!1),d=(0,_.useMemo)(()=>r.filter(e=>e.source===`local`||e.source===`both`),[r]),f=t.get(`dataset`),p=t.get(`episode`),m=p===null?null:Number(p),h=r.find(e=>e.repo_id===f)?.source,g=h===`local`||h===`both`,{data:v,loading:y,error:b}=kse(f),{detail:x,loading:S,error:C}=Ase(f,m),w=e=>{let n=t.get(`api`);return n?{...e,api:n}:e},T=e=>n(w({dataset:e})),E=async(e,t)=>{let n=await hf(o,s,e,t);a(),T(n.repo_id),c({title:`Datasets merged`,description:`${n.num_episodes} episodes are ready to browse.`})},D=e=>{f&&n(w({dataset:f,episode:String(e)}))};return(0,_.useEffect)(()=>{f&&v?.success&&p===null&&v.episodes.length>0&&n(w({dataset:f,episode:String(v.episodes[0].episode_index)}),{replace:!0})},[f,v,p,n]),(0,V.jsxs)(`div`,{className:`min-h-screen bg-black p-6 pb-24 text-white`,children:[(0,V.jsxs)(`div`,{className:`mx-auto max-w-[1400px]`,children:[(0,V.jsxs)(`div`,{className:`mb-5 flex flex-wrap items-center gap-3`,children:[(0,V.jsxs)(q,{variant:`ghost`,size:`sm`,onClick:()=>e(`/`),className:`h-8 gap-1.5 px-2 text-gray-400 hover:bg-gray-900 hover:text-white`,children:[(0,V.jsx)(as,{className:`h-4 w-4`}),`Back`]}),(0,V.jsxs)(`h1`,{className:`flex items-center gap-2 text-xl font-semibold tracking-tight`,children:[(0,V.jsx)(Cs,{className:`h-5 w-5 text-orange-500`}),`Browse dataset`]}),(0,V.jsxs)(`div`,{className:`ml-auto flex w-full items-center gap-2 sm:w-auto`,children:[(0,V.jsx)(`div`,{className:`w-full sm:w-[380px]`,children:(0,V.jsxs)(Gy,{value:f??void 0,onValueChange:T,children:[(0,V.jsx)(qy,{className:`h-9 border-gray-800 bg-gray-950 text-sm text-white`,children:(0,V.jsx)(Ky,{placeholder:i?`Loading datasets…`:`Select a local dataset`})}),(0,V.jsx)(Xy,{className:`border-gray-800 bg-gray-950 text-white`,children:d.map(e=>(0,V.jsx)(Qy,{value:e.repo_id,className:`text-sm`,children:e.repo_id},e.repo_id))})]})}),f&&g&&(0,V.jsxs)(q,{variant:`outline`,size:`sm`,onClick:()=>u(!0),className:`h-9 gap-1.5 border-gray-800 bg-gray-950 text-xs text-gray-300 hover:bg-gray-900`,children:[(0,V.jsx)(Ps,{className:`h-3.5 w-3.5`}),`Merge`]}),f&&(0,V.jsxs)(q,{variant:`outline`,size:`sm`,onClick:()=>e(`/upload`,{state:{datasetInfo:{dataset_repo_id:f,source:h??`local`}}}),className:`h-9 gap-1.5 border-gray-800 bg-gray-950 text-xs text-gray-300 hover:bg-gray-900`,children:[(0,V.jsx)(Qs,{className:`h-3.5 w-3.5`}),`Upload`]})]})]}),!f&&(0,V.jsxs)(`div`,{className:`rounded-lg border border-gray-800 bg-gray-950 p-10 text-center`,children:[(0,V.jsx)(Cs,{className:`mx-auto mb-3 h-8 w-8 text-gray-700`}),(0,V.jsx)(`p`,{className:`text-sm text-gray-400`,children:`Select a dataset to browse its episodes.`}),!i&&d.length===0&&(0,V.jsx)(`p`,{className:`mt-2 text-xs text-gray-600`,children:`No datasets in the local LeRobot cache. Record one, or download it from the Hub first.`})]}),f&&y&&(0,V.jsxs)(`div`,{className:`flex items-center justify-center gap-2 rounded-lg border border-gray-800 bg-gray-950 p-10 text-sm text-gray-500`,children:[(0,V.jsx)(Ms,{className:`h-4 w-4 animate-spin`}),`Reading dataset…`]}),f&&b&&(0,V.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-red-900/50 bg-red-950/30 p-4`,children:[(0,V.jsx)(ms,{className:`mt-0.5 h-4 w-4 flex-none text-red-400`}),(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`p`,{className:`text-sm font-medium text-red-300`,children:`Could not read this dataset`}),(0,V.jsx)(`p`,{className:`mt-0.5 text-xs text-red-400/80`,children:b})]})]}),f&&v?.success&&(0,V.jsxs)(V.Fragment,{children:[(0,V.jsxs)(`div`,{className:`mb-4 flex flex-wrap items-center gap-x-5 gap-y-1 rounded-lg border border-gray-800 bg-gray-950 px-4 py-2.5 text-xs`,children:[(0,V.jsx)(Z9,{label:`Episodes`,value:String(v.total_episodes)}),(0,V.jsx)(Z9,{label:`Frames`,value:v.total_frames?.toLocaleString()??`—`}),(0,V.jsx)(Z9,{label:`FPS`,value:String(v.fps??`—`)}),(0,V.jsx)(Z9,{label:`Robot`,value:v.robot_type??`—`}),(0,V.jsx)(Z9,{label:`Cameras`,value:v.cameras.join(`, `)||`—`}),x&&(0,V.jsx)(Z9,{label:`This episode`,value:X9(x.duration_s)})]}),(0,V.jsxs)(`div`,{className:`grid grid-cols-1 gap-4 lg:grid-cols-[260px_1fr]`,children:[(0,V.jsx)(Sse,{episodes:v.episodes,selected:m,onSelect:D}),(0,V.jsxs)(`div`,{children:[S&&!x&&(0,V.jsxs)(`div`,{className:`flex h-64 items-center justify-center gap-2 rounded-lg border border-gray-800 bg-gray-950 text-sm text-gray-500`,children:[(0,V.jsx)(Ms,{className:`h-4 w-4 animate-spin`}),`Loading episode…`]}),C&&(0,V.jsx)(`div`,{className:`rounded-lg border border-red-900/50 bg-red-950/30 p-4 text-xs text-red-400`,children:C}),x&&(0,V.jsx)(Dse,{repoId:f,detail:x,onNavigate:D})]})]})]})]}),f&&g&&(0,V.jsx)(Ose,{datasets:r,selectedRepoId:f,open:l,onOpenChange:u,onMerge:E})]})},Mse=()=>{let e=dt(),t=mt(),{toast:n}=$i(),{baseUrl:r,fetchWithHeaders:i}=Tl(),a=e.state?.datasetInfo,[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(!0),[u,d]=(0,_.useState)({tags:[`robotics`,`lerobot`],private:!1}),[f,p]=(0,_.useState)(u.tags.join(`, `)),[m,h]=(0,_.useState)(!1),[g,v]=(0,_.useState)(!1),[y,b]=(0,_.useState)(!1),[x,S]=(0,_.useState)(!1);_.useEffect(()=>{(async()=>{if(!a?.dataset_repo_id){n({title:`No Dataset Information`,description:`Please complete a recording session first.`,variant:`destructive`}),t(`/`);return}try{let e=await i(`${r}/dataset-info`,{method:`POST`,body:JSON.stringify({dataset_repo_id:a.dataset_repo_id})}),t=await e.json();e.ok&&t.success?s({...t,saved_episodes:t.num_episodes,session_elapsed_seconds:a.session_elapsed_seconds||0,source:a.source}):(n({title:`Warning`,description:`Could not load complete dataset information. Using session data.`,variant:`destructive`}),s(a))}catch(e){console.error(`Error loading dataset info:`,e),n({title:`Warning`,description:`Could not connect to backend. Using session data.`,variant:`destructive`}),s(a)}finally{l(!1)}})()},[a,t,n]);let C=e=>{let t=`/spaces/lerobot/visualize_dataset?path=${encodeURIComponent(`/${e}`)}`,n=`https://huggingface.co/login?next=${encodeURIComponent(t)}`;window.open(n,`_blank`,`noopener,noreferrer`)},w=e=>{let t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=e%60;return t>0?`${t}h ${n}m ${r}s`:n>0?`${n}m ${r}s`:`${r}s`},T=async()=>{if(o){h(!0);try{let e=f.split(`,`).map(e=>e.trim()).filter(e=>e.length>0),t=await i(`${r}/upload-dataset`,{method:`POST`,body:JSON.stringify({dataset_repo_id:o.dataset_repo_id,tags:e,private:u.private})}),a=await t.json();if(t.ok&&a.success)v(!0),n({title:`Upload Successful!`,description:`Dataset ${o.dataset_repo_id} has been uploaded to HuggingFace Hub.`});else{let e=`Failed to upload dataset to HuggingFace Hub.`;n({title:`Upload Failed`,description:a.docs_url?(0,V.jsxs)(`span`,{children:[a.message||e,` `,(0,V.jsx)(`a`,{href:a.docs_url,target:`_blank`,rel:`noopener noreferrer`,className:`underline font-medium`,children:`Open setup guide`})]}):a.message||e,variant:`destructive`})}}catch(e){console.error(`Error uploading dataset:`,e),n({title:`Connection Error`,description:`Could not connect to the backend server.`,variant:`destructive`})}finally{h(!1)}}},E=()=>{n({title:`Upload Skipped`,description:`Dataset saved locally. You can upload it manually later.`}),t(`/`)},D=async()=>{if(o){S(!0);try{let e=await i(`${r}/delete-dataset`,{method:`POST`,body:JSON.stringify({dataset_repo_id:o.dataset_repo_id})}),a=await e.json();e.ok&&a.success?(n({title:`Dataset Deleted`,description:`${o.dataset_repo_id} has been removed from disk.`}),t(`/`)):n({title:`Delete Failed`,description:a.message||`Could not delete the dataset.`,variant:`destructive`})}catch{n({title:`Connection Error`,description:`Could not connect to the backend server.`,variant:`destructive`})}finally{S(!1),b(!1)}}};if(c||!o)return(0,V.jsx)(`div`,{className:`min-h-screen bg-black text-white flex items-center justify-center`,children:(0,V.jsxs)(`div`,{className:`text-center`,children:[(0,V.jsx)(`div`,{className:`animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500 mx-auto mb-4`}),(0,V.jsx)(`p`,{className:`text-lg`,children:`Loading dataset information...`})]})});let O=o.source===`both`;return(0,V.jsxs)(`div`,{className:`min-h-screen bg-black text-white p-8`,children:[(0,V.jsxs)(`div`,{className:`max-w-4xl mx-auto`,children:[(0,V.jsxs)(`div`,{className:`flex items-center justify-between mb-8`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,V.jsxs)(q,{onClick:()=>t(`/`),variant:`outline`,className:`border-gray-500 hover:border-gray-200 text-gray-300 hover:text-white`,children:[(0,V.jsx)(as,{className:`w-4 h-4 mr-2`}),`Back to Home`]}),(0,V.jsx)(q,{onClick:()=>b(!0),variant:`outline`,size:`icon`,disabled:x,"aria-label":`Delete dataset from disk`,className:`border-red-500/40 text-red-400 hover:border-red-400 hover:text-red-300 hover:bg-red-500/10`,children:(0,V.jsx)(Xs,{className:`w-4 h-4`})})]}),(0,V.jsxs)(`div`,{className:`flex items-center gap-3`,children:[g?(0,V.jsx)(hs,{className:`w-8 h-8 text-green-500`}):(0,V.jsx)(Cs,{className:`w-8 h-8 text-blue-500`}),(0,V.jsx)(`h1`,{className:`text-3xl font-bold`,children:g?`Upload Complete`:`Dataset Upload`})]})]}),g&&(0,V.jsxs)(`div`,{className:`bg-green-900/20 border border-green-600 rounded-lg p-6 mb-8`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-3 mb-4`,children:[(0,V.jsx)(hs,{className:`w-6 h-6 text-green-500`}),(0,V.jsx)(`h2`,{className:`text-xl font-semibold text-green-400`,children:`Successfully Uploaded!`})]}),(0,V.jsx)(`p`,{className:`text-gray-300 mb-4`,children:`Your dataset has been uploaded to HuggingFace Hub and is now available for training and sharing.`}),(0,V.jsxs)(`div`,{className:`flex flex-col sm:flex-row gap-4`,children:[(0,V.jsxs)(q,{onClick:()=>{let e=`/spaces/lerobot/visualize_dataset?path=${encodeURIComponent(`/${o.dataset_repo_id}`)}`,t=u.private?`https://huggingface.co/login?next=${encodeURIComponent(e)}`:`https://huggingface.co${e}`;window.open(t,`_blank`,`noopener,noreferrer`)},className:`bg-blue-500 hover:bg-blue-600 text-white`,children:[(0,V.jsx)(Es,{className:`w-4 h-4 mr-2`}),`View on HuggingFace Hub`]}),(0,V.jsx)(q,{onClick:()=>t(`/training`,{state:{datasetRepoId:o.dataset_repo_id}}),className:`bg-purple-500 hover:bg-purple-600 text-white`,children:`Start Training`})]})]}),!g&&(0,V.jsxs)(V.Fragment,{children:[(0,V.jsxs)(`div`,{className:`bg-gray-900 rounded-lg p-6 border border-gray-700 mb-8`,children:[(0,V.jsx)(`h2`,{className:`text-xl font-semibold text-white mb-4`,children:`Dataset Summary`}),(0,V.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,V.jsxs)(`div`,{className:`space-y-3`,children:[(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`span`,{className:`text-gray-400`,children:`Repository ID:`}),(0,V.jsx)(`p`,{className:`text-white font-mono text-lg`,children:o.dataset_repo_id})]}),(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`span`,{className:`text-gray-400`,children:`Task:`}),(0,V.jsx)(`p`,{className:`text-white`,children:o.single_task})]})]}),(0,V.jsxs)(`div`,{className:`space-y-3`,children:[(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`span`,{className:`text-gray-400`,children:`Episodes Recorded:`}),(0,V.jsx)(`p`,{className:`text-white text-2xl font-bold text-green-400`,children:o.saved_episodes||o.num_episodes}),o.total_frames&&(0,V.jsxs)(`p`,{className:`text-gray-400 text-sm`,children:[o.total_frames,` total frames`]})]}),(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`span`,{className:`text-gray-400`,children:`Session Duration:`}),(0,V.jsx)(`p`,{className:`text-white`,children:w(o.session_elapsed_seconds||0)}),o.fps&&(0,V.jsxs)(`p`,{className:`text-gray-400 text-sm`,children:[o.fps,` FPS`]})]})]})]})]}),!O&&(0,V.jsxs)(`div`,{className:`bg-gray-900 rounded-lg p-6 border border-gray-700 mb-8`,children:[(0,V.jsx)(`h2`,{className:`text-xl font-semibold text-white mb-6`,children:`Upload Configuration`}),(0,V.jsxs)(`div`,{className:`space-y-6`,children:[(0,V.jsxs)(`div`,{children:[(0,V.jsx)(J,{htmlFor:`tags`,className:`text-gray-300 mb-2 block`,children:`Tags (comma-separated)`}),(0,V.jsx)(k_,{id:`tags`,value:f,onChange:e=>p(e.target.value),placeholder:`robotics, lerobot, manipulation`,className:`bg-gray-800 border-gray-600 text-white`}),(0,V.jsx)(`p`,{className:`text-sm text-gray-500 mt-1`,children:`Tags help others discover your dataset on HuggingFace Hub`})]}),(0,V.jsxs)(`div`,{className:`flex items-center space-x-3`,children:[(0,V.jsx)(J_,{id:`private`,checked:u.private,onCheckedChange:e=>d({...u,private:e})}),(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[u.private?(0,V.jsx)(Ds,{className:`w-4 h-4 text-gray-400`}):(0,V.jsx)(Os,{className:`w-4 h-4 text-gray-400`}),(0,V.jsx)(J,{htmlFor:`private`,className:`text-gray-300`,children:`Make dataset private`})]})]}),(0,V.jsx)(`p`,{className:`text-sm text-gray-500 ml-6`,children:u.private?`Only you will be able to access this dataset`:`Dataset will be publicly accessible on HuggingFace Hub`})]})]}),(0,V.jsx)(`div`,{className:`flex flex-col sm:flex-row gap-4 justify-center`,children:O?(0,V.jsxs)(q,{onClick:()=>C(o.dataset_repo_id),className:`bg-blue-500 hover:bg-blue-600 text-white font-semibold py-4 px-8 text-lg`,children:[(0,V.jsx)(Es,{className:`w-5 h-5 mr-2`}),`View on Hugging Face Hub`]}):(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(q,{onClick:T,disabled:m,className:`bg-blue-500 hover:bg-blue-600 text-white font-semibold py-4 px-8 text-lg`,children:m?(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Ms,{className:`w-5 h-5 mr-2 animate-spin`}),`Uploading to Hub...`]}):(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Qs,{className:`w-5 h-5 mr-2`}),`Upload to HuggingFace Hub`]})}),(0,V.jsx)(q,{onClick:E,disabled:m,variant:`outline`,className:`border-gray-600 text-gray-300 hover:bg-gray-800 hover:text-white py-4 px-8 text-lg`,children:`Skip Upload`})]})}),!O&&(0,V.jsx)(`div`,{className:`mt-8 p-4 bg-blue-900/20 border border-blue-600 rounded-lg`,children:(0,V.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,V.jsx)(ms,{className:`w-5 h-5 text-blue-400 mt-0.5`}),(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`h3`,{className:`font-semibold text-blue-400 mb-2`,children:`About HuggingFace Hub Upload`}),(0,V.jsxs)(`ul`,{className:`text-sm text-gray-300 space-y-1`,children:[(0,V.jsx)(`li`,{children:`• Your dataset will be uploaded to HuggingFace Hub for sharing and collaboration`}),(0,V.jsx)(`li`,{children:`• You need to be logged in to HuggingFace CLI on the server`}),(0,V.jsx)(`li`,{children:`• Uploaded datasets can be used for training models and sharing with the community`}),(0,V.jsx)(`li`,{children:`• You can always upload manually later using the HuggingFace CLI`})]})]})]})})]})]}),(0,V.jsx)($I,{open:y,onOpenChange:b,children:(0,V.jsxs)(tL,{className:`bg-gray-900 border-gray-700 text-white`,children:[(0,V.jsxs)(nL,{children:[(0,V.jsx)(iL,{children:`Delete dataset from disk?`}),(0,V.jsxs)(aL,{className:`text-gray-400`,children:[`This permanently removes `,(0,V.jsx)(`span`,{className:`font-mono text-white`,children:o.dataset_repo_id}),` from your local cache. This action cannot be undone.`]})]}),(0,V.jsxs)(rL,{children:[(0,V.jsx)(sL,{className:`bg-gray-800 border-gray-700 text-white hover:bg-gray-700`,children:`Keep dataset`}),(0,V.jsx)(oL,{onClick:D,disabled:x,className:`bg-red-500 hover:bg-red-600 text-white`,children:x?`Deleting…`:`Delete`})]})]})})]})},Nse=()=>{let e=dt();return(0,_.useEffect)(()=>{console.error(`404 Error: User attempted to access non-existent route:`,e.pathname)},[e.pathname]),(0,V.jsx)(`div`,{className:`min-h-screen flex items-center justify-center bg-gray-100`,children:(0,V.jsxs)(`div`,{className:`text-center`,children:[(0,V.jsx)(`h1`,{className:`text-4xl font-bold mb-4`,children:`404`}),(0,V.jsx)(`p`,{className:`text-xl text-gray-600 mb-4`,children:`Oops! Page not found`}),(0,V.jsx)(`a`,{href:`/`,className:`text-blue-500 hover:text-blue-700 underline`,children:`Return to Home`})]})})},Pse=`lelab-tabs-v1`,Fse=1e3,Ise=3e3,Lse=({children:e})=>{let[t,n]=(0,_.useState)(!0),r=(0,_.useRef)(new Map),i=(0,_.useRef)(``),a=(0,_.useRef)(0),o=(0,_.useRef)(null),s=(0,_.useCallback)(()=>{let e=r.current,t=Date.now()-Ise;for(let[n,r]of e)r.lastSeen{if(typeof window>`u`||typeof BroadcastChannel>`u`)return;i.current=crypto.randomUUID(),a.current=Date.now();let e=new BroadcastChannel(Pse);o.current=e;let t=t=>{e.postMessage({type:t,id:i.current,openedAt:a.current})};e.onmessage=e=>{let t=e.data;if(!t||t.id===i.current)return;let n=r.current;t.type===`HEARTBEAT`?n.set(t.id,{id:t.id,openedAt:t.openedAt,lastSeen:Date.now()}):t.type===`RELEASE`?n.delete(t.id):t.type===`TAKEOVER`&&(n.set(t.id,{id:t.id,openedAt:t.openedAt,lastSeen:Date.now()}),a.current<=t.openedAt&&(a.current=t.openedAt+1)),s()},t(`HEARTBEAT`);let n=setInterval(()=>{t(`HEARTBEAT`),s()},Fse),c=()=>t(`RELEASE`);return window.addEventListener(`beforeunload`,c),()=>{window.removeEventListener(`beforeunload`,c),clearInterval(n),t(`RELEASE`),e.close(),o.current=null}},[s]);let c=(0,_.useCallback)(()=>{a.current=0,o.current?.postMessage({type:`TAKEOVER`,id:i.current,openedAt:0}),s()},[s]);return(0,V.jsxs)(V.Fragment,{children:[t&&e,!t&&(0,V.jsx)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center bg-black/80 backdrop-blur-sm`,role:`dialog`,"aria-modal":`true`,children:(0,V.jsxs)(`div`,{className:`mx-4 max-w-md space-y-4 rounded-lg border bg-background p-6 text-center shadow-lg`,children:[(0,V.jsx)(`h2`,{className:`text-lg font-semibold`,children:`LeLab is already open in another tab`}),(0,V.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Only one tab can control the robot at a time. Switch back to the original tab, or take over here — the other tab will lock.`}),(0,V.jsx)(q,{onClick:c,children:`Use this tab`})]})})]})},Q9=`lelab:teleop-stopped`,Rse=()=>{let{toast:e}=$i();return(0,_.useEffect)(()=>{let t=!1;try{t=sessionStorage.getItem(Q9)===`1`,t&&sessionStorage.removeItem(Q9)}catch{}t&&e({title:`Teleoperation stopped`,description:`The arm was disconnected cleanly when you left the page.`})},[e]),null},$9=`lelab:update-dismissed-sha`;function zse(){let{baseUrl:e,fetchWithHeaders:t}=Tl(),[n,r]=(0,_.useState)(null),[i,a]=(0,_.useState)(!1);return(0,_.useEffect)(()=>{if(Nf())return;let n=!1;return t(`${e}/system/update-check`).then(e=>e.ok?e.json():null).then(e=>{if(n||!e||!e.update_available)return;let t=null;try{t=localStorage.getItem($9)}catch{}t&&t===e.latest_commit||(r(e),a(!0))}).catch(()=>{}),()=>{n=!0}},[e,t]),{status:n,open:i,dismiss:(0,_.useCallback)(e=>{if(e&&n?.latest_commit)try{localStorage.setItem($9,n.latest_commit)}catch{}a(!1)},[n])}}var Bse=()=>{let{status:e,open:t,dismiss:n}=zse(),{baseUrl:r,fetchWithHeaders:i}=Tl(),{toast:a}=$i(),[o,s]=(0,_.useState)(!1),[c,l]=(0,_.useState)(!1),[u,d]=(0,_.useState)(null);if(!e)return null;let f=typeof e.commits_behind==`number`&&e.commits_behind>0?`${e.commits_behind} commit${e.commits_behind===1?``:`s`} behind`:`A new version is available`;return(0,V.jsx)(nf,{open:t,onOpenChange:e=>{!e&&!c&&n(o)},children:(0,V.jsxs)(of,{className:`bg-slate-800 border-slate-700 text-white max-w-lg`,onOpenAutoFocus:e=>e.preventDefault(),children:[(0,V.jsxs)(sf,{children:[(0,V.jsxs)(lf,{className:`flex items-center gap-3 text-white`,children:[(0,V.jsx)(qs,{className:`w-5 h-5 text-amber-400`}),`LeLab update available`]}),(0,V.jsxs)(uf,{className:`text-slate-300`,children:[`You're `,f,` 😱.`,(0,V.jsx)(`br`,{}),`Update to get the latest fixes and features 🤗.`,e.compare_url&&(0,V.jsxs)(V.Fragment,{children:[` `,(0,V.jsx)(`a`,{href:e.compare_url,target:`_blank`,rel:`noreferrer`,className:`text-sky-300 underline hover:text-sky-200`,children:`See what changed`}),`.`]})]})]}),(0,V.jsxs)(`div`,{className:`space-y-4`,children:[(0,V.jsxs)(rv,{children:[(0,V.jsxs)(iv,{className:`group flex items-center gap-1.5 text-xs font-medium text-slate-300 hover:text-white transition-colors`,children:[(0,V.jsx)(ds,{className:`w-3.5 h-3.5 transition-transform group-data-[state=open]:rotate-90`}),`Or update manually`]}),(0,V.jsx)(av,{className:`pt-2`,children:(0,V.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,V.jsx)(`code`,{className:`min-w-0 flex-1 px-2 py-1.5 rounded bg-slate-900 text-sky-300 text-xs break-all whitespace-pre-wrap`,children:e.update_command}),(0,V.jsx)(q,{variant:`outline`,size:`icon`,onClick:async()=>{if(e.update_command)try{await navigator.clipboard.writeText(e.update_command),a({title:`Copied`,description:`Update command copied to clipboard.`})}catch{a({title:`Copy failed`,description:`Select and copy the command manually.`,variant:`destructive`})}},title:`Copy command`,className:`shrink-0 bg-slate-900 border-slate-600 text-white hover:bg-slate-700`,children:(0,V.jsx)(Ss,{className:`w-4 h-4`})})]})})]}),u&&(0,V.jsx)(`pre`,{className:`max-h-40 overflow-auto rounded bg-slate-900 p-2 text-xs text-slate-300 whitespace-pre-wrap`,children:u}),(0,V.jsxs)(`div`,{className:`flex items-center justify-between gap-3 pt-1`,children:[(0,V.jsxs)(`label`,{className:`flex items-center gap-2 text-sm text-slate-300`,children:[(0,V.jsx)(J_,{checked:o,onCheckedChange:e=>s(e===!0),className:`border-slate-300 data-[state=checked]:bg-slate-300 data-[state=checked]:text-slate-900`}),`Don't ask me again`]}),(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,V.jsx)(q,{variant:`ghost`,onClick:()=>n(o),disabled:c,className:`text-slate-300 hover:bg-slate-700 hover:text-white`,children:`Later`}),e.can_auto_update&&(0,V.jsx)(q,{onClick:async()=>{l(!0),d(null);try{let e=await(await i(`${r}/system/update`,{method:`POST`})).json();e.success?(a({title:`Updated`,description:e.message}),n(!1)):(d(e.output||e.message),a({title:`Update failed`,description:e.message,variant:`destructive`}))}catch(e){a({title:`Update failed`,description:e instanceof Error?e.message:String(e),variant:`destructive`})}finally{l(!1)}},disabled:c,children:c?(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Ms,{className:`w-4 h-4 mr-2 animate-spin`}),`Updating…`]}):`Update now`})]})]})]})]})})},Vse=new Xr;function Hse(){return(0,V.jsx)($r,{client:Vse,children:(0,V.jsx)(uh,{children:(0,V.jsx)(ti,{children:(0,V.jsx)(wl,{children:(0,V.jsx)(Dl,{children:(0,V.jsx)(Ri,{children:(0,V.jsx)(Vi,{children:(0,V.jsxs)(jn,{children:[(0,V.jsx)(Lse,{children:(0,V.jsxs)(Yf,{children:[(0,V.jsx)(Rse,{}),(0,V.jsx)(Bse,{}),(0,V.jsxs)(Vt,{children:[(0,V.jsx)(B,{path:`/`,element:(0,V.jsx)(tx,{})}),(0,V.jsx)(B,{path:`/teleoperation`,element:(0,V.jsx)(gN,{})}),(0,V.jsx)(B,{path:`/recording`,element:(0,V.jsx)(ure,{})}),(0,V.jsx)(B,{path:`/upload`,element:(0,V.jsx)(Mse,{})}),(0,V.jsx)(B,{path:`/training`,element:(0,V.jsx)(K9,{})}),(0,V.jsx)(B,{path:`/training/:jobId`,element:(0,V.jsx)(K9,{})}),(0,V.jsx)(B,{path:`/inference`,element:(0,V.jsx)(_se,{})}),(0,V.jsx)(B,{path:`/calibration`,element:(0,V.jsx)(PN,{})}),(0,V.jsx)(B,{path:`/edit-dataset`,element:(0,V.jsx)(jse,{})}),(0,V.jsx)(B,{path:`*`,element:(0,V.jsx)(Nse,{})})]})]})}),(0,V.jsx)(ol,{})]})})})})})})})})}(0,y.createRoot)(document.getElementById(`root`)).render((0,V.jsx)(Hse,{})); \ No newline at end of file diff --git a/frontend/dist/index.html b/frontend/dist/index.html index 8bf573dde..440b88f3b 100644 --- a/frontend/dist/index.html +++ b/frontend/dist/index.html @@ -10,7 +10,7 @@ - + diff --git a/frontend/src/components/dataset/MergeDatasetsDialog.test.tsx b/frontend/src/components/dataset/MergeDatasetsDialog.test.tsx new file mode 100644 index 000000000..abdf357e4 --- /dev/null +++ b/frontend/src/components/dataset/MergeDatasetsDialog.test.tsx @@ -0,0 +1,41 @@ +// @vitest-environment jsdom +import React, { act } from "react"; +import { createRoot } from "react-dom/client"; +import { expect, test } from "vitest"; + +import MergeDatasetsDialog from "./MergeDatasetsDialog"; + +test("opens with the browsed local dataset retained as the first merge source", async () => { + Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true }); + const host = document.createElement("div"); + document.body.append(host); + const root = createRoot(host); + + try { + await act(async () => { + root.render( + {}} + onMerge={async () => {}} + />, + ); + }); + + expect(document.body.textContent).toContain("local/browsed is included"); + expect(document.body.textContent).toContain("local/additional"); + expect(document.body.textContent).toContain("Select at least one additional dataset."); + const mergeButton = [...document.body.querySelectorAll("button")].find((button) => + button.textContent?.includes("Merge datasets"), + ) as HTMLButtonElement; + expect(mergeButton.disabled).toBe(true); + } finally { + await act(async () => root.unmount()); + host.remove(); + } +}); diff --git a/frontend/src/components/dataset/MergeDatasetsDialog.tsx b/frontend/src/components/dataset/MergeDatasetsDialog.tsx index 838faadfd..c38422a91 100644 --- a/frontend/src/components/dataset/MergeDatasetsDialog.tsx +++ b/frontend/src/components/dataset/MergeDatasetsDialog.tsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { Loader2 } from "lucide-react"; import { Button } from "@/components/ui/button"; @@ -17,6 +17,7 @@ import { DatasetItem } from "@/lib/replayApi"; interface MergeDatasetsDialogProps { datasets: DatasetItem[]; + selectedRepoId: string; open: boolean; onOpenChange: (open: boolean) => void; onMerge: (sourceRepoIds: string[], outputName: string) => Promise; @@ -24,18 +25,23 @@ interface MergeDatasetsDialogProps { export default function MergeDatasetsDialog({ datasets, + selectedRepoId, open, onOpenChange, onMerge, }: MergeDatasetsDialogProps) { - const [selected, setSelected] = useState([]); + const [selected, setSelected] = useState([selectedRepoId]); const [outputName, setOutputName] = useState(""); const [merging, setMerging] = useState(false); const [error, setError] = useState(null); const localDatasets = useMemo( - () => datasets.filter((dataset) => dataset.source === "local" || dataset.source === "both"), - [datasets], + () => + datasets.filter( + (dataset) => + dataset.repo_id !== selectedRepoId && (dataset.source === "local" || dataset.source === "both"), + ), + [datasets, selectedRepoId], ); const canMerge = selected.length >= 2 && /^[A-Za-z0-9._-]+$/.test(outputName) && !merging; @@ -45,12 +51,21 @@ export default function MergeDatasetsDialog({ }; const reset = () => { - setSelected([]); + setSelected([selectedRepoId]); setOutputName(""); setMerging(false); setError(null); }; + useEffect(() => { + if (open) { + setSelected([selectedRepoId]); + setOutputName(""); + setMerging(false); + setError(null); + } + }, [open, selectedRepoId]); + const handleOpenChange = (nextOpen: boolean) => { if (!merging && !nextOpen) reset(); onOpenChange(nextOpen); @@ -76,13 +91,15 @@ export default function MergeDatasetsDialog({ Merge local datasets - Select two or more local datasets. Their source files stay unchanged; the merged dataset is saved locally. + {selectedRepoId} is included. Select at least one more local dataset. Their source files stay + unchanged; the merged dataset is saved locally.
+

{selectedRepoId}

{localDatasets.map((dataset) => (
-

Select at least two datasets.

+

Select at least one additional dataset.

- + {repoId && selectedIsLocal && ( + + )} {/* Picking a dataset now lands here rather than on /upload, so the upload + delete flow hangs off the page you browse from. */} {repoId && ( @@ -228,12 +231,15 @@ const EditDataset = () => { )}
- + {repoId && selectedIsLocal && ( + + )} ); }; diff --git a/lelab/datasets.py b/lelab/datasets.py index f5b575218..d4f2f3e98 100644 --- a/lelab/datasets.py +++ b/lelab/datasets.py @@ -27,6 +27,7 @@ from lerobot.datasets.dataset_tools import merge_datasets from . import episode_media +from .dataset_repair import DatasetRepairError, repair_local_dataset from .utils.hf_auth import cached_whoami, shared_hf_api logger = logging.getLogger(__name__) @@ -202,6 +203,15 @@ def handle_merge_local_datasets(source_repo_ids: list[str], output_name: str) -> if output_dir.exists(): raise ValueError(f"A local dataset already exists at {output_repo_id}") + # An interrupted local recording can have data and info.json but no episode + # index. LeRobot then treats it as absent and attempts a Hub lookup, so make + # each source readable before constructing a dataset from its local path. + try: + for repo_id in source_repo_ids: + repair_local_dataset(repo_id) + except DatasetRepairError as exc: + raise ValueError(str(exc)) from exc + source_dirs = [episode_media.resolve_dataset_dir(repo_id) for repo_id in source_repo_ids] datasets = [ LeRobotDataset(repo_id=repo_id, root=source_dir) diff --git a/tests/test_datasets.py b/tests/test_datasets.py index 30de15766..744a3f57c 100644 --- a/tests/test_datasets.py +++ b/tests/test_datasets.py @@ -172,6 +172,65 @@ def fake_merge(datasets, output_repo_id: str, output_dir: Path): assert (tmp_lerobot_home / "bob" / "second" / "meta" / "info.json").is_file() +def test_merge_local_datasets_repairs_an_interrupted_source_before_opening( + tmp_lerobot_home: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """A recorded-but-unfinalized source must stay local when it is merged.""" + from lelab import datasets as datasets_mod + + from .test_dataset_repair import _record + + # dataset_repair follows LeRobot's import-time cache constant, whereas the + # browser functions use the per-test environment variable. + monkeypatch.setattr("lerobot.utils.constants.HF_LEROBOT_HOME", tmp_lerobot_home) + monkeypatch.setattr("lerobot.datasets.dataset_metadata.HF_LEROBOT_HOME", tmp_lerobot_home) + first = _record("alice/first", video=False, episodes=1) + _record("bob/second", video=False, episodes=1) + # This is the on-disk state an interrupted recording leaves behind. With + # LeRobot v0.6.0, opening it before repair would fall through to the Hub. + import shutil + + shutil.rmtree(first / "meta" / "episodes") + + class FakeDataset: + def __init__(self, repo_id: str, root: Path) -> None: + assert (root / "meta" / "episodes").is_dir() + self.repo_id = repo_id + + class FakeMergedDataset: + num_episodes = 4 + num_frames = 4 + + def fake_merge(datasets, output_repo_id: str, output_dir: Path): + (output_dir / "meta").mkdir(parents=True) + (output_dir / "meta" / "info.json").write_text("{}") + return FakeMergedDataset() + + monkeypatch.setattr(datasets_mod, "LeRobotDataset", FakeDataset) + monkeypatch.setattr(datasets_mod, "merge_datasets", fake_merge) + + result = datasets_mod.handle_merge_local_datasets(["alice/first", "bob/second"], "combined") + + assert result["success"] is True + assert (first / "meta" / "episodes").is_dir() + + +def test_merge_local_datasets_reports_unrepairable_source( + tmp_lerobot_home: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + from lelab import datasets as datasets_mod + from lelab.dataset_repair import DatasetRepairError + + monkeypatch.setattr( + datasets_mod, + "repair_local_dataset", + lambda _repo_id: (_ for _ in ()).throw(DatasetRepairError("Re-record it")), + ) + + with pytest.raises(ValueError, match="Re-record it"): + datasets_mod.handle_merge_local_datasets(["alice/first", "bob/second"], "combined") + + @pytest.mark.parametrize( ("source_repo_ids", "output_name", "message"), [ From 328d9de3697a1e7b0adb9c11ea45b91d66f37b2b Mon Sep 17 00:00:00 2001 From: Samuel-Hills Date: Wed, 30 Sep 2026 18:40:49 -0400 Subject: [PATCH 3/3] fix: keep generated frontend index fresh --- frontend/dist/index.html | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/frontend/dist/index.html b/frontend/dist/index.html index 440b88f3b..7ec5cb961 100644 --- a/frontend/dist/index.html +++ b/frontend/dist/index.html @@ -1,20 +1,20 @@ - - - - - - LeLab - - - - - - + + + + + + LeLab + + + + + + - - - -
- - + + + +
+ +