ldrouter 1.18.0 → 1.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -8,9 +8,10 @@ import { uuid } from '../../auth/ids.js';
|
|
|
8
8
|
import { GatewayError } from '../../errors.js';
|
|
9
9
|
import { circuitBlocks } from '../../routing/circuit.js';
|
|
10
10
|
const MemberSpec = z.object({ modelId: z.string(), position: z.number().int().min(0), enabled: z.boolean().default(true) });
|
|
11
|
+
const OptionalSlug = z.preprocess((value) => typeof value === 'string' && value.trim() === '' ? undefined : value, z.string().min(1).max(64).optional());
|
|
11
12
|
const ComboCreate = z.object({
|
|
12
13
|
name: z.string().min(1).max(128),
|
|
13
|
-
slug:
|
|
14
|
+
slug: OptionalSlug,
|
|
14
15
|
mode: z.literal('fallback').default('fallback'),
|
|
15
16
|
maxTotalAttempts: z.number().int().min(1).max(8).optional(),
|
|
16
17
|
enabled: z.boolean().optional(),
|
|
@@ -345,5 +345,5 @@ Please change the parent <Route path="${N}"> to <Route path="${N==="/"?"*":`${N}
|
|
|
345
345
|
To pick up a draggable item, press the space bar.
|
|
346
346
|
While dragging, use the arrow keys to move the item.
|
|
347
347
|
Press space again to drop the item in its new position, or press escape to cancel.
|
|
348
|
-
`},H_={onDragStart(n){let{active:a}=n;return"Picked up draggable item "+a.id+"."},onDragOver(n){let{active:a,over:l}=n;return l?"Draggable item "+a.id+" was moved over droppable area "+l.id+".":"Draggable item "+a.id+" is no longer over a droppable area."},onDragEnd(n){let{active:a,over:l}=n;return l?"Draggable item "+a.id+" was dropped over droppable area "+l.id:"Draggable item "+a.id+" was dropped."},onDragCancel(n){let{active:a}=n;return"Dragging was cancelled. Draggable item "+a.id+" was dropped."}};function I_(n){let{announcements:a=H_,container:l,hiddenTextDescribedById:s,screenReaderInstructions:c=B_}=n;const{announce:u,announcement:f}=z_(),p=xi("DndLiveRegion"),[g,v]=m.useState(!1);if(m.useEffect(()=>{v(!0)},[]),L_(m.useMemo(()=>({onDragStart(y){let{active:b}=y;u(a.onDragStart({active:b}))},onDragMove(y){let{active:b,over:w}=y;a.onDragMove&&u(a.onDragMove({active:b,over:w}))},onDragOver(y){let{active:b,over:w}=y;u(a.onDragOver({active:b,over:w}))},onDragEnd(y){let{active:b,over:w}=y;u(a.onDragEnd({active:b,over:w}))},onDragCancel(y){let{active:b,over:w}=y;u(a.onDragCancel({active:b,over:w}))}}),[u,a])),!g)return null;const x=ue.createElement(ue.Fragment,null,ue.createElement(__,{id:s,value:c.draggable}),ue.createElement(k_,{id:p,announcement:f}));return l?ba.createPortal(x,l):x}var Gt;(function(n){n.DragStart="dragStart",n.DragMove="dragMove",n.DragEnd="dragEnd",n.DragCancel="dragCancel",n.DragOver="dragOver",n.RegisterDroppable="registerDroppable",n.SetDroppableDisabled="setDroppableDisabled",n.UnregisterDroppable="unregisterDroppable"})(Gt||(Gt={}));function hu(){}function Mb(n,a){return m.useMemo(()=>({sensor:n,options:a??{}}),[n,a])}function P_(){for(var n=arguments.length,a=new Array(n),l=0;l<n;l++)a[l]=arguments[l];return m.useMemo(()=>[...a].filter(s=>s!=null),[...a])}const Ea=Object.freeze({x:0,y:0});function lS(n,a){return Math.sqrt(Math.pow(n.x-a.x,2)+Math.pow(n.y-a.y,2))}function sS(n,a){let{data:{value:l}}=n,{data:{value:s}}=a;return l-s}function q_(n,a){let{data:{value:l}}=n,{data:{value:s}}=a;return s-l}function Ab(n){let{left:a,top:l,height:s,width:c}=n;return[{x:a,y:l},{x:a+c,y:l},{x:a,y:l+s},{x:a+c,y:l+s}]}function oS(n,a){if(!n||n.length===0)return null;const[l]=n;return l[a]}function Db(n,a,l){return a===void 0&&(a=n.left),l===void 0&&(l=n.top),{x:a+n.width*.5,y:l+n.height*.5}}const V_=n=>{let{collisionRect:a,droppableRects:l,droppableContainers:s}=n;const c=Db(a,a.left,a.top),u=[];for(const f of s){const{id:p}=f,g=l.get(p);if(g){const v=lS(Db(g),c);u.push({id:p,data:{droppableContainer:f,value:v}})}}return u.sort(sS)},$_=n=>{let{collisionRect:a,droppableRects:l,droppableContainers:s}=n;const c=Ab(a),u=[];for(const f of s){const{id:p}=f,g=l.get(p);if(g){const v=Ab(g),x=c.reduce((b,w,E)=>b+lS(v[E],w),0),y=Number((x/4).toFixed(4));u.push({id:p,data:{droppableContainer:f,value:y}})}}return u.sort(sS)};function Y_(n,a){const l=Math.max(a.top,n.top),s=Math.max(a.left,n.left),c=Math.min(a.left+a.width,n.left+n.width),u=Math.min(a.top+a.height,n.top+n.height),f=c-s,p=u-l;if(s<c&&l<u){const g=a.width*a.height,v=n.width*n.height,x=f*p,y=x/(g+v-x);return Number(y.toFixed(4))}return 0}const G_=n=>{let{collisionRect:a,droppableRects:l,droppableContainers:s}=n;const c=[];for(const u of s){const{id:f}=u,p=l.get(f);if(p){const g=Y_(p,a);g>0&&c.push({id:f,data:{droppableContainer:u,value:g}})}}return c.sort(q_)};function K_(n,a,l){return{...n,scaleX:a&&l?a.width/l.width:1,scaleY:a&&l?a.height/l.height:1}}function iS(n,a){return n&&a?{x:n.left-a.left,y:n.top-a.top}:Ea}function X_(n){return function(l){for(var s=arguments.length,c=new Array(s>1?s-1:0),u=1;u<s;u++)c[u-1]=arguments[u];return c.reduce((f,p)=>({...f,top:f.top+n*p.y,bottom:f.bottom+n*p.y,left:f.left+n*p.x,right:f.right+n*p.x}),{...l})}}const F_=X_(1);function Q_(n){if(n.startsWith("matrix3d(")){const a=n.slice(9,-1).split(/, /);return{x:+a[12],y:+a[13],scaleX:+a[0],scaleY:+a[5]}}else if(n.startsWith("matrix(")){const a=n.slice(7,-1).split(/, /);return{x:+a[4],y:+a[5],scaleX:+a[0],scaleY:+a[3]}}return null}function Z_(n,a,l){const s=Q_(a);if(!s)return n;const{scaleX:c,scaleY:u,x:f,y:p}=s,g=n.left-f-(1-c)*parseFloat(l),v=n.top-p-(1-u)*parseFloat(l.slice(l.indexOf(" ")+1)),x=c?n.width/c:n.width,y=u?n.height/u:n.height;return{width:x,height:y,top:v,right:g+x,bottom:v+y,left:g}}const J_={ignoreTransform:!1};function Qs(n,a){a===void 0&&(a=J_);let l=n.getBoundingClientRect();if(a.ignoreTransform){const{transform:v,transformOrigin:x}=zn(n).getComputedStyle(n);v&&(l=Z_(l,v,x))}const{top:s,left:c,width:u,height:f,bottom:p,right:g}=l;return{top:s,left:c,width:u,height:f,bottom:p,right:g}}function Ob(n){return Qs(n,{ignoreTransform:!0})}function W_(n){const a=n.innerWidth,l=n.innerHeight;return{top:0,left:0,right:a,bottom:l,width:a,height:l}}function e3(n,a){return a===void 0&&(a=zn(n).getComputedStyle(n)),a.position==="fixed"}function t3(n,a){a===void 0&&(a=zn(n).getComputedStyle(n));const l=/(auto|scroll|overlay)/;return["overflow","overflowX","overflowY"].some(c=>{const u=a[c];return typeof u=="string"?l.test(u):!1})}function Fu(n,a){const l=[];function s(c){if(a!=null&&l.length>=a||!c)return l;if(Ep(c)&&c.scrollingElement!=null&&!l.includes(c.scrollingElement))return l.push(c.scrollingElement),l;if(!gi(c)||nS(c)||l.includes(c))return l;const u=zn(n).getComputedStyle(c);return c!==n&&t3(c,u)&&l.push(c),e3(c,u)?l:s(c.parentNode)}return n?s(n):l}function cS(n){const[a]=Fu(n,1);return a??null}function kh(n){return!Xu||!n?null:Xs(n)?n:Cp(n)?Ep(n)||n===Fs(n).scrollingElement?window:gi(n)?n:null:null}function uS(n){return Xs(n)?n.scrollX:n.scrollLeft}function dS(n){return Xs(n)?n.scrollY:n.scrollTop}function hm(n){return{x:uS(n),y:dS(n)}}var Wt;(function(n){n[n.Forward=1]="Forward",n[n.Backward=-1]="Backward"})(Wt||(Wt={}));function fS(n){return!Xu||!n?!1:n===document.scrollingElement}function hS(n){const a={x:0,y:0},l=fS(n)?{height:window.innerHeight,width:window.innerWidth}:{height:n.clientHeight,width:n.clientWidth},s={x:n.scrollWidth-l.width,y:n.scrollHeight-l.height},c=n.scrollTop<=a.y,u=n.scrollLeft<=a.x,f=n.scrollTop>=s.y,p=n.scrollLeft>=s.x;return{isTop:c,isLeft:u,isBottom:f,isRight:p,maxScroll:s,minScroll:a}}const n3={x:.2,y:.2};function a3(n,a,l,s,c){let{top:u,left:f,right:p,bottom:g}=l;s===void 0&&(s=10),c===void 0&&(c=n3);const{isTop:v,isBottom:x,isLeft:y,isRight:b}=hS(n),w={x:0,y:0},E={x:0,y:0},j={height:a.height*c.y,width:a.width*c.x};return!v&&u<=a.top+j.height?(w.y=Wt.Backward,E.y=s*Math.abs((a.top+j.height-u)/j.height)):!x&&g>=a.bottom-j.height&&(w.y=Wt.Forward,E.y=s*Math.abs((a.bottom-j.height-g)/j.height)),!b&&p>=a.right-j.width?(w.x=Wt.Forward,E.x=s*Math.abs((a.right-j.width-p)/j.width)):!y&&f<=a.left+j.width&&(w.x=Wt.Backward,E.x=s*Math.abs((a.left+j.width-f)/j.width)),{direction:w,speed:E}}function r3(n){if(n===document.scrollingElement){const{innerWidth:u,innerHeight:f}=window;return{top:0,left:0,right:u,bottom:f,width:u,height:f}}const{top:a,left:l,right:s,bottom:c}=n.getBoundingClientRect();return{top:a,left:l,right:s,bottom:c,width:n.clientWidth,height:n.clientHeight}}function mS(n){return n.reduce((a,l)=>Us(a,hm(l)),Ea)}function l3(n){return n.reduce((a,l)=>a+uS(l),0)}function s3(n){return n.reduce((a,l)=>a+dS(l),0)}function o3(n,a){if(a===void 0&&(a=Qs),!n)return;const{top:l,left:s,bottom:c,right:u}=a(n);cS(n)&&(c<=0||u<=0||l>=window.innerHeight||s>=window.innerWidth)&&n.scrollIntoView({block:"center",inline:"center"})}const i3=[["x",["left","right"],l3],["y",["top","bottom"],s3]];class Tp{constructor(a,l){this.rect=void 0,this.width=void 0,this.height=void 0,this.top=void 0,this.bottom=void 0,this.right=void 0,this.left=void 0;const s=Fu(l),c=mS(s);this.rect={...a},this.width=a.width,this.height=a.height;for(const[u,f,p]of i3)for(const g of f)Object.defineProperty(this,g,{get:()=>{const v=p(s),x=c[u]-v;return this.rect[g]+x},enumerable:!0});Object.defineProperty(this,"rect",{enumerable:!1})}}class Xo{constructor(a){this.target=void 0,this.listeners=[],this.removeAll=()=>{this.listeners.forEach(l=>{var s;return(s=this.target)==null?void 0:s.removeEventListener(...l)})},this.target=a}add(a,l,s){var c;(c=this.target)==null||c.addEventListener(a,l,s),this.listeners.push([a,l,s])}}function c3(n){const{EventTarget:a}=zn(n);return n instanceof a?n:Fs(n)}function zh(n,a){const l=Math.abs(n.x),s=Math.abs(n.y);return typeof a=="number"?Math.sqrt(l**2+s**2)>a:"x"in a&&"y"in a?l>a.x&&s>a.y:"x"in a?l>a.x:"y"in a?s>a.y:!1}var la;(function(n){n.Click="click",n.DragStart="dragstart",n.Keydown="keydown",n.ContextMenu="contextmenu",n.Resize="resize",n.SelectionChange="selectionchange",n.VisibilityChange="visibilitychange"})(la||(la={}));function _b(n){n.preventDefault()}function u3(n){n.stopPropagation()}var Ke;(function(n){n.Space="Space",n.Down="ArrowDown",n.Right="ArrowRight",n.Left="ArrowLeft",n.Up="ArrowUp",n.Esc="Escape",n.Enter="Enter",n.Tab="Tab"})(Ke||(Ke={}));const pS={start:[Ke.Space,Ke.Enter],cancel:[Ke.Esc],end:[Ke.Space,Ke.Enter,Ke.Tab]},d3=(n,a)=>{let{currentCoordinates:l}=a;switch(n.code){case Ke.Right:return{...l,x:l.x+25};case Ke.Left:return{...l,x:l.x-25};case Ke.Down:return{...l,y:l.y+25};case Ke.Up:return{...l,y:l.y-25}}};class Mp{constructor(a){this.props=void 0,this.autoScrollEnabled=!1,this.referenceCoordinates=void 0,this.listeners=void 0,this.windowListeners=void 0,this.props=a;const{event:{target:l}}=a;this.props=a,this.listeners=new Xo(Fs(l)),this.windowListeners=new Xo(zn(l)),this.handleKeyDown=this.handleKeyDown.bind(this),this.handleCancel=this.handleCancel.bind(this),this.attach()}attach(){this.handleStart(),this.windowListeners.add(la.Resize,this.handleCancel),this.windowListeners.add(la.VisibilityChange,this.handleCancel),setTimeout(()=>this.listeners.add(la.Keydown,this.handleKeyDown))}handleStart(){const{activeNode:a,onStart:l}=this.props,s=a.node.current;s&&o3(s),l(Ea)}handleKeyDown(a){if(Np(a)){const{active:l,context:s,options:c}=this.props,{keyboardCodes:u=pS,coordinateGetter:f=d3,scrollBehavior:p="smooth"}=c,{code:g}=a;if(u.end.includes(g)){this.handleEnd(a);return}if(u.cancel.includes(g)){this.handleCancel(a);return}const{collisionRect:v}=s.current,x=v?{x:v.left,y:v.top}:Ea;this.referenceCoordinates||(this.referenceCoordinates=x);const y=f(a,{active:l,context:s.current,currentCoordinates:x});if(y){const b=ni(y,x),w={x:0,y:0},{scrollableAncestors:E}=s.current;for(const j of E){const C=a.code,{isTop:N,isRight:M,isLeft:T,isBottom:D,maxScroll:O,minScroll:A}=hS(j),U=r3(j),k={x:Math.min(C===Ke.Right?U.right-U.width/2:U.right,Math.max(C===Ke.Right?U.left:U.left+U.width/2,y.x)),y:Math.min(C===Ke.Down?U.bottom-U.height/2:U.bottom,Math.max(C===Ke.Down?U.top:U.top+U.height/2,y.y))},$=C===Ke.Right&&!M||C===Ke.Left&&!T,X=C===Ke.Down&&!D||C===Ke.Up&&!N;if($&&k.x!==y.x){const te=j.scrollLeft+b.x,G=C===Ke.Right&&te<=O.x||C===Ke.Left&&te>=A.x;if(G&&!b.y){j.scrollTo({left:te,behavior:p});return}G?w.x=j.scrollLeft-te:w.x=C===Ke.Right?j.scrollLeft-O.x:j.scrollLeft-A.x,w.x&&j.scrollBy({left:-w.x,behavior:p});break}else if(X&&k.y!==y.y){const te=j.scrollTop+b.y,G=C===Ke.Down&&te<=O.y||C===Ke.Up&&te>=A.y;if(G&&!b.x){j.scrollTo({top:te,behavior:p});return}G?w.y=j.scrollTop-te:w.y=C===Ke.Down?j.scrollTop-O.y:j.scrollTop-A.y,w.y&&j.scrollBy({top:-w.y,behavior:p});break}}this.handleMove(a,Us(ni(y,this.referenceCoordinates),w))}}}handleMove(a,l){const{onMove:s}=this.props;a.preventDefault(),s(l)}handleEnd(a){const{onEnd:l}=this.props;a.preventDefault(),this.detach(),l()}handleCancel(a){const{onCancel:l}=this.props;a.preventDefault(),this.detach(),l()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll()}}Mp.activators=[{eventName:"onKeyDown",handler:(n,a,l)=>{let{keyboardCodes:s=pS,onActivation:c}=a,{active:u}=l;const{code:f}=n.nativeEvent;if(s.start.includes(f)){const p=u.activatorNode.current;return p&&n.target!==p?!1:(n.preventDefault(),c==null||c({event:n.nativeEvent}),!0)}return!1}}];function kb(n){return!!(n&&"distance"in n)}function zb(n){return!!(n&&"delay"in n)}class Ap{constructor(a,l,s){var c;s===void 0&&(s=c3(a.event.target)),this.props=void 0,this.events=void 0,this.autoScrollEnabled=!0,this.document=void 0,this.activated=!1,this.initialCoordinates=void 0,this.timeoutId=null,this.listeners=void 0,this.documentListeners=void 0,this.windowListeners=void 0,this.props=a,this.events=l;const{event:u}=a,{target:f}=u;this.props=a,this.events=l,this.document=Fs(f),this.documentListeners=new Xo(this.document),this.listeners=new Xo(s),this.windowListeners=new Xo(zn(f)),this.initialCoordinates=(c=fm(u))!=null?c:Ea,this.handleStart=this.handleStart.bind(this),this.handleMove=this.handleMove.bind(this),this.handleEnd=this.handleEnd.bind(this),this.handleCancel=this.handleCancel.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.removeTextSelection=this.removeTextSelection.bind(this),this.attach()}attach(){const{events:a,props:{options:{activationConstraint:l,bypassActivationConstraint:s}}}=this;if(this.listeners.add(a.move.name,this.handleMove,{passive:!1}),this.listeners.add(a.end.name,this.handleEnd),a.cancel&&this.listeners.add(a.cancel.name,this.handleCancel),this.windowListeners.add(la.Resize,this.handleCancel),this.windowListeners.add(la.DragStart,_b),this.windowListeners.add(la.VisibilityChange,this.handleCancel),this.windowListeners.add(la.ContextMenu,_b),this.documentListeners.add(la.Keydown,this.handleKeydown),l){if(s!=null&&s({event:this.props.event,activeNode:this.props.activeNode,options:this.props.options}))return this.handleStart();if(zb(l)){this.timeoutId=setTimeout(this.handleStart,l.delay),this.handlePending(l);return}if(kb(l)){this.handlePending(l);return}}this.handleStart()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll(),setTimeout(this.documentListeners.removeAll,50),this.timeoutId!==null&&(clearTimeout(this.timeoutId),this.timeoutId=null)}handlePending(a,l){const{active:s,onPending:c}=this.props;c(s,a,this.initialCoordinates,l)}handleStart(){const{initialCoordinates:a}=this,{onStart:l}=this.props;a&&(this.activated=!0,this.documentListeners.add(la.Click,u3,{capture:!0}),this.removeTextSelection(),this.documentListeners.add(la.SelectionChange,this.removeTextSelection),l(a))}handleMove(a){var l;const{activated:s,initialCoordinates:c,props:u}=this,{onMove:f,options:{activationConstraint:p}}=u;if(!c)return;const g=(l=fm(a))!=null?l:Ea,v=ni(c,g);if(!s&&p){if(kb(p)){if(p.tolerance!=null&&zh(v,p.tolerance))return this.handleCancel();if(zh(v,p.distance))return this.handleStart()}if(zb(p)&&zh(v,p.tolerance))return this.handleCancel();this.handlePending(p,v);return}a.cancelable&&a.preventDefault(),f(g)}handleEnd(){const{onAbort:a,onEnd:l}=this.props;this.detach(),this.activated||a(this.props.active),l()}handleCancel(){const{onAbort:a,onCancel:l}=this.props;this.detach(),this.activated||a(this.props.active),l()}handleKeydown(a){a.code===Ke.Esc&&this.handleCancel()}removeTextSelection(){var a;(a=this.document.getSelection())==null||a.removeAllRanges()}}const f3={cancel:{name:"pointercancel"},move:{name:"pointermove"},end:{name:"pointerup"}};class Dp extends Ap{constructor(a){const{event:l}=a,s=Fs(l.target);super(a,f3,s)}}Dp.activators=[{eventName:"onPointerDown",handler:(n,a)=>{let{nativeEvent:l}=n,{onActivation:s}=a;return!l.isPrimary||l.button!==0?!1:(s==null||s({event:l}),!0)}}];const h3={move:{name:"mousemove"},end:{name:"mouseup"}};var mm;(function(n){n[n.RightClick=2]="RightClick"})(mm||(mm={}));class m3 extends Ap{constructor(a){super(a,h3,Fs(a.event.target))}}m3.activators=[{eventName:"onMouseDown",handler:(n,a)=>{let{nativeEvent:l}=n,{onActivation:s}=a;return l.button===mm.RightClick?!1:(s==null||s({event:l}),!0)}}];const Lh={cancel:{name:"touchcancel"},move:{name:"touchmove"},end:{name:"touchend"}};class p3 extends Ap{constructor(a){super(a,Lh)}static setup(){return window.addEventListener(Lh.move.name,a,{capture:!1,passive:!1}),function(){window.removeEventListener(Lh.move.name,a)};function a(){}}}p3.activators=[{eventName:"onTouchStart",handler:(n,a)=>{let{nativeEvent:l}=n,{onActivation:s}=a;const{touches:c}=l;return c.length>1?!1:(s==null||s({event:l}),!0)}}];var Fo;(function(n){n[n.Pointer=0]="Pointer",n[n.DraggableRect=1]="DraggableRect"})(Fo||(Fo={}));var mu;(function(n){n[n.TreeOrder=0]="TreeOrder",n[n.ReversedTreeOrder=1]="ReversedTreeOrder"})(mu||(mu={}));function g3(n){let{acceleration:a,activator:l=Fo.Pointer,canScroll:s,draggingRect:c,enabled:u,interval:f=5,order:p=mu.TreeOrder,pointerCoordinates:g,scrollableAncestors:v,scrollableAncestorRects:x,delta:y,threshold:b}=n;const w=x3({delta:y,disabled:!u}),[E,j]=T_(),C=m.useRef({x:0,y:0}),N=m.useRef({x:0,y:0}),M=m.useMemo(()=>{switch(l){case Fo.Pointer:return g?{top:g.y,bottom:g.y,left:g.x,right:g.x}:null;case Fo.DraggableRect:return c}},[l,c,g]),T=m.useRef(null),D=m.useCallback(()=>{const A=T.current;if(!A)return;const U=C.current.x*N.current.x,k=C.current.y*N.current.y;A.scrollBy(U,k)},[]),O=m.useMemo(()=>p===mu.TreeOrder?[...v].reverse():v,[p,v]);m.useEffect(()=>{if(!u||!v.length||!M){j();return}for(const A of O){if((s==null?void 0:s(A))===!1)continue;const U=v.indexOf(A),k=x[U];if(!k)continue;const{direction:$,speed:X}=a3(A,k,M,a,b);for(const te of["x","y"])w[te][$[te]]||(X[te]=0,$[te]=0);if(X.x>0||X.y>0){j(),T.current=A,E(D,f),C.current=X,N.current=$;return}}C.current={x:0,y:0},N.current={x:0,y:0},j()},[a,D,s,j,u,f,JSON.stringify(M),JSON.stringify(w),E,v,O,x,JSON.stringify(b)])}const v3={x:{[Wt.Backward]:!1,[Wt.Forward]:!1},y:{[Wt.Backward]:!1,[Wt.Forward]:!1}};function x3(n){let{delta:a,disabled:l}=n;const s=dm(a);return vi(c=>{if(l||!s||!c)return v3;const u={x:Math.sign(a.x-s.x),y:Math.sign(a.y-s.y)};return{x:{[Wt.Backward]:c.x[Wt.Backward]||u.x===-1,[Wt.Forward]:c.x[Wt.Forward]||u.x===1},y:{[Wt.Backward]:c.y[Wt.Backward]||u.y===-1,[Wt.Forward]:c.y[Wt.Forward]||u.y===1}}},[l,a,s])}function y3(n,a){const l=a!=null?n.get(a):void 0,s=l?l.node.current:null;return vi(c=>{var u;return a==null?null:(u=s??c)!=null?u:null},[s,a])}function b3(n,a){return m.useMemo(()=>n.reduce((l,s)=>{const{sensor:c}=s,u=c.activators.map(f=>({eventName:f.eventName,handler:a(f.handler,s)}));return[...l,...u]},[]),[n,a])}var ai;(function(n){n[n.Always=0]="Always",n[n.BeforeDragging=1]="BeforeDragging",n[n.WhileDragging=2]="WhileDragging"})(ai||(ai={}));var pm;(function(n){n.Optimized="optimized"})(pm||(pm={}));const Lb=new Map;function w3(n,a){let{dragging:l,dependencies:s,config:c}=a;const[u,f]=m.useState(null),{frequency:p,measure:g,strategy:v}=c,x=m.useRef(n),y=C(),b=ti(y),w=m.useCallback(function(N){N===void 0&&(N=[]),!b.current&&f(M=>M===null?N:M.concat(N.filter(T=>!M.includes(T))))},[b]),E=m.useRef(null),j=vi(N=>{if(y&&!l)return Lb;if(!N||N===Lb||x.current!==n||u!=null){const M=new Map;for(let T of n){if(!T)continue;if(u&&u.length>0&&!u.includes(T.id)&&T.rect.current){M.set(T.id,T.rect.current);continue}const D=T.node.current,O=D?new Tp(g(D),D):null;T.rect.current=O,O&&M.set(T.id,O)}return M}return N},[n,u,l,y,g]);return m.useEffect(()=>{x.current=n},[n]),m.useEffect(()=>{y||w()},[l,y]),m.useEffect(()=>{u&&u.length>0&&f(null)},[JSON.stringify(u)]),m.useEffect(()=>{y||typeof p!="number"||E.current!==null||(E.current=setTimeout(()=>{w(),E.current=null},p))},[p,y,w,...s]),{droppableRects:j,measureDroppableContainers:w,measuringScheduled:u!=null};function C(){switch(v){case ai.Always:return!1;case ai.BeforeDragging:return l;default:return!l}}}function gS(n,a){return vi(l=>n?l||(typeof a=="function"?a(n):n):null,[a,n])}function S3(n,a){return gS(n,a)}function j3(n){let{callback:a,disabled:l}=n;const s=Rp(a),c=m.useMemo(()=>{if(l||typeof window>"u"||typeof window.MutationObserver>"u")return;const{MutationObserver:u}=window;return new u(s)},[s,l]);return m.useEffect(()=>()=>c==null?void 0:c.disconnect(),[c]),c}function Qu(n){let{callback:a,disabled:l}=n;const s=Rp(a),c=m.useMemo(()=>{if(l||typeof window>"u"||typeof window.ResizeObserver>"u")return;const{ResizeObserver:u}=window;return new u(s)},[l]);return m.useEffect(()=>()=>c==null?void 0:c.disconnect(),[c]),c}function C3(n){return new Tp(Qs(n),n)}function Ub(n,a,l){a===void 0&&(a=C3);const[s,c]=m.useState(null);function u(){c(g=>{if(!n)return null;if(n.isConnected===!1){var v;return(v=g??l)!=null?v:null}const x=a(n);return JSON.stringify(g)===JSON.stringify(x)?g:x})}const f=j3({callback(g){if(n)for(const v of g){const{type:x,target:y}=v;if(x==="childList"&&y instanceof HTMLElement&&y.contains(n)){u();break}}}}),p=Qu({callback:u});return qa(()=>{u(),n?(p==null||p.observe(n),f==null||f.observe(document.body,{childList:!0,subtree:!0})):(p==null||p.disconnect(),f==null||f.disconnect())},[n]),s}function E3(n){const a=gS(n);return iS(n,a)}const Bb=[];function R3(n){const a=m.useRef(n),l=vi(s=>n?s&&s!==Bb&&n&&a.current&&n.parentNode===a.current.parentNode?s:Fu(n):Bb,[n]);return m.useEffect(()=>{a.current=n},[n]),l}function N3(n){const[a,l]=m.useState(null),s=m.useRef(n),c=m.useCallback(u=>{const f=kh(u.target);f&&l(p=>p?(p.set(f,hm(f)),new Map(p)):null)},[]);return m.useEffect(()=>{const u=s.current;if(n!==u){f(u);const p=n.map(g=>{const v=kh(g);return v?(v.addEventListener("scroll",c,{passive:!0}),[v,hm(v)]):null}).filter(g=>g!=null);l(p.length?new Map(p):null),s.current=n}return()=>{f(n),f(u)};function f(p){p.forEach(g=>{const v=kh(g);v==null||v.removeEventListener("scroll",c)})}},[c,n]),m.useMemo(()=>n.length?a?Array.from(a.values()).reduce((u,f)=>Us(u,f),Ea):mS(n):Ea,[n,a])}function Hb(n,a){a===void 0&&(a=[]);const l=m.useRef(null);return m.useEffect(()=>{l.current=null},a),m.useEffect(()=>{const s=n!==Ea;s&&!l.current&&(l.current=n),!s&&l.current&&(l.current=null)},[n]),l.current?ni(n,l.current):Ea}function T3(n){m.useEffect(()=>{if(!Xu)return;const a=n.map(l=>{let{sensor:s}=l;return s.setup==null?void 0:s.setup()});return()=>{for(const l of a)l==null||l()}},n.map(a=>{let{sensor:l}=a;return l}))}function M3(n,a){return m.useMemo(()=>n.reduce((l,s)=>{let{eventName:c,handler:u}=s;return l[c]=f=>{u(f,a)},l},{}),[n,a])}function vS(n){return m.useMemo(()=>n?W_(n):null,[n])}const Ib=[];function A3(n,a){a===void 0&&(a=Qs);const[l]=n,s=vS(l?zn(l):null),[c,u]=m.useState(Ib);function f(){u(()=>n.length?n.map(g=>fS(g)?s:new Tp(a(g),g)):Ib)}const p=Qu({callback:f});return qa(()=>{p==null||p.disconnect(),f(),n.forEach(g=>p==null?void 0:p.observe(g))},[n]),c}function D3(n){if(!n)return null;if(n.children.length>1)return n;const a=n.children[0];return gi(a)?a:n}function O3(n){let{measure:a}=n;const[l,s]=m.useState(null),c=m.useCallback(v=>{for(const{target:x}of v)if(gi(x)){s(y=>{const b=a(x);return y?{...y,width:b.width,height:b.height}:b});break}},[a]),u=Qu({callback:c}),f=m.useCallback(v=>{const x=D3(v);u==null||u.disconnect(),x&&(u==null||u.observe(x)),s(x?a(x):null)},[a,u]),[p,g]=du(f);return m.useMemo(()=>({nodeRef:p,rect:l,setRef:g}),[l,p,g])}const _3=[{sensor:Dp,options:{}},{sensor:Mp,options:{}}],k3={current:{}},eu={draggable:{measure:Ob},droppable:{measure:Ob,strategy:ai.WhileDragging,frequency:pm.Optimized},dragOverlay:{measure:Qs}};class Qo extends Map{get(a){var l;return a!=null&&(l=super.get(a))!=null?l:void 0}toArray(){return Array.from(this.values())}getEnabled(){return this.toArray().filter(a=>{let{disabled:l}=a;return!l})}getNodeFor(a){var l,s;return(l=(s=this.get(a))==null?void 0:s.node.current)!=null?l:void 0}}const z3={activatorEvent:null,active:null,activeNode:null,activeNodeRect:null,collisions:null,containerNodeRect:null,draggableNodes:new Map,droppableRects:new Map,droppableContainers:new Qo,over:null,dragOverlay:{nodeRef:{current:null},rect:null,setRef:hu},scrollableAncestors:[],scrollableAncestorRects:[],measuringConfiguration:eu,measureDroppableContainers:hu,windowRect:null,measuringScheduled:!1},L3={activatorEvent:null,activators:[],active:null,activeNodeRect:null,ariaDescribedById:{draggable:""},dispatch:hu,draggableNodes:new Map,over:null,measureDroppableContainers:hu},Zu=m.createContext(L3),xS=m.createContext(z3);function U3(){return{draggable:{active:null,initialCoordinates:{x:0,y:0},nodes:new Map,translate:{x:0,y:0}},droppable:{containers:new Qo}}}function B3(n,a){switch(a.type){case Gt.DragStart:return{...n,draggable:{...n.draggable,initialCoordinates:a.initialCoordinates,active:a.active}};case Gt.DragMove:return n.draggable.active==null?n:{...n,draggable:{...n.draggable,translate:{x:a.coordinates.x-n.draggable.initialCoordinates.x,y:a.coordinates.y-n.draggable.initialCoordinates.y}}};case Gt.DragEnd:case Gt.DragCancel:return{...n,draggable:{...n.draggable,active:null,initialCoordinates:{x:0,y:0},translate:{x:0,y:0}}};case Gt.RegisterDroppable:{const{element:l}=a,{id:s}=l,c=new Qo(n.droppable.containers);return c.set(s,l),{...n,droppable:{...n.droppable,containers:c}}}case Gt.SetDroppableDisabled:{const{id:l,key:s,disabled:c}=a,u=n.droppable.containers.get(l);if(!u||s!==u.key)return n;const f=new Qo(n.droppable.containers);return f.set(l,{...u,disabled:c}),{...n,droppable:{...n.droppable,containers:f}}}case Gt.UnregisterDroppable:{const{id:l,key:s}=a,c=n.droppable.containers.get(l);if(!c||s!==c.key)return n;const u=new Qo(n.droppable.containers);return u.delete(l),{...n,droppable:{...n.droppable,containers:u}}}default:return n}}function H3(n){let{disabled:a}=n;const{active:l,activatorEvent:s,draggableNodes:c}=m.useContext(Zu),u=dm(s),f=dm(l==null?void 0:l.id);return m.useEffect(()=>{if(!a&&!s&&u&&f!=null){if(!Np(u)||document.activeElement===u.target)return;const p=c.get(f);if(!p)return;const{activatorNode:g,node:v}=p;if(!g.current&&!v.current)return;requestAnimationFrame(()=>{for(const x of[g.current,v.current]){if(!x)continue;const y=D_(x);if(y){y.focus();break}}})}},[s,a,c,f,u]),null}function I3(n,a){let{transform:l,...s}=a;return n!=null&&n.length?n.reduce((c,u)=>u({transform:c,...s}),l):l}function P3(n){return m.useMemo(()=>({draggable:{...eu.draggable,...n==null?void 0:n.draggable},droppable:{...eu.droppable,...n==null?void 0:n.droppable},dragOverlay:{...eu.dragOverlay,...n==null?void 0:n.dragOverlay}}),[n==null?void 0:n.draggable,n==null?void 0:n.droppable,n==null?void 0:n.dragOverlay])}function q3(n){let{activeNode:a,measure:l,initialRect:s,config:c=!0}=n;const u=m.useRef(!1),{x:f,y:p}=typeof c=="boolean"?{x:c,y:c}:c;qa(()=>{if(!f&&!p||!a){u.current=!1;return}if(u.current||!s)return;const v=a==null?void 0:a.node.current;if(!v||v.isConnected===!1)return;const x=l(v),y=iS(x,s);if(f||(y.x=0),p||(y.y=0),u.current=!0,Math.abs(y.x)>0||Math.abs(y.y)>0){const b=cS(v);b&&b.scrollBy({top:y.y,left:y.x})}},[a,f,p,s,l])}const yS=m.createContext({...Ea,scaleX:1,scaleY:1});var al;(function(n){n[n.Uninitialized=0]="Uninitialized",n[n.Initializing=1]="Initializing",n[n.Initialized=2]="Initialized"})(al||(al={}));const V3=m.memo(function(a){var l,s,c,u;let{id:f,accessibility:p,autoScroll:g=!0,children:v,sensors:x=_3,collisionDetection:y=G_,measuring:b,modifiers:w,...E}=a;const j=m.useReducer(B3,void 0,U3),[C,N]=j,[M,T]=U_(),[D,O]=m.useState(al.Uninitialized),A=D===al.Initialized,{draggable:{active:U,nodes:k,translate:$},droppable:{containers:X}}=C,te=U!=null?k.get(U):null,G=m.useRef({initial:null,translated:null}),ie=m.useMemo(()=>{var vt;return U!=null?{id:U,data:(vt=te==null?void 0:te.data)!=null?vt:k3,rect:G}:null},[U,te]),ce=m.useRef(null),[se,_]=m.useState(null),[H,Q]=m.useState(null),J=ti(E,Object.values(E)),ee=xi("DndDescribedBy",f),z=m.useMemo(()=>X.getEnabled(),[X]),I=P3(b),{droppableRects:F,measureDroppableContainers:re,measuringScheduled:he}=w3(z,{dragging:A,dependencies:[$.x,$.y],config:I.droppable}),ge=y3(k,U),q=m.useMemo(()=>H?fm(H):null,[H]),oe=Nr(),de=S3(ge,I.draggable.measure);q3({activeNode:U!=null?k.get(U):null,config:oe.layoutShiftCompensation,initialRect:de,measure:I.draggable.measure});const fe=Ub(ge,I.draggable.measure,de),Te=Ub(ge?ge.parentElement:null),je=m.useRef({activatorEvent:null,active:null,activeNode:ge,collisionRect:null,collisions:null,droppableRects:F,draggableNodes:k,draggingNode:null,draggingNodeRect:null,droppableContainers:X,over:null,scrollableAncestors:[],scrollAdjustedTranslate:null}),De=X.getNodeFor((l=je.current.over)==null?void 0:l.id),Fe=O3({measure:I.dragOverlay.measure}),et=(s=Fe.nodeRef.current)!=null?s:ge,le=A?(c=Fe.rect)!=null?c:fe:null,Le=!!(Fe.nodeRef.current&&Fe.rect),Ie=E3(Le?null:fe),kt=vS(et?zn(et):null),St=R3(A?De??ge:null),Ft=A3(St),on=I3(w,{transform:{x:$.x-Ie.x,y:$.y-Ie.y,scaleX:1,scaleY:1},activatorEvent:H,active:ie,activeNodeRect:fe,containerNodeRect:Te,draggingNodeRect:le,over:je.current.over,overlayNodeRect:Fe.rect,scrollableAncestors:St,scrollableAncestorRects:Ft,windowRect:kt}),Qt=q?Us(q,$):null,jt=N3(St),fn=Hb(jt),Mt=Hb(jt,[fe]),At=Us(on,fn),cn=le?F_(le,on):null,fa=ie&&cn?y({active:ie,collisionRect:cn,droppableRects:F,droppableContainers:z,pointerCoordinates:Qt}):null,Ta=oS(fa,"id"),[Gn,dl]=m.useState(null),ha=Le?on:Us(on,Mt),Dt=K_(ha,(u=Gn==null?void 0:Gn.rect)!=null?u:null,fe),hn=m.useRef(null),Tt=m.useCallback((vt,st)=>{let{sensor:Bt,options:Ce}=st;if(ce.current==null)return;const ke=k.get(ce.current);if(!ke)return;const Ue=vt.nativeEvent,gt=new Bt({active:ce.current,activeNode:ke,event:Ue,options:Ce,context:je,onAbort(ct){if(!k.get(ct))return;const{onDragAbort:xt}=J.current,zt={id:ct};xt==null||xt(zt),M({type:"onDragAbort",event:zt})},onPending(ct,$t,xt,zt){if(!k.get(ct))return;const{onDragPending:Ka}=J.current,ma={id:ct,constraint:$t,initialCoordinates:xt,offset:zt};Ka==null||Ka(ma),M({type:"onDragPending",event:ma})},onStart(ct){const $t=ce.current;if($t==null)return;const xt=k.get($t);if(!xt)return;const{onDragStart:zt}=J.current,Ga={activatorEvent:Ue,active:{id:$t,data:xt.data,rect:G}};ba.unstable_batchedUpdates(()=>{zt==null||zt(Ga),O(al.Initializing),N({type:Gt.DragStart,initialCoordinates:ct,active:$t}),M({type:"onDragStart",event:Ga}),_(hn.current),Q(Ue)})},onMove(ct){N({type:Gt.DragMove,coordinates:ct})},onEnd:Ct(Gt.DragEnd),onCancel:Ct(Gt.DragCancel)});hn.current=gt;function Ct(ct){return async function(){const{active:xt,collisions:zt,over:Ga,scrollAdjustedTranslate:Ka}=je.current;let ma=null;if(xt&&Ka){const{cancelDrop:Tr}=J.current;ma={activatorEvent:Ue,active:xt,collisions:zt,delta:Ka,over:Ga},ct===Gt.DragEnd&&typeof Tr=="function"&&await Promise.resolve(Tr(ma))&&(ct=Gt.DragCancel)}ce.current=null,ba.unstable_batchedUpdates(()=>{N({type:ct}),O(al.Uninitialized),dl(null),_(null),Q(null),hn.current=null;const Tr=ct===Gt.DragEnd?"onDragEnd":"onDragCancel";if(ma){const Kn=J.current[Tr];Kn==null||Kn(ma),M({type:Tr,event:ma})}})}}},[k]),Js=m.useCallback((vt,st)=>(Bt,Ce)=>{const ke=Bt.nativeEvent,Ue=k.get(Ce);if(ce.current!==null||!Ue||ke.dndKit||ke.defaultPrevented)return;const gt={active:Ue};vt(Bt,st.options,gt)===!0&&(ke.dndKit={capturedBy:st.sensor},ce.current=Ce,Tt(Bt,st))},[k,Tt]),Pl=b3(x,Js);T3(x),qa(()=>{fe&&D===al.Initializing&&O(al.Initialized)},[fe,D]),m.useEffect(()=>{const{onDragMove:vt}=J.current,{active:st,activatorEvent:Bt,collisions:Ce,over:ke}=je.current;if(!st||!Bt)return;const Ue={active:st,activatorEvent:Bt,collisions:Ce,delta:{x:At.x,y:At.y},over:ke};ba.unstable_batchedUpdates(()=>{vt==null||vt(Ue),M({type:"onDragMove",event:Ue})})},[At.x,At.y]),m.useEffect(()=>{const{active:vt,activatorEvent:st,collisions:Bt,droppableContainers:Ce,scrollAdjustedTranslate:ke}=je.current;if(!vt||ce.current==null||!st||!ke)return;const{onDragOver:Ue}=J.current,gt=Ce.get(Ta),Ct=gt&>.rect.current?{id:gt.id,rect:gt.rect.current,data:gt.data,disabled:gt.disabled}:null,ct={active:vt,activatorEvent:st,collisions:Bt,delta:{x:ke.x,y:ke.y},over:Ct};ba.unstable_batchedUpdates(()=>{dl(Ct),Ue==null||Ue(ct),M({type:"onDragOver",event:ct})})},[Ta]),qa(()=>{je.current={activatorEvent:H,active:ie,activeNode:ge,collisionRect:cn,collisions:fa,droppableRects:F,draggableNodes:k,draggingNode:et,draggingNodeRect:le,droppableContainers:X,over:Gn,scrollableAncestors:St,scrollAdjustedTranslate:At},G.current={initial:le,translated:cn}},[ie,ge,fa,cn,k,et,le,F,X,Gn,St,At]),g3({...oe,delta:$,draggingRect:cn,pointerCoordinates:Qt,scrollableAncestors:St,scrollableAncestorRects:Ft});const ql=m.useMemo(()=>({active:ie,activeNode:ge,activeNodeRect:fe,activatorEvent:H,collisions:fa,containerNodeRect:Te,dragOverlay:Fe,draggableNodes:k,droppableContainers:X,droppableRects:F,over:Gn,measureDroppableContainers:re,scrollableAncestors:St,scrollableAncestorRects:Ft,measuringConfiguration:I,measuringScheduled:he,windowRect:kt}),[ie,ge,fe,H,fa,Te,Fe,k,X,F,Gn,re,St,Ft,I,he,kt]),Ya=m.useMemo(()=>({activatorEvent:H,activators:Pl,active:ie,activeNodeRect:fe,ariaDescribedById:{draggable:ee},dispatch:N,draggableNodes:k,over:Gn,measureDroppableContainers:re}),[H,Pl,ie,fe,N,ee,k,Gn,re]);return ue.createElement(rS.Provider,{value:T},ue.createElement(Zu.Provider,{value:Ya},ue.createElement(xS.Provider,{value:ql},ue.createElement(yS.Provider,{value:Dt},v)),ue.createElement(H3,{disabled:(p==null?void 0:p.restoreFocus)===!1})),ue.createElement(I_,{...p,hiddenTextDescribedById:ee}));function Nr(){const vt=(se==null?void 0:se.autoScrollEnabled)===!1,st=typeof g=="object"?g.enabled===!1:g===!1,Bt=A&&!vt&&!st;return typeof g=="object"?{...g,enabled:Bt}:{enabled:Bt}}}),$3=m.createContext(null),Pb="button",Y3="Draggable";function G3(n){let{id:a,data:l,disabled:s=!1,attributes:c}=n;const u=xi(Y3),{activators:f,activatorEvent:p,active:g,activeNodeRect:v,ariaDescribedById:x,draggableNodes:y,over:b}=m.useContext(Zu),{role:w=Pb,roleDescription:E="draggable",tabIndex:j=0}=c??{},C=(g==null?void 0:g.id)===a,N=m.useContext(C?yS:$3),[M,T]=du(),[D,O]=du(),A=M3(f,a),U=ti(l);qa(()=>(y.set(a,{id:a,key:u,node:M,activatorNode:D,data:U}),()=>{const $=y.get(a);$&&$.key===u&&y.delete(a)}),[y,a]);const k=m.useMemo(()=>({role:w,tabIndex:j,"aria-disabled":s,"aria-pressed":C&&w===Pb?!0:void 0,"aria-roledescription":E,"aria-describedby":x.draggable}),[s,w,j,C,E,x.draggable]);return{active:g,activatorEvent:p,activeNodeRect:v,attributes:k,isDragging:C,listeners:s?void 0:A,node:M,over:b,setNodeRef:T,setActivatorNodeRef:O,transform:N}}function K3(){return m.useContext(xS)}const X3="Droppable",F3={timeout:25};function Q3(n){let{data:a,disabled:l=!1,id:s,resizeObserverConfig:c}=n;const u=xi(X3),{active:f,dispatch:p,over:g,measureDroppableContainers:v}=m.useContext(Zu),x=m.useRef({disabled:l}),y=m.useRef(!1),b=m.useRef(null),w=m.useRef(null),{disabled:E,updateMeasurementsFor:j,timeout:C}={...F3,...c},N=ti(j??s),M=m.useCallback(()=>{if(!y.current){y.current=!0;return}w.current!=null&&clearTimeout(w.current),w.current=setTimeout(()=>{v(Array.isArray(N.current)?N.current:[N.current]),w.current=null},C)},[C]),T=Qu({callback:M,disabled:E||!f}),D=m.useCallback((k,$)=>{T&&($&&(T.unobserve($),y.current=!1),k&&T.observe(k))},[T]),[O,A]=du(D),U=ti(a);return m.useEffect(()=>{!T||!O.current||(T.disconnect(),y.current=!1,T.observe(O.current))},[O,T]),m.useEffect(()=>(p({type:Gt.RegisterDroppable,element:{id:s,key:u,disabled:l,node:O,rect:b,data:U}}),()=>p({type:Gt.UnregisterDroppable,key:u,id:s})),[s]),m.useEffect(()=>{l!==x.current.disabled&&(p({type:Gt.SetDroppableDisabled,id:s,key:u,disabled:l}),x.current.disabled=l)},[s,u,l,p]),{active:f,rect:b,isOver:(g==null?void 0:g.id)===s,node:O,over:g,setNodeRef:A}}function Z3(n,a,l){const s={...n};return a.top+n.y<=l.top?s.y=l.top-a.top:a.bottom+n.y>=l.top+l.height&&(s.y=l.top+l.height-a.bottom),a.left+n.x<=l.left?s.x=l.left-a.left:a.right+n.x>=l.left+l.width&&(s.x=l.left+l.width-a.right),s}const J3=n=>{let{containerNodeRect:a,draggingNodeRect:l,transform:s}=n;return!l||!a?s:Z3(s,l,a)},W3=n=>{let{transform:a}=n;return{...a,x:0}};function Op(n,a,l){const s=n.slice();return s.splice(l<0?s.length+l:l,0,s.splice(a,1)[0]),s}function ek(n,a){return n.reduce((l,s,c)=>{const u=a.get(s);return u&&(l[c]=u),l},Array(n.length))}function Pc(n){return n!==null&&n>=0}function tk(n,a){if(n===a)return!0;if(n.length!==a.length)return!1;for(let l=0;l<n.length;l++)if(n[l]!==a[l])return!1;return!0}function nk(n){return typeof n=="boolean"?{draggable:n,droppable:n}:n}const bS=n=>{let{rects:a,activeIndex:l,overIndex:s,index:c}=n;const u=Op(a,s,l),f=a[c],p=u[c];return!p||!f?null:{x:p.left-f.left,y:p.top-f.top,scaleX:p.width/f.width,scaleY:p.height/f.height}},qc={scaleX:1,scaleY:1},ak=n=>{var a;let{activeIndex:l,activeNodeRect:s,index:c,rects:u,overIndex:f}=n;const p=(a=u[l])!=null?a:s;if(!p)return null;if(c===l){const v=u[f];return v?{x:0,y:l<f?v.top+v.height-(p.top+p.height):v.top-p.top,...qc}:null}const g=rk(u,c,l);return c>l&&c<=f?{x:0,y:-p.height-g,...qc}:c<l&&c>=f?{x:0,y:p.height+g,...qc}:{x:0,y:0,...qc}};function rk(n,a,l){const s=n[a],c=n[a-1],u=n[a+1];return s?l<a?c?s.top-(c.top+c.height):u?u.top-(s.top+s.height):0:u?u.top-(s.top+s.height):c?s.top-(c.top+c.height):0:0}const wS="Sortable",SS=ue.createContext({activeIndex:-1,containerId:wS,disableTransforms:!1,items:[],overIndex:-1,useDragOverlay:!1,sortedRects:[],strategy:bS,disabled:{draggable:!1,droppable:!1}});function lk(n){let{children:a,id:l,items:s,strategy:c=bS,disabled:u=!1}=n;const{active:f,dragOverlay:p,droppableRects:g,over:v,measureDroppableContainers:x}=K3(),y=xi(wS,l),b=p.rect!==null,w=m.useMemo(()=>s.map(A=>typeof A=="object"&&"id"in A?A.id:A),[s]),E=f!=null,j=f?w.indexOf(f.id):-1,C=v?w.indexOf(v.id):-1,N=m.useRef(w),M=!tk(w,N.current),T=C!==-1&&j===-1||M,D=nk(u);qa(()=>{M&&E&&x(w)},[M,w,E,x]),m.useEffect(()=>{N.current=w},[w]);const O=m.useMemo(()=>({activeIndex:j,containerId:y,disabled:D,disableTransforms:T,items:w,overIndex:C,useDragOverlay:b,sortedRects:ek(w,g),strategy:c}),[j,y,D.draggable,D.droppable,T,w,C,g,b,c]);return ue.createElement(SS.Provider,{value:O},a)}const sk=n=>{let{id:a,items:l,activeIndex:s,overIndex:c}=n;return Op(l,s,c).indexOf(a)},ok=n=>{let{containerId:a,isSorting:l,wasDragging:s,index:c,items:u,newIndex:f,previousItems:p,previousContainerId:g,transition:v}=n;return!v||!s||p!==u&&c===f?!1:l?!0:f!==c&&a===g},ik={duration:200,easing:"ease"},jS="transform",ck=fu.Transition.toString({property:jS,duration:0,easing:"linear"}),uk={roleDescription:"sortable"};function dk(n){let{disabled:a,index:l,node:s,rect:c}=n;const[u,f]=m.useState(null),p=m.useRef(l);return qa(()=>{if(!a&&l!==p.current&&s.current){const g=c.current;if(g){const v=Qs(s.current,{ignoreTransform:!0}),x={x:g.left-v.left,y:g.top-v.top,scaleX:g.width/v.width,scaleY:g.height/v.height};(x.x||x.y)&&f(x)}}l!==p.current&&(p.current=l)},[a,l,s,c]),m.useEffect(()=>{u&&f(null)},[u]),u}function fk(n){let{animateLayoutChanges:a=ok,attributes:l,disabled:s,data:c,getNewIndex:u=sk,id:f,strategy:p,resizeObserverConfig:g,transition:v=ik}=n;const{items:x,containerId:y,activeIndex:b,disabled:w,disableTransforms:E,sortedRects:j,overIndex:C,useDragOverlay:N,strategy:M}=m.useContext(SS),T=hk(s,w),D=x.indexOf(f),O=m.useMemo(()=>({sortable:{containerId:y,index:D,items:x},...c}),[y,c,D,x]),A=m.useMemo(()=>x.slice(x.indexOf(f)),[x,f]),{rect:U,node:k,isOver:$,setNodeRef:X}=Q3({id:f,data:O,disabled:T.droppable,resizeObserverConfig:{updateMeasurementsFor:A,...g}}),{active:te,activatorEvent:G,activeNodeRect:ie,attributes:ce,setNodeRef:se,listeners:_,isDragging:H,over:Q,setActivatorNodeRef:J,transform:ee}=G3({id:f,data:O,attributes:{...uk,...l},disabled:T.draggable}),z=N_(X,se),I=!!te,F=I&&!E&&Pc(b)&&Pc(C),re=!N&&H,he=re&&F?ee:null,q=F?he??(p??M)({rects:j,activeNodeRect:ie,activeIndex:b,overIndex:C,index:D}):null,oe=Pc(b)&&Pc(C)?u({id:f,items:x,activeIndex:b,overIndex:C}):D,de=te==null?void 0:te.id,fe=m.useRef({activeId:de,items:x,newIndex:oe,containerId:y}),Te=x!==fe.current.items,je=a({active:te,containerId:y,isDragging:H,isSorting:I,id:f,index:D,items:x,newIndex:fe.current.newIndex,previousItems:fe.current.items,previousContainerId:fe.current.containerId,transition:v,wasDragging:fe.current.activeId!=null}),De=dk({disabled:!je,index:D,node:k,rect:U});return m.useEffect(()=>{I&&fe.current.newIndex!==oe&&(fe.current.newIndex=oe),y!==fe.current.containerId&&(fe.current.containerId=y),x!==fe.current.items&&(fe.current.items=x)},[I,oe,y,x]),m.useEffect(()=>{if(de===fe.current.activeId)return;if(de!=null&&fe.current.activeId==null){fe.current.activeId=de;return}const et=setTimeout(()=>{fe.current.activeId=de},50);return()=>clearTimeout(et)},[de]),{active:te,activeIndex:b,attributes:ce,data:O,rect:U,index:D,newIndex:oe,items:x,isOver:$,isSorting:I,isDragging:H,listeners:_,node:k,overIndex:C,over:Q,setNodeRef:z,setActivatorNodeRef:J,setDroppableNodeRef:X,setDraggableNodeRef:se,transform:De??q,transition:Fe()};function Fe(){if(De||Te&&fe.current.newIndex===D)return ck;if(!(re&&!Np(G)||!v)&&(I||je))return fu.Transition.toString({...v,property:jS})}}function hk(n,a){var l,s;return typeof n=="boolean"?{draggable:n,droppable:!1}:{draggable:(l=n==null?void 0:n.draggable)!=null?l:a.draggable,droppable:(s=n==null?void 0:n.droppable)!=null?s:a.droppable}}function pu(n){if(!n)return!1;const a=n.data.current;return!!(a&&"sortable"in a&&typeof a.sortable=="object"&&"containerId"in a.sortable&&"items"in a.sortable&&"index"in a.sortable)}const mk=[Ke.Down,Ke.Right,Ke.Up,Ke.Left],pk=(n,a)=>{let{context:{active:l,collisionRect:s,droppableRects:c,droppableContainers:u,over:f,scrollableAncestors:p}}=a;if(mk.includes(n.code)){if(n.preventDefault(),!l||!s)return;const g=[];u.getEnabled().forEach(y=>{if(!y||y!=null&&y.disabled)return;const b=c.get(y.id);if(b)switch(n.code){case Ke.Down:s.top<b.top&&g.push(y);break;case Ke.Up:s.top>b.top&&g.push(y);break;case Ke.Left:s.left>b.left&&g.push(y);break;case Ke.Right:s.left<b.left&&g.push(y);break}});const v=$_({collisionRect:s,droppableRects:c,droppableContainers:g});let x=oS(v,"id");if(x===(f==null?void 0:f.id)&&v.length>1&&(x=v[1].id),x!=null){const y=u.get(l.id),b=u.get(x),w=b?c.get(b.id):null,E=b==null?void 0:b.node.current;if(E&&w&&y&&b){const C=Fu(E).some((A,U)=>p[U]!==A),N=CS(y,b),M=gk(y,b),T=C||!N?{x:0,y:0}:{x:M?s.width-w.width:0,y:M?s.height-w.height:0},D={x:w.left,y:w.top};return T.x&&T.y?D:ni(D,T)}}}};function CS(n,a){return!pu(n)||!pu(a)?!1:n.data.current.sortable.containerId===a.data.current.sortable.containerId}function gk(n,a){return!pu(n)||!pu(a)||!CS(n,a)?!1:n.data.current.sortable.index<a.data.current.sortable.index}const Uh={maxTotalAttempts:3,fallbackOnConnection:!0,fallbackOnConnectTimeout:!0,fallbackOnFirstTokenTimeout:!0,fallbackOn408:!0,fallbackOn429:!0,fallbackOn5xx:!0},vk={member_disabled:"member disabled",model_missing:"model missing",provider_disabled:"provider disabled",provider_down:"provider down",model_disabled:"model disabled",upstream_unavailable:"upstream unavailable",circuit_open:"circuit open",chat_capability_unavailable:"chat capability unavailable"},gu=n=>n.map((a,l)=>({...a,position:l}));function xk(){const[n,a]=m.useState([]),[l,s]=m.useState([]),[c,u]=m.useState(!1),[f,p]=m.useState(!1),[g,v]=m.useState(null),[x,y]=m.useState(!1),[b,w]=m.useState(!1),[E,j]=m.useState(null),[C,N]=m.useState(null),[M,T]=m.useState({name:"",slug:"",enabled:!0,...Uh,members:[]}),[D,O]=m.useState({name:"",slug:"",enabled:!0,...Uh,members:[]}),[A,U]=m.useState(null),k=async()=>{const[_,H]=await Promise.all([Se.get("/api/admin/combos"),Se.get("/api/admin/models")]);a(_.combos),s(H.models)};m.useEffect(()=>{k()},[]);const $=async _=>{j(_.id);try{N(await Se.post("/api/admin/combos/"+_.id+"/test"))}catch(H){ve.error(H.message)}finally{j(null)}},X=async()=>{if(M.members.length===0){ve.error("Add at least one member");return}y(!0);try{await Se.post("/api/admin/combos",{name:M.name,slug:M.slug||void 0,enabled:M.enabled,...M,members:M.members}),ve.success("Combo created"),u(!1),T({name:"",slug:"",enabled:!0,...Uh,members:[]}),k()}catch(_){ve.error(_.message)}finally{y(!1)}},te=async _=>{try{const Q=(await Se.get(`/api/admin/combos/${_.id}`)).combo;v(Q.id),O({name:Q.name,slug:Q.publicModelId.startsWith("combo/")?Q.slug:"",enabled:Q.enabled,maxTotalAttempts:Q.maxTotalAttempts,fallbackOnConnection:Q.fallbackOnConnection,fallbackOnConnectTimeout:Q.fallbackOnConnectTimeout,fallbackOnFirstTokenTimeout:Q.fallbackOnFirstTokenTimeout,fallbackOn408:Q.fallbackOn408,fallbackOn429:Q.fallbackOn429,fallbackOn5xx:Q.fallbackOn5xx,members:Q.members.map(J=>({modelId:J.modelId,position:J.position,enabled:J.enabled}))}),p(!0)}catch(H){ve.error(H.message)}},G=async()=>{if(g){if(D.members.length===0){ve.error("Add at least one member");return}w(!0);try{await Se.patch("/api/admin/combos",{id:g,name:D.name,slug:D.slug||void 0,enabled:D.enabled,...D,members:D.members}),ve.success("Combo updated"),p(!1),v(null),k()}catch(_){ve.error(_.message)}finally{w(!1)}}},ie=_=>{T(H=>({...H,members:gu([...H.members,{modelId:_,position:H.members.length,enabled:!0}])}))},ce=_=>{O(H=>({...H,members:gu([...H.members,{modelId:_,position:H.members.length,enabled:!0}])}))},se=async _=>{try{await Se.del(`/api/admin/combos/${_}`),ve.success("Combo removed"),U(null),k()}catch(H){ve.error(H.message)}};return o.jsxs("div",{children:[o.jsx($a,{title:"Combos",description:"Virtual models combining physical models",actions:o.jsxs(Mn,{open:c,onOpenChange:u,children:[o.jsx(mi,{asChild:!0,children:o.jsxs(me,{children:[o.jsx(Su,{className:"mr-1 h-4 w-4"})," New combo"]})}),o.jsxs(vn,{className:"max-h-[calc(100vh-2rem)] max-w-2xl grid-rows-[auto_minmax(0,1fr)_auto] overflow-hidden",children:[o.jsx(xn,{children:o.jsx(yn,{children:"New combo"})}),o.jsxs("div",{className:"min-h-0 space-y-3 overflow-y-auto pr-1",children:[o.jsxs("div",{children:[o.jsx(we,{children:"Name"}),o.jsx(Ae,{value:M.name,onChange:_=>T({...M,name:_.target.value})})]}),o.jsxs("div",{children:[o.jsx(we,{children:"Slug (optional — empty uses the name as the model ID)"}),o.jsx(Ae,{value:M.slug,onChange:_=>T({...M,slug:_.target.value}),placeholder:"empty → gpt-5.5 · set → combo/gpt-5.5"})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ca,{checked:M.enabled,onCheckedChange:_=>T({...M,enabled:_})}),o.jsx(we,{children:"Enabled"})]}),o.jsx(qb,{value:M,onChange:_=>T(H=>({...H,..._}))}),o.jsxs("div",{children:[o.jsx(we,{children:"Members — priority order · drag to reorder"}),o.jsx(Yb,{models:l,addedIds:M.members.map(_=>_.modelId),onAdd:ie}),o.jsx(Vb,{members:M.members,modelFor:_=>l.find(H=>H.id===_.modelId)??null}),o.jsx($b,{className:"mt-2",members:M.members,label:_=>{var H;return((H=l.find(Q=>Q.id===_.modelId))==null?void 0:H.publicModelId)??_.modelId},modelFor:_=>l.find(H=>H.id===_.modelId)??null,onChange:_=>T(H=>({...H,members:_}))})]})]}),o.jsxs(An,{children:[o.jsx(me,{variant:"outline",onClick:()=>u(!1),children:"Cancel"}),o.jsx(me,{disabled:!M.name||x,onClick:X,children:x?"Creating…":"Create"})]})]})]})}),o.jsxs(nt,{children:[o.jsxs(at,{children:[o.jsx(rt,{className:"text-base",children:"All combos"}),o.jsxs(gn,{children:[n.length," total"]})]}),o.jsx(lt,{children:o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Public ID"}),o.jsx(ye,{children:"Members"}),o.jsx(ye,{children:"Status"}),o.jsx(ye,{children:"Enabled"}),o.jsx(ye,{})]})}),o.jsxs(da,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:5,className:"text-center text-muted-foreground",children:"No combos yet."})}),n.map(_=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:_.publicModelId}),o.jsx(pe,{children:_.memberCount}),o.jsxs(pe,{children:[o.jsxs(Qe,{variant:_.status==="ready"?"success":_.status==="disabled"?"secondary":"destructive",children:[_.healthyMemberCount,"/",_.memberCount," ready"]}),_.capabilityWarnings.length>0&&o.jsx("div",{className:"text-xs text-amber-600",children:"Capability metadata differs"}),_.status==="unavailable"&&_.unavailableReasons.length>0&&o.jsx("div",{className:"text-xs text-muted-foreground",children:_.unavailableReasons.map(H=>vk[H]??H).join(", ")})]}),o.jsx(pe,{children:_.enabled?"Yes":"No"}),o.jsx(pe,{className:"text-right",children:o.jsxs("div",{className:"flex items-center justify-end gap-1",children:[o.jsxs(me,{size:"sm",variant:"outline",title:"Sends a real non-streaming inference request",onClick:()=>void $(_),disabled:E===_.id,children:[E===_.id?o.jsx(_s,{className:"mr-1 h-3.5 w-3.5 animate-spin"}):o.jsx(A0,{className:"mr-1 h-3.5 w-3.5"})," Test"]}),o.jsxs(me,{size:"sm",variant:"outline",onClick:()=>void te(_),children:[o.jsx(xR,{className:"h-3.5 w-3.5"})," Sửa"]}),o.jsxs(me,{size:"sm",variant:"destructive",onClick:()=>U(_),children:[o.jsx(ju,{className:"h-3.5 w-3.5"})," Delete"]})]})})]},_.id))]})]})})]}),o.jsx(Mn,{open:f,onOpenChange:p,children:o.jsxs(vn,{className:"max-h-[calc(100vh-2rem)] max-w-2xl grid-rows-[auto_minmax(0,1fr)_auto] overflow-hidden",children:[o.jsx(xn,{children:o.jsx(yn,{children:"Edit combo"})}),o.jsxs("div",{className:"min-h-0 space-y-3 overflow-y-auto pr-1",children:[o.jsxs("div",{children:[o.jsx(we,{children:"Name"}),o.jsx(Ae,{value:D.name,onChange:_=>O({...D,name:_.target.value})})]}),o.jsxs("div",{children:[o.jsx(we,{children:"Slug (optional — leave empty to use the name as the model ID)"}),o.jsx(Ae,{value:D.slug,onChange:_=>O({...D,slug:_.target.value}),placeholder:"empty → gpt-5.5 · set → combo/gpt-5.5"})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ca,{checked:D.enabled,onCheckedChange:_=>O({...D,enabled:_})}),o.jsx(we,{children:"Enabled"})]}),o.jsx(qb,{value:D,onChange:_=>O(H=>({...H,..._}))}),o.jsxs("div",{children:[o.jsx(we,{children:"Members — priority order · drag to reorder"}),o.jsx(Yb,{models:l,addedIds:D.members.map(_=>_.modelId),onAdd:ce}),o.jsx(Vb,{members:D.members,modelFor:_=>l.find(H=>H.id===_.modelId)??null}),o.jsx($b,{className:"mt-2",members:D.members,label:_=>{var H;return((H=l.find(Q=>Q.id===_.modelId))==null?void 0:H.publicModelId)??_.modelId},modelFor:_=>l.find(H=>H.id===_.modelId)??null,onChange:_=>O(H=>({...H,members:_}))})]})]}),o.jsxs(An,{children:[o.jsx(me,{variant:"outline",onClick:()=>p(!1),children:"Cancel"}),o.jsx(me,{disabled:!D.name||b,onClick:G,children:b?"Saving…":"Save"})]})]})}),o.jsx(Mn,{open:C!==null,onOpenChange:_=>{_||N(null)},children:o.jsxs(vn,{className:"max-w-2xl",children:[o.jsxs(xn,{children:[o.jsx(yn,{children:"Combo test result"}),o.jsx("p",{className:"text-sm text-muted-foreground",children:"Test sends a real non-streaming inference request through this combo."})]}),C&&o.jsx(yk,{result:C}),o.jsx(An,{children:o.jsx(me,{onClick:()=>N(null),children:"Close"})})]})}),o.jsx(up,{open:A!==null,onOpenChange:_=>{_||U(null)},children:o.jsxs(Pu,{children:[o.jsxs(dp,{children:[o.jsx(qu,{children:"Delete combo?"}),o.jsx(Vu,{children:"This removes the virtual model and its ordered fallback configuration. Request history is preserved."})]}),o.jsxs(fp,{children:[o.jsx(Yu,{children:"Cancel"}),o.jsx($u,{onClick:()=>A&&void se(A.id),children:"Delete"})]})]})})]})}function qb({value:n,onChange:a}){const l=[["fallbackOnConnection","Connection failure"],["fallbackOnConnectTimeout","Connect timeout"],["fallbackOnFirstTokenTimeout","First-token timeout"],["fallbackOn408","HTTP 408"],["fallbackOn429","HTTP 429"],["fallbackOn5xx","HTTP 5xx"]];return o.jsxs("div",{className:"rounded border bg-muted/20 p-3",children:[o.jsx("div",{className:"mb-2 text-sm font-medium",children:"Fallback policy"}),o.jsxs("div",{className:"grid gap-3 sm:grid-cols-[10rem_1fr]",children:[o.jsxs("div",{children:[o.jsx(we,{children:"Max total attempts"}),o.jsx(Ae,{type:"number",min:1,max:8,value:n.maxTotalAttempts,onChange:s=>a({maxTotalAttempts:Math.min(8,Math.max(1,Number(s.target.value)||1))})})]}),o.jsx("div",{className:"grid gap-2 sm:grid-cols-2",children:l.map(([s,c])=>o.jsxs("label",{className:"flex items-center gap-2 text-xs",children:[o.jsx(Ca,{checked:!!n[s],onCheckedChange:u=>a({[s]:u})}),o.jsx("span",{children:c})]},s))})]})]})}function Vb({members:n,modelFor:a}){if(n.length===0)return null;const l=n.map(a).filter(c=>!!c),s=["chat","streaming","tools","structured_output","image_input","reasoning"].filter(c=>new Set(l.map(u=>u.capabilities[c]===!0?"yes":u.capabilities[c]===!1?"no":"unknown")).size>1);return o.jsxs("div",{className:"rounded border bg-muted/20 p-2 text-xs",children:[o.jsxs("div",{className:"mb-1 font-medium",children:["Route preview ",o.jsx("span",{className:"font-normal text-muted-foreground",children:"(first available member wins)"})]}),s.length>0&&o.jsxs("div",{className:"mb-2 flex items-center gap-1 text-amber-600",children:[o.jsx(O0,{className:"h-3.5 w-3.5"})," Members differ on: ",s.join(", ")]}),o.jsx("div",{className:"space-y-1",children:n.map((c,u)=>{const f=a(c);return o.jsxs("div",{className:"flex items-center gap-2 font-mono",children:[o.jsxs("span",{className:"w-4 text-muted-foreground",children:[u+1,"."]}),o.jsx("span",{children:(f==null?void 0:f.publicModelId)??c.modelId}),o.jsxs("span",{className:"text-muted-foreground",children:["→ ",(f==null?void 0:f.upstreamModelId)??"upstream model unknown"]})]},c.id??c.modelId)})})]})}function yk({result:n}){return o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{className:"flex items-center justify-between rounded border p-3",children:[o.jsxs("div",{className:"flex items-center gap-2",children:[n.success?o.jsx(ci,{className:"h-4 w-4 text-emerald-600"}):o.jsx(O0,{className:"h-4 w-4 text-amber-600"}),o.jsx(Qe,{variant:n.success?"success":"warning",children:n.success?"Success":"Failed"})]}),o.jsxs("span",{className:"text-xs text-muted-foreground",children:[n.latencyMs," ms total"]})]}),o.jsxs("div",{children:[o.jsx("div",{className:"mb-1 text-sm font-medium",children:"Selected upstream"}),n.selectedModel?o.jsxs("div",{className:"rounded border bg-muted/20 p-2 font-mono text-xs",children:[n.selectedModel.publicModelId," → ",n.selectedModel.upstreamModelId,o.jsxs("span",{className:"ml-2 text-muted-foreground",children:["(",n.selectedModel.providerSlug,")"]})]}):o.jsx("p",{className:"text-sm text-muted-foreground",children:"No member completed successfully."})]}),o.jsxs("div",{children:[o.jsx("div",{className:"mb-1 text-sm font-medium",children:"Attempts"}),o.jsx("div",{className:"space-y-1",children:n.attempts.map((a,l)=>o.jsxs("div",{className:"flex items-center gap-2 rounded border p-2 text-xs",children:[o.jsxs("span",{className:"w-4 text-muted-foreground",children:[l+1,"."]}),o.jsxs("span",{className:"min-w-0 flex-1 font-mono",children:[a.publicModelId," → ",a.upstreamModelId]}),o.jsxs("span",{className:"text-muted-foreground",children:[a.latencyMs," ms"]}),o.jsx(Qe,{variant:a.success?"success":"warning",children:a.success?"Used":a.failureReason??"Skipped"})]},a.publicModelId+"-"+l))})]}),n.text&&o.jsx("pre",{className:"max-h-32 overflow-auto whitespace-pre-wrap rounded border bg-muted/20 p-2 text-xs",children:n.text})]})}function $b({members:n,label:a,modelFor:l,onChange:s,className:c}){const u=P_(Mb(Dp,{activationConstraint:{distance:4}}),Mb(Mp,{coordinateGetter:pk}));if(n.length===0)return o.jsx("p",{className:Ee("text-xs text-muted-foreground",c),children:"No members yet — add at least one."});const f=({active:p,over:g})=>{!g||p.id===g.id||s(gu(Op(n,Number(p.id),Number(g.id))))};return o.jsx(V3,{sensors:u,collisionDetection:V_,modifiers:[W3,J3],onDragEnd:f,children:o.jsx(lk,{items:n.map((p,g)=>g),strategy:ak,children:o.jsx("div",{className:Ee("space-y-1",c),children:n.map((p,g)=>o.jsx(bk,{index:g,label:a(p),model:l(p),onRemove:()=>s(gu(n.filter((v,x)=>x!==g)))},p.id??p.modelId))})})})}function bk({index:n,label:a,model:l,onRemove:s}){const{attributes:c,listeners:u,setNodeRef:f,transform:p,transition:g,isDragging:v}=fk({id:n});return o.jsxs("div",{ref:f,style:{transform:p?`translate3d(${p.x}px, ${p.y}px, 0)`:void 0,transition:g},className:Ee("flex items-center gap-2 rounded border p-2 text-sm",v&&"relative z-10 bg-muted/60 shadow-sm"),children:[o.jsx("button",{type:"button",...c,...u,"aria-label":`Reorder ${a}`,title:"Drag to change priority",className:"cursor-grab touch-none rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground active:cursor-grabbing",children:o.jsx(cR,{className:"h-4 w-4"})}),o.jsx("span",{className:"w-5 text-xs tabular-nums text-muted-foreground",children:n+1}),o.jsxs("div",{className:"min-w-0 flex-1",children:[o.jsx("div",{className:"truncate font-mono text-xs",children:a}),o.jsxs("div",{className:"truncate text-[11px] text-muted-foreground",children:[(l==null?void 0:l.providerSlug)||"provider"," · upstream: ",(l==null?void 0:l.upstreamModelId)??"unknown"]})]}),o.jsx(Qe,{variant:l&&l.enabled&&l.providerEnabled&&l.providerHealth!=="down"&&l.providerHealth!=="circuit_open"&&!l.circuitOpen&&l.upstreamAvailable&&l.capabilities.chat!==!1?"success":"warning",children:l&&l.enabled&&l.providerEnabled&&l.providerHealth!=="down"&&l.providerHealth!=="circuit_open"&&!l.circuitOpen&&l.upstreamAvailable&&l.capabilities.chat!==!1?"Ready":"Unavailable"}),o.jsx(me,{size:"sm",variant:"outline",onClick:s,children:"Remove"})]})}function Yb({models:n,addedIds:a,onAdd:l}){const[s,c]=m.useState(""),f=(s?n.filter(p=>{const g=s.toLowerCase();return p.publicModelId.toLowerCase().includes(g)||p.displayName.toLowerCase().includes(g)}):n).filter(p=>!a.includes(p.id));return o.jsxs("div",{className:"space-y-1",children:[o.jsxs("div",{className:"relative",children:[o.jsx(D0,{className:"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground"}),o.jsx(Ae,{className:"pl-8",placeholder:"Search models…",value:s,onChange:p=>c(p.target.value)}),s&&o.jsx("button",{className:"absolute right-2 top-2.5 text-muted-foreground hover:text-foreground",onClick:()=>c(""),children:o.jsx(Cu,{className:"h-4 w-4"})})]}),f.length===0?o.jsx("p",{className:"text-xs text-muted-foreground",children:"No models match."}):o.jsx("div",{className:"max-h-40 space-y-1 overflow-auto rounded border p-1",children:f.map(p=>o.jsxs("div",{className:"flex items-center justify-between rounded p-1 text-sm hover:bg-accent",children:[o.jsx("span",{className:"font-mono text-xs",children:p.publicModelId}),o.jsx(me,{size:"sm",variant:"ghost",onClick:()=>l(p.id),children:"+ Add"})]},p.id))})]})}function wk(){const[n,a]=m.useState([]),[l,s]=m.useState([]),[c,u]=m.useState([]),[f,p]=m.useState(!1),[g,v]=m.useState({alias:"",targetKind:"model",targetId:"",enabled:!0}),x=async()=>{const[b,w,E]=await Promise.all([Se.get("/api/admin/aliases"),Se.get("/api/admin/models"),Se.get("/api/admin/combos")]);a(b.aliases),s(w.models),u(E.combos)};m.useEffect(()=>{x()},[]);const y=async()=>{try{await Se.post("/api/admin/aliases",g),ve.success("Alias created"),p(!1),v({alias:"",targetKind:"model",targetId:"",enabled:!0}),x()}catch(b){ve.error(b.message)}};return o.jsxs("div",{children:[o.jsx($a,{title:"Aliases",description:"Stable client-visible names for models or combos",actions:o.jsxs(Mn,{open:f,onOpenChange:p,children:[o.jsx(mi,{asChild:!0,children:o.jsxs(me,{children:[o.jsx(Su,{className:"mr-1 h-4 w-4"})," New alias"]})}),o.jsxs(vn,{children:[o.jsx(xn,{children:o.jsx(yn,{children:"New alias"})}),o.jsxs("div",{className:"space-y-3",children:[o.jsxs("div",{children:[o.jsx(we,{children:"Alias"}),o.jsx(Ae,{value:g.alias,onChange:b=>v({...g,alias:b.target.value}),placeholder:"coding"})]}),o.jsxs("div",{children:[o.jsx(we,{children:"Target type"}),o.jsxs(Ua,{value:g.targetKind,onValueChange:b=>v({...g,targetKind:b}),children:[o.jsx(Sa,{children:o.jsx(Ba,{})}),o.jsxs(ja,{children:[o.jsx(Rt,{value:"model",children:"Model"}),o.jsx(Rt,{value:"combo",children:"Combo"})]})]})]}),o.jsxs("div",{children:[o.jsx(we,{children:"Target"}),o.jsxs(Ua,{value:g.targetId,onValueChange:b=>v({...g,targetId:b}),children:[o.jsx(Sa,{children:o.jsx(Ba,{placeholder:"Choose target"})}),o.jsx(ja,{children:(g.targetKind==="model"?l:c).map(b=>o.jsx(Rt,{value:b.id,children:b.publicModelId},b.id))})]})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ca,{checked:g.enabled,onCheckedChange:b=>v({...g,enabled:b})}),o.jsx(we,{children:"Enabled"})]})]}),o.jsxs(An,{children:[o.jsx(me,{variant:"outline",onClick:()=>p(!1),children:"Cancel"}),o.jsx(me,{disabled:!g.alias||!g.targetId,onClick:y,children:"Create"})]})]})]})}),o.jsxs(nt,{children:[o.jsxs(at,{children:[o.jsx(rt,{className:"text-base",children:"All aliases"}),o.jsxs(gn,{children:[n.length," total"]})]}),o.jsx(lt,{children:o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Alias"}),o.jsx(ye,{children:"Target"}),o.jsx(ye,{children:"Type"}),o.jsx(ye,{children:"Enabled"}),o.jsx(ye,{})]})}),o.jsxs(da,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:5,className:"text-center text-muted-foreground",children:"No aliases yet."})}),n.map(b=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:b.alias}),o.jsx(pe,{className:"font-mono text-xs",children:b.targetName??b.targetId}),o.jsx(pe,{children:o.jsx(Qe,{variant:"outline",children:b.targetKind})}),o.jsx(pe,{children:b.enabled?"Yes":"No"}),o.jsx(pe,{className:"text-right",children:o.jsx(me,{size:"sm",variant:"outline",onClick:async()=>{await Se.del(`/api/admin/aliases/${b.id}`),ve.success("Removed"),x()},children:"Delete"})})]},b.id))]})]})})]})]})}function Sk(){const[n,a]=m.useState([]),[l,s]=m.useState([]),[c,u]=m.useState([]),[f,p]=m.useState(!1),[g,v]=m.useState(null),[x,y]=m.useState(null),[b,w]=m.useState(null),[E,j]=m.useState({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""}),C=async()=>{const[A,U,k]=await Promise.all([Se.get("/api/admin/api-keys"),Se.get("/api/admin/models"),Se.get("/api/admin/combos")]);a(A.apiKeys),s(U.models),u(k.combos)};m.useEffect(()=>{C()},[]);const N=async()=>{try{if(g){await Se.patch("/api/admin/api-keys",{id:g,name:E.name,expiresAt:E.expiresAt||null,allowAllModels:E.allowAll,permissions:E.allowAll?[]:E.permissions,rpmLimit:E.rpmLimit?Number(E.rpmLimit):null,tpmLimit:E.tpmLimit?Number(E.tpmLimit):null,maxConcurrent:E.concurrency?Number(E.concurrency):null}),p(!1),v(null),j({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""}),ve.success("Key updated"),C();return}const A=await Se.post("/api/admin/api-keys",{name:E.name,expiresAt:E.expiresAt||null,allowAllModels:E.allowAll,permissions:E.allowAll?void 0:E.permissions,rpmLimit:E.rpmLimit?Number(E.rpmLimit):null,tpmLimit:E.tpmLimit?Number(E.tpmLimit):null,maxConcurrent:E.concurrency?Number(E.concurrency):null,...E.customSecret.trim()?{secret:E.customSecret.trim()}:{}});p(!1),y({secret:A.secret,name:A.name}),j({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""}),C()}catch(A){ve.error(A.message)}},M=async A=>{try{const k=((await Se.get(`/api/admin/api-keys/${A.id}`)).apiKey.permissions??[]).filter($=>$.targetKind==="model"||$.targetKind==="combo");v(A.id),j({name:A.name,expiresAt:A.expiresAt?A.expiresAt.slice(0,16):"",allowAll:A.allowAllModels,permissions:k,rpmLimit:A.rpmLimit!=null?String(A.rpmLimit):"",tpmLimit:A.tpmLimit!=null?String(A.tpmLimit):"",concurrency:A.concurrencyLimit!=null?String(A.concurrencyLimit):"",customSecret:""}),p(!0)}catch(U){ve.error(U.message)}},T=()=>{p(!1),v(null),j({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""})},D=async(A,U)=>{try{await Se.patch("/api/admin/api-keys",{id:A,enabled:!U}),ve.success(U?"Key disabled":"Key enabled"),C()}catch(k){ve.error(k.message)}},O=async A=>{if(window.confirm("Delete this API key? This cannot be undone."))try{await Se.del(`/api/admin/api-keys/${A}`),ve.success("Key deleted"),C()}catch(U){ve.error(U.message)}};return o.jsxs("div",{children:[o.jsx($a,{title:"API Keys",description:"Gateway bearer keys for client applications",actions:o.jsxs(Mn,{open:f,onOpenChange:A=>{A?p(!0):T()},children:[o.jsx(mi,{asChild:!0,children:o.jsxs(me,{children:[o.jsx(Su,{className:"mr-1 h-4 w-4"})," New key"]})}),o.jsxs(vn,{className:"max-w-2xl",children:[o.jsx(xn,{children:o.jsx(yn,{children:g?"Edit API key":"New API key"})}),o.jsxs("div",{className:"space-y-3",children:[o.jsxs("div",{children:[o.jsx(we,{children:"Name"}),o.jsx(Ae,{value:E.name,onChange:A=>j({...E,name:A.target.value})})]}),o.jsxs("div",{children:[o.jsx(we,{children:"Expires (optional)"}),o.jsx(Ae,{type:"datetime-local",value:E.expiresAt,onChange:A=>j({...E,expiresAt:A.target.value})})]}),o.jsxs("div",{className:"grid grid-cols-3 gap-2",children:[o.jsxs("div",{children:[o.jsx(we,{children:"RPM limit"}),o.jsx(Ae,{value:E.rpmLimit,onChange:A=>j({...E,rpmLimit:A.target.value}),type:"number"})]}),o.jsxs("div",{children:[o.jsx(we,{children:"TPM limit"}),o.jsx(Ae,{value:E.tpmLimit,onChange:A=>j({...E,tpmLimit:A.target.value}),type:"number"})]}),o.jsxs("div",{children:[o.jsx(we,{children:"Concurrency"}),o.jsx(Ae,{value:E.concurrency,onChange:A=>j({...E,concurrency:A.target.value}),type:"number"})]})]}),!g&&o.jsxs("div",{children:[o.jsx(we,{children:"Key value (optional)"}),o.jsx(Ae,{value:E.customSecret,onChange:A=>j({...E,customSecret:A.target.value}),placeholder:"Leave empty to auto-generate ld-…"}),o.jsx("p",{className:"text-xs text-muted-foreground",children:"If provided, this exact value is stored as the key. Otherwise a random ld-… key is generated."})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ca,{checked:E.allowAll,onCheckedChange:A=>j({...E,allowAll:A})}),o.jsx(we,{children:"Allow all current and future models"})]}),!E.allowAll&&o.jsxs("div",{children:[o.jsx(we,{children:"Scope"}),o.jsx("div",{className:"max-h-48 space-y-1 overflow-auto rounded border p-2",children:[...l.map(A=>({targetKind:"model",targetId:A.id,label:A.publicModelId})),...c.map(A=>({targetKind:"combo",targetId:A.id,label:A.publicModelId}))].map(A=>{const U=E.permissions.some(k=>k.targetKind===A.targetKind&&k.targetId===A.targetId);return o.jsxs("label",{className:"flex items-center gap-2 rounded p-1 text-sm hover:bg-accent",children:[o.jsx(jp,{checked:U,onCheckedChange:k=>{j($=>({...$,permissions:k?[...$.permissions,{targetKind:A.targetKind,targetId:A.targetId}]:$.permissions.filter(X=>!(X.targetKind===A.targetKind&&X.targetId===A.targetId))}))}}),o.jsx("span",{className:"font-mono text-xs",children:A.label}),o.jsx(Qe,{variant:"outline",className:"ml-1",children:A.targetKind})]},`${A.targetKind}:${A.targetId}`)})})]})]}),o.jsxs(An,{children:[o.jsx(me,{variant:"outline",onClick:T,children:"Cancel"}),o.jsx(me,{disabled:!E.name,onClick:N,children:g?"Save changes":"Create"})]})]})]})}),o.jsxs(nt,{children:[o.jsxs(at,{children:[o.jsx(rt,{className:"text-base",children:"All keys"}),o.jsxs(gn,{children:[n.length," total"]})]}),o.jsx(lt,{children:o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Name"}),o.jsx(ye,{children:"Prefix"}),o.jsx(ye,{children:"Status"}),o.jsx(ye,{children:"Scope"}),o.jsx(ye,{children:"RPM/TPM/Conc"}),o.jsx(ye,{})]})}),o.jsxs(da,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:6,className:"text-center text-muted-foreground",children:"No API keys yet."})}),n.map(A=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-medium",children:A.name}),o.jsxs(pe,{className:"font-mono text-xs",children:[A.keyPrefix,"…"]}),o.jsx(pe,{children:A.enabled?o.jsx(Qe,{variant:"success",children:"enabled"}):o.jsx(Qe,{variant:"destructive",children:"disabled"})}),o.jsx(pe,{children:A.allowAllModels?"all":`${A.modelScopeCount} scoped`}),o.jsx(pe,{className:"text-xs",children:[A.rpmLimit,A.tpmLimit,A.concurrencyLimit].map((U,k)=>U?["","RPM","TPM","Conc"][k+1]:null).filter(Boolean).join(" / ")||"—"}),o.jsx(pe,{className:"text-right",children:o.jsxs("div",{className:"flex items-center justify-end gap-1",children:[A.secret&&o.jsxs(o.Fragment,{children:[o.jsx(me,{size:"sm",variant:"ghost",title:"Copy secret",onClick:()=>{navigator.clipboard.writeText(A.secret),ve.success("Copied")},children:o.jsx(Fc,{className:"h-3.5 w-3.5"})}),o.jsx(me,{size:"sm",variant:"ghost",title:"Show secret",onClick:()=>w({secret:A.secret,name:A.name}),children:o.jsx(sR,{className:"h-3.5 w-3.5"})})]}),o.jsx(me,{size:"sm",variant:"ghost",title:"Edit",onClick:()=>void M(A),children:o.jsx(hR,{className:"h-3.5 w-3.5"})}),o.jsxs(me,{size:"sm",variant:"outline",onClick:()=>D(A.id,A.enabled),children:[A.enabled?o.jsx(FE,{className:"mr-1 h-3.5 w-3.5"}):o.jsx(ci,{className:"mr-1 h-3.5 w-3.5"}),A.enabled?"Disable":"Enable"]}),o.jsx(me,{size:"sm",variant:"destructive",onClick:()=>O(A.id),children:o.jsx(ju,{className:"h-3.5 w-3.5"})})]})})]},A.id))]})]})})]}),o.jsx(Mn,{open:!!x,onOpenChange:A=>{A||y(null)},children:o.jsxs(vn,{children:[o.jsxs(xn,{children:[o.jsx(yn,{children:"API key created"}),o.jsx(uu,{children:"Copy now — this secret will not be shown again."})]}),o.jsx("div",{className:"rounded border bg-muted p-3 font-mono text-xs break-all",children:x==null?void 0:x.secret}),o.jsxs(An,{children:[o.jsxs(me,{onClick:()=>{x&&(navigator.clipboard.writeText(x.secret),ve.success("Copied"))},children:[o.jsx(Fc,{className:"mr-1 h-4 w-4"})," Copy"]}),o.jsx(me,{variant:"outline",onClick:()=>y(null),children:"I have saved it"})]})]})}),o.jsx(Mn,{open:!!b,onOpenChange:A=>{A||w(null)},children:o.jsxs(vn,{children:[o.jsxs(xn,{children:[o.jsxs(yn,{children:["API key: ",b==null?void 0:b.name]}),o.jsx(uu,{children:"Full secret for this key, readable any time."})]}),o.jsx("div",{className:"rounded border bg-muted p-3 font-mono text-xs break-all",children:b==null?void 0:b.secret}),o.jsxs(An,{children:[o.jsxs(me,{onClick:()=>{b&&(navigator.clipboard.writeText(b.secret),ve.success("Copied"))},children:[o.jsx(Fc,{className:"mr-1 h-4 w-4"})," Copy"]}),o.jsx(me,{variant:"outline",onClick:()=>w(null),children:"Close"})]})]})})]})}const jk=3e3;function Ck(n,a){return!(a.success!=="all"&&n.success!==(a.success==="true")||a.protocol!=="all"&&n.protocol!==a.protocol||a.streaming!=="all"&&n.streaming!==(a.streaming==="true")||a.model&&!n.requestedModel.toLowerCase().includes(a.model.toLowerCase()))}function Ek(){const[n,a]=m.useState([]),[l,s]=m.useState(0),[c,u]=m.useState(0),[f,p]=m.useState({success:"all",protocol:"all",streaming:"all",model:""}),[g,v]=m.useState(null),[x,y]=m.useState(null),[b,w]=m.useState(0),E=50,j=m.useRef(Date.now()),C=m.useRef(new Set),N=m.useRef(f);N.current=f;const M=m.useRef(c);M.current=c;const T=m.useCallback(async()=>{const O=new URLSearchParams;O.set("limit",String(E)),O.set("offset",String(c)),f.success!=="all"&&O.set("success",f.success),f.protocol!=="all"&&O.set("protocol",f.protocol),f.streaming!=="all"&&O.set("streaming",f.streaming),f.model&&O.set("requestedModel",f.model);const A=await Se.get(`/api/admin/requests?${O.toString()}`);a(A.requests),s(A.total);for(const U of A.requests)C.current.add(U.id)},[c,f]);m.useEffect(()=>{T()},[T]),m.useEffect(()=>{w(0)},[c,f]),m.useEffect(()=>{let O=!1,A=null;const U=new Set,k=()=>{O||(A=new EventSource(`/api/admin/requests/stream?since=${j.current}`),A.addEventListener("request",$=>{if(!O)try{const X=JSON.parse($.data),te=new Date(X.createdAt).getTime();if(Number.isFinite(te)&&(j.current=Math.max(j.current,te)),C.current.has(X.id))return;C.current.add(X.id),w(G=>G+1),M.current===0&&Ck(X,N.current)&&(a(G=>G.some(ie=>ie.id===X.id)?G:[X,...G].slice(0,E)),s(G=>G+1))}catch{}}),A.onerror=()=>{A==null||A.close(),A=null,O||U.add(setTimeout(k,jk))})};return k(),()=>{O=!0,A==null||A.close();for(const $ of U)clearTimeout($);U.clear()}},[]);const D=async O=>{v(O);const A=await Se.get(`/api/admin/requests/${O}`);y(A)};return o.jsxs("div",{children:[o.jsx($a,{title:"Requests",description:`${l} matching · live updates`}),o.jsxs(nt,{children:[o.jsxs(at,{children:[o.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[o.jsxs(Ua,{value:f.success,onValueChange:O=>{u(0),p({...f,success:O})},children:[o.jsx(Sa,{className:"w-36",children:o.jsx(Ba,{})}),o.jsxs(ja,{children:[o.jsx(Rt,{value:"all",children:"All"}),o.jsx(Rt,{value:"true",children:"Success"}),o.jsx(Rt,{value:"false",children:"Failed"})]})]}),o.jsxs(Ua,{value:f.protocol,onValueChange:O=>{u(0),p({...f,protocol:O})},children:[o.jsx(Sa,{className:"w-32",children:o.jsx(Ba,{})}),o.jsxs(ja,{children:[o.jsx(Rt,{value:"all",children:"Any protocol"}),o.jsx(Rt,{value:"openai",children:"OpenAI"}),o.jsx(Rt,{value:"anthropic",children:"Anthropic"})]})]}),o.jsxs(Ua,{value:f.streaming,onValueChange:O=>{u(0),p({...f,streaming:O})},children:[o.jsx(Sa,{className:"w-32",children:o.jsx(Ba,{})}),o.jsxs(ja,{children:[o.jsx(Rt,{value:"all",children:"Any"}),o.jsx(Rt,{value:"true",children:"Streaming"}),o.jsx(Rt,{value:"false",children:"Non-stream"})]})]}),o.jsx(Ae,{className:"max-w-xs",placeholder:"Model contains…",value:f.model,onChange:O=>{u(0),p({...f,model:O.target.value})}}),b>0&&o.jsxs(me,{size:"sm",variant:"secondary",onClick:()=>{w(0),T()},children:[b," new request",b>1?"s":""," — refresh"]})]}),o.jsx(rt,{className:"mt-3 text-base",children:"Results"})]}),o.jsxs(lt,{children:[o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Time"}),o.jsx(ye,{children:"Status"}),o.jsx(ye,{children:"Requested"}),o.jsx(ye,{children:"Final"}),o.jsx(ye,{children:"Tokens"}),o.jsx(ye,{children:"Latency"}),o.jsx(ye,{children:"Attempts"}),o.jsx(ye,{children:"Key"}),o.jsx(ye,{children:"IP"}),o.jsx(ye,{})]})}),o.jsxs(da,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:10,className:"text-center text-muted-foreground",children:"No requests yet."})}),n.map(O=>o.jsxs(We,{className:"cursor-pointer",onClick:()=>D(O.id),children:[o.jsx(pe,{className:"text-xs",children:Lm(O.createdAt)}),o.jsx(pe,{children:O.success?o.jsx(Qe,{variant:"success",children:O.httpStatus}):o.jsx(Qe,{variant:"destructive",children:O.httpStatus})}),o.jsx(pe,{className:"font-mono text-xs",children:O.requestedModel}),o.jsx(pe,{className:"font-mono text-xs text-muted-foreground",children:O.finalModelPublicId??"—"}),o.jsxs(pe,{className:"text-xs",children:[Kt(O.inputTokens+O.outputTokens)," ",O.cacheReadTokens?o.jsxs("span",{className:"text-amber-600",children:["(+",O.cacheReadTokens," cache)"]}):null]}),o.jsxs(pe,{className:"text-xs",children:[Ol(O.totalLatencyMs),O.ttftMs?o.jsxs("span",{className:"text-muted-foreground",children:[" · ttft ",O.ttftMs,"ms"]}):null]}),o.jsxs(pe,{className:"text-xs",children:[O.attemptsCount,O.gatewayCacheHit?o.jsx(Qe,{variant:"secondary",className:"ml-1",children:"cache"}):null]}),o.jsx(pe,{className:"text-xs",children:O.apiKeyName??"—"}),o.jsx(pe,{className:"text-xs",children:O.clientIp}),o.jsx(pe,{className:"text-right",children:o.jsx(me,{size:"sm",variant:"ghost",children:"View"})})]},O.id))]})]}),o.jsxs("div",{className:"mt-3 flex items-center justify-between",children:[o.jsxs("span",{className:"text-xs text-muted-foreground",children:["Showing ",c+1,"–",Math.min(c+E,l)," of ",l]}),o.jsxs("div",{className:"flex gap-2",children:[o.jsx(me,{size:"sm",variant:"outline",disabled:c===0,onClick:()=>u(Math.max(0,c-E)),children:"Prev"}),o.jsx(me,{size:"sm",variant:"outline",disabled:c+E>=l,onClick:()=>u(c+E),children:"Next"})]})]})]})]}),o.jsx(Mn,{open:!!g,onOpenChange:O=>{O||(v(null),y(null))},children:o.jsxs(vn,{className:"max-w-3xl",children:[o.jsx(xn,{children:o.jsxs(yn,{children:["Request ",tN(g,16)]})}),x?o.jsxs("div",{className:"space-y-3 text-sm",children:[o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Requested model"}),o.jsx("span",{className:"font-mono text-xs",children:x.request.requestedModel})]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Upstream model"}),o.jsx("span",{className:"font-mono text-xs",children:x.request.finalModelUpstreamId??"—"})]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Provider"}),x.request.providerId?o.jsx(ra,{className:"text-primary underline",to:`/providers?providerId=${encodeURIComponent(x.request.providerId)}`,children:x.request.providerName??x.request.providerSlug??x.request.providerId}):"—"]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Route"}),x.request.resolvedTargetId?o.jsx(ra,{className:"text-primary underline",to:x.request.resolvedTargetKind==="combo"?"/combos":"/models",children:x.request.resolvedTargetKind??"target"}):"—"]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Status"}),x.request.success?o.jsx(Qe,{variant:"success",children:x.request.httpStatus}):o.jsx(Qe,{variant:"destructive",children:x.request.httpStatus})]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Latency"}),Ol(x.request.totalLatencyMs)]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Tokens"}),"in ",Kt(x.request.inputTokens)," · out ",Kt(x.request.outputTokens)," · cache ",Kt(x.request.cacheReadTokens)]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Attempts"}),x.request.attemptsCount]})]}),x.request.errorType&&o.jsxs("div",{className:"rounded border border-destructive/40 bg-destructive/10 p-2",children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Error"}),o.jsxs("div",{className:"font-mono text-xs",children:[x.request.errorType,": ",x.request.errorMessage]})]}),x.request.fallbackReasons.length>0&&o.jsxs("div",{className:"rounded border border-amber-500/40 bg-amber-500/10 p-2",children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Fallback reasons"}),o.jsx("div",{className:"text-xs",children:x.request.fallbackReasons.join(", ")})]}),o.jsxs("div",{children:[o.jsxs("div",{className:"mb-1 flex items-center justify-between text-xs text-muted-foreground",children:[o.jsx("span",{children:"Safe replay curl"}),o.jsxs(me,{size:"sm",variant:"ghost",onClick:()=>{navigator.clipboard.writeText(x.request.reproductionCurl).then(()=>ve.success("Curl copied"))},children:[o.jsx(Fc,{className:"mr-1 h-3.5 w-3.5"})," Copy"]})]}),o.jsx("pre",{className:"max-h-36 overflow-auto whitespace-pre-wrap rounded bg-muted p-2 font-mono text-xs",children:x.request.reproductionCurl}),o.jsx("p",{className:"mt-1 text-xs text-muted-foreground",children:"Replace the placeholder key before running. No stored secret is included."})]}),x.request.requestPayload&&o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Request content"}),o.jsx("pre",{className:"max-h-60 overflow-auto rounded bg-muted p-2 font-mono text-xs whitespace-pre-wrap",children:x.request.requestPayload})]}),x.request.responsePayload&&o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Response content"}),o.jsx("pre",{className:"max-h-60 overflow-auto rounded bg-muted p-2 font-mono text-xs whitespace-pre-wrap",children:x.request.responsePayload})]}),x.attempts.length>0&&o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Attempts"}),o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"#"}),o.jsx(ye,{children:"Provider"}),o.jsx(ye,{children:"Model"}),o.jsx(ye,{children:"Status"}),o.jsx(ye,{children:"Latency"}),o.jsx(ye,{children:"Reason"})]})}),o.jsx(da,{children:x.attempts.map(O=>o.jsxs(We,{children:[o.jsx(pe,{children:O.attemptNumber}),o.jsx(pe,{children:O.providerName}),o.jsxs(pe,{children:[o.jsx("div",{className:"font-mono text-xs",children:O.modelPublicId}),o.jsxs("div",{className:"text-[11px] text-muted-foreground",children:["upstream: ",O.upstreamModelId]})]}),o.jsx(pe,{children:O.success?o.jsx(Qe,{variant:"success",children:String(O.statusCode??"OK")}):o.jsx(Qe,{variant:"destructive",children:String(O.statusCode??"err")})}),o.jsx(pe,{className:"text-xs",children:Ol(O.latencyMs)}),o.jsx(pe,{className:"text-xs",children:O.failureReason??O.selectionReason})]},O.id))})]})]})]}):o.jsx("div",{className:"text-muted-foreground",children:"Loading…"})]})})]})}var Rk=Object.defineProperty,Zs=(n,a)=>Rk(n,"name",{value:a,configurable:!0}),_p="Tabs",[Nk,Z4]=kn(_p,[Lu]),ES=Lu(),[Tk,kp]=Nk(_p),Mk=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,value:c,onValueChange:u,defaultValue:f,orientation:p="horizontal",dir:g,activationMode:v="automatic",...x}=a,y=di(g),[b,w]=yr({prop:c,onChange:u,defaultProp:f??"",caller:_p});return o.jsx(Tk,{scope:s,baseId:La(),value:b,onValueChange:w,orientation:p,dir:y,activationMode:v,children:o.jsx(Ve.div,{dir:y,"data-orientation":p,...x,ref:l})})},"Tabs")),Ak="TabsList",Dk=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,loop:c=!0,...u}=a,f=kp(Ak,s),p=ES(s);return o.jsx(G1,{asChild:!0,...p,orientation:f.orientation,dir:f.dir,loop:c,children:o.jsx(Ve.div,{role:"tablist","aria-orientation":f.orientation,...u,ref:l})})},"TabsList")),Ok="TabsTrigger",_k=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,value:c,disabled:u=!1,...f}=a,p=kp(Ok,s),g=ES(s),v=zp(p.baseId,c),x=Lp(p.baseId,c),y=c===p.value;return o.jsx(K1,{asChild:!0,...g,focusable:!u,active:y,children:o.jsx(Ve.button,{type:"button",role:"tab","aria-selected":y,"aria-controls":x,"data-state":y?"active":"inactive","data-disabled":u?"":void 0,disabled:u,id:v,...f,ref:l,onMouseDown:Ne(a.onMouseDown,b=>{!u&&b.button===0&&b.ctrlKey===!1?p.onValueChange(c):b.preventDefault()}),onKeyDown:Ne(a.onKeyDown,b=>{u||b.target!==b.currentTarget||[" ","Enter"].includes(b.key)&&p.onValueChange(c)}),onFocus:Ne(a.onFocus,()=>{const b=p.activationMode!=="manual";!y&&!u&&b&&p.onValueChange(c)})})})},"TabsTrigger")),kk="TabsContent",zk=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,value:c,forceMount:u,children:f,...p}=a,g=kp(kk,s),v=zp(g.baseId,c),x=Lp(g.baseId,c),y=c===g.value,b=m.useRef(y);return m.useEffect(()=>{const w=requestAnimationFrame(()=>b.current=!1);return()=>cancelAnimationFrame(w)},[]),o.jsx(Cr,{present:u||y,children:({present:w})=>o.jsx(Ve.div,{"data-state":y?"active":"inactive","data-orientation":g.orientation,role:"tabpanel","aria-labelledby":v,hidden:!w,id:x,tabIndex:0,...p,ref:l,style:{...a.style,animationDuration:b.current?"0s":void 0},children:w&&f})})},"TabsContent"));function zp(n,a){return`${n}-trigger-${a}`}Zs(zp,"makeTriggerId");function Lp(n,a){return`${n}-content-${a}`}Zs(Lp,"makeContentId");var Lk=Mk,RS=Dk,NS=_k,TS=zk;const MS=Lk,Up=m.forwardRef(({className:n,...a},l)=>o.jsx(RS,{ref:l,className:Ee("inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",n),...a}));Up.displayName=RS.displayName;const mr=m.forwardRef(({className:n,...a},l)=>o.jsx(NS,{ref:l,className:Ee("inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",n),...a}));mr.displayName=NS.displayName;const Os=m.forwardRef(({className:n,...a},l)=>o.jsx(TS,{ref:l,className:Ee("mt-2 ring-offset-background focus-visible:outline-none",n),...a}));Os.displayName=TS.displayName;const Uk=3e3,Bk=1600,Hk=10,Ik=3,Pk=12,qk=10*6e4,Vk={cacheReadTokens:0,promptTokens:0,gatewayCacheHits:0,fallbacks:0};function AS(n,a,l){return l==="anthropic"?n+a:n}function $k(n){return n.promptTokens>0?n.cacheReadTokens/n.promptTokens:0}function Yk(n,a){return a>0?n.fallbacks/a:0}function Gk(n,a){return a>0?n.gatewayCacheHits/a:0}function Kk(n,a,l){const s=n.totalRequests+1,c=n.successfulRequests+(l.success?1:0),u={cacheReadTokens:a.cacheReadTokens+l.cacheReadTokens,promptTokens:a.promptTokens+AS(l.inputTokens,l.cacheReadTokens,l.providerType),gatewayCacheHits:a.gatewayCacheHits+(l.gatewayCacheHit?1:0),fallbacks:a.fallbacks+(l.attemptsCount>1?1:0)};return{...n,...u,totalRequests:s,successfulRequests:c,failedRequests:n.failedRequests+(l.success?0:1),successRate:c/s,inputTokens:n.inputTokens+l.inputTokens,outputTokens:n.outputTokens+l.outputTokens,totalTokens:n.totalTokens+l.inputTokens+l.outputTokens,cacheHitRate:$k(u),gatewayCacheHitRate:Gk(u,s),fallbackRate:Yk(u,s),averageLatencyMs:(n.averageLatencyMs*n.totalRequests+l.totalLatencyMs)/s}}function Xk(n){const[a,l]=m.useState(null),[s,c]=m.useState(null),[u,f]=m.useState([]),[p,g]=m.useState([]),[v,x]=m.useState([]),[y,b]=m.useState([]),[w,E]=m.useState(!0),[j,C]=m.useState(null),N=m.useRef([]),M=m.useRef(null),T=m.useRef(Vk),D=m.useRef(new Set),O=m.useRef(Date.now()),A=m.useRef(0),U=m.useRef([]),k=m.useRef([]);return m.useEffect(()=>{let $=!1;return E(!0),C(null),D.current=new Set,O.current=Date.now(),Se.get(`/api/admin/stats?preset=${n}`).then(X=>{if(!$){l(X),c(X.summary),M.current=X.summary,T.current={cacheReadTokens:X.summary.cacheReadTokens,promptTokens:X.summary.cacheHitRate>0?Math.round(X.summary.cacheReadTokens/X.summary.cacheHitRate):X.summary.inputTokens,gatewayCacheHits:Math.round(X.summary.gatewayCacheHitRate*X.summary.totalRequests),fallbacks:Math.round(X.summary.fallbackRate*X.summary.totalRequests)},f(X.recent),g(X.providers),N.current=X.providers;for(const te of X.recent)D.current.add(te.id);E(!1)}}).catch(X=>{$||(C(X.message),E(!1))}),()=>{$=!0}},[n]),m.useEffect(()=>{let $=!1,X=null;const te=new Set,G=()=>{$||(X=new EventSource(`/api/admin/requests/stream?since=${O.current}`),X.addEventListener("request",ce=>{if(!$)try{const se=JSON.parse(ce.data),_=new Date(se.createdAt).getTime();if(Number.isFinite(_)&&(O.current=Math.max(O.current,_)),D.current.has(se.id))return;D.current.add(se.id);const H={cacheReadTokens:T.current.cacheReadTokens+se.cacheReadTokens,promptTokens:T.current.promptTokens+AS(se.inputTokens,se.cacheReadTokens,se.providerType),gatewayCacheHits:T.current.gatewayCacheHits+(se.gatewayCacheHit?1:0),fallbacks:T.current.fallbacks+(se.attemptsCount>1?1:0)};if(T.current=H,M.current&&c(Kk(M.current,H,se)),f(Q=>Q.some(J=>J.id===se.id)?Q:[se,...Q].slice(0,Hk)),se.providerId){N.current=N.current.map(z=>z.id===se.providerId?{...z,requests:z.requests+1,errorRate:z.requests+1?(z.errorRate*z.requests+(se.success?0:1))/(z.requests+1):0}:z),g(N.current);const Q=`p${++A.current}`,J={id:Q,providerId:se.providerId,success:se.success};U.current=[...U.current.slice(-(Ik*4)),J],x(U.current);const ee=setTimeout(()=>{U.current=U.current.filter(z=>z.id!==Q),x(U.current)},Bk);te.add(ee)}k.current.some(Q=>Q.id===se.id)&&(k.current=k.current.filter(Q=>Q.id!==se.id),b(k.current))}catch{}}),X.addEventListener("request_started",ce=>{if(!$)try{const se=JSON.parse(ce.data);if(!se.providerId||se.providerId==="")return;k.current=[...k.current.filter(_=>_.id!==se.requestId).slice(-(Pk-1)),{id:se.requestId,providerId:se.providerId,startedAt:Date.now(),ttftMs:se.ttftMs??0}],b(k.current)}catch{}}),X.onerror=()=>{X==null||X.close(),X=null,$||te.add(setTimeout(G,Uk))})};G();const ie=setInterval(()=>{const ce=Date.now()-qk;k.current.some(se=>se.startedAt<ce)&&(k.current=k.current.filter(se=>se.startedAt>=ce),b(k.current))},3e4);return()=>{$=!0,X==null||X.close();for(const ce of te)clearTimeout(ce);te.clear(),clearInterval(ie)}},[]),m.useEffect(()=>{const $=setInterval(()=>{Se.get("/api/admin/providers").then(X=>{const te=new Map(X.providers.map(G=>[G.id,G]));N.current=N.current.map(G=>{const ie=te.get(G.id);return ie?{...G,health:ie.health,enabled:ie.enabled}:G}),g(N.current)}).catch(()=>{})},3e4);return()=>clearInterval($)},[]),{snapshot:a,live:s??(a==null?void 0:a.summary)??Fk,recent:u,providers:p,pulses:v,activeRoutes:y,loading:w,error:j}}const Fk={totalRequests:0,successfulRequests:0,failedRequests:0,successRate:0,inputTokens:0,outputTokens:0,totalTokens:0,cacheReadTokens:0,cacheWriteTokens:0,reasoningTokens:0,averageLatencyMs:0,p95LatencyMs:0,averageTtftMs:null,p95TtftMs:null,cacheHitRate:0,gatewayCacheHitRate:0,fallbackRate:0};function DS({data:n,className:a,strokeClass:l="stroke-primary",fillClass:s}){if(n.length===0)return o.jsx("svg",{className:Ee("h-6 w-20",a),viewBox:"0 0 80 24"});const f=Math.max(...n),p=Math.min(...n),g=f-p||1,x=n.map((y,b)=>{const w=b/(n.length-1)*78+1,E=22-(y-p)/g*20;return`${w.toFixed(1)},${E.toFixed(1)}`}).join(" ");return o.jsxs("svg",{className:Ee("h-6 w-20",a),viewBox:"0 0 80 24",preserveAspectRatio:"none",children:[s&&o.jsx("polygon",{points:`1,23 ${x} 79,23`,className:s}),o.jsx("polyline",{points:x,fill:"none",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",className:l})]})}function Qk(n,a,l){const s=performance.now();let c=0;const u=f=>{const p=Math.min((f-s)/a,1),g=Math.round(n*p);g!==c&&(c=g,l(g)),p<1&&requestAnimationFrame(u)};requestAnimationFrame(u)}function Zk({delta:n,inverse:a}){if(Math.abs(n)<.005)return null;const l=n>0,s=a?!l:l,c=`${(Math.abs(n)*100).toFixed(1)}%`;return o.jsxs("span",{className:Ee("ml-1.5 inline-flex items-center rounded-full px-1.5 py-0.5 text-[10px] font-semibold leading-none",s?"bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-300":"bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300"),children:[o.jsx("span",{className:"mr-0.5",children:l?"▲":"▼"}),c]})}function el({icon:n,label:a,value:l,format:s="number",delta:c,deltaInverse:u,sparkData:f,sparkStroke:p}){const[g,v]=m.useState(0),x=m.useRef(0);m.useEffect(()=>{const b=x.current,w=l;x.current=l,b!==w&&Qk(Math.abs(w-b),600,E=>v(b+(w>b?E:-E)))},[l]);const y=s==="percent"?Eu(g):s==="latency"?Ol(g):Kt(Math.round(g));return o.jsxs(nt,{children:[o.jsxs(at,{className:"flex flex-row items-center justify-between pb-1",children:[o.jsxs(rt,{className:"flex items-center gap-2 text-sm font-medium text-muted-foreground",children:[o.jsx(n,{className:"h-4 w-4"}),a]}),c!==void 0&&o.jsx(Zk,{delta:c,inverse:u})]}),o.jsxs(lt,{className:"flex items-end justify-between",children:[o.jsx("span",{className:"text-2xl font-semibold tabular-nums",children:y}),f&&f.length>1&&o.jsx(DS,{data:f,strokeClass:p??"stroke-primary",fillClass:"fill-primary/10"})]})]})}const OS=1e3,Gb=380,Vc=60,tl=OS/2,nl=720,Bh=62,Jk=260;function Wk(n){return n==="healthy"?"fill-emerald-400":n==="degraded"?"fill-amber-400":"fill-red-400"}function $c(n,a,l,s){const c=n+(l-n)*.45,u=n+(l-n)*.55;return`M${n},${a} C${c},${a} ${u},${s} ${l},${s}`}function e4({liveRequests:n,successRate:a,providers:l,pulses:s,activeRoutes:c}){const u=Gb/2,f=u,p=Math.max(1,l.reduce((x,y)=>x+y.requests,0)),g=new Set(c.map(x=>x.providerId)),v=g.size>0;return o.jsxs(nt,{children:[o.jsx(at,{className:"pb-2",children:o.jsxs("div",{className:"flex items-center justify-between",children:[o.jsx(rt,{className:"text-base",children:"Real-time Request Routing"}),o.jsxs("div",{className:"flex items-center gap-3 text-xs text-muted-foreground",children:[o.jsxs("span",{className:"flex items-center gap-1",children:[o.jsx("span",{className:"inline-block h-2 w-2 rounded-full bg-emerald-400"})," healthy"]}),o.jsxs("span",{className:"flex items-center gap-1",children:[o.jsx("span",{className:"inline-block h-2 w-2 rounded-full bg-amber-400"})," degraded"]}),o.jsxs("span",{className:"flex items-center gap-1",children:[o.jsx("span",{className:"inline-block h-2 w-2 rounded-full bg-red-400"})," down"]})]})]})}),o.jsx(lt,{className:"pt-0",children:o.jsx("div",{className:"relative w-full",children:o.jsxs("svg",{viewBox:`0 0 ${OS} ${Gb}`,className:"w-full h-auto",preserveAspectRatio:"xMidYMid meet",children:[o.jsx("defs",{children:o.jsxs("filter",{id:"glow",x:"-50%",y:"-50%",width:"200%",height:"200%",children:[o.jsx("feGaussianBlur",{stdDeviation:"3",result:"blur"}),o.jsxs("feMerge",{children:[o.jsx("feMergeNode",{in:"blur"}),o.jsx("feMergeNode",{in:"SourceGraphic"})]})]})}),l.map(x=>{const b=60+l.indexOf(x)*Bh,w=x.requests/p,E=Math.max(1.5,Math.min(6,2+w*8)),j=g.has(x.id);return o.jsxs("g",{children:[j&&o.jsx("path",{d:$c(tl,u,nl-20,b),fill:"none",stroke:"hsl(var(--primary) / 0.25)",strokeWidth:E+6,strokeLinecap:"round"}),o.jsx("path",{d:$c(tl,u,nl-20,b),fill:"none",stroke:j?"hsl(var(--primary))":"hsl(var(--border))",strokeWidth:j?E+1:E,strokeLinecap:"round",opacity:j?.95:.6,className:j?"route-active":void 0})]},x.id)}),o.jsx("path",{d:$c(Vc+30,f,tl-30,u),fill:"none",stroke:v?"hsl(var(--primary))":"hsl(var(--border))",strokeWidth:3,strokeLinecap:"round",strokeDasharray:"6 3",opacity:v?.9:.5,className:v?"route-active":void 0}),s.map(x=>{const y=l.findIndex(j=>j.id===x.providerId);if(y===-1)return null;const b=60+y*Bh,w=$c(tl,u,nl-20,b),E=x.success?"var(--primary)":"#f87171";return o.jsxs("g",{filter:"url(#glow)",children:[o.jsx("circle",{r:5,fill:E,opacity:.9,children:o.jsx("animateMotion",{dur:"1.4s",fill:"freeze",path:w})}),o.jsx("circle",{r:9,fill:E,opacity:.25,children:o.jsx("animateMotion",{dur:"1.4s",fill:"freeze",path:w})})]},x.id)}),o.jsx("circle",{cx:Vc,cy:f,r:28,fill:"hsl(var(--card))",stroke:"hsl(var(--border))",strokeWidth:1.5}),o.jsx("text",{x:Vc,y:f-4,textAnchor:"middle",className:"fill-foreground",fontSize:12,fontWeight:600,children:Kb(n)}),o.jsx("text",{x:Vc,y:f+10,textAnchor:"middle",className:"fill-muted-foreground",fontSize:9,children:"requests"}),o.jsx("circle",{cx:tl,cy:u,r:36,fill:"hsl(var(--card))",stroke:"var(--primary)",strokeWidth:2}),o.jsx("image",{x:tl-12,y:u-16,width:24,height:24,href:"/logo.png"}),o.jsx("text",{x:tl,y:u+28,textAnchor:"middle",className:"fill-muted-foreground",fontSize:9,children:"AI Gateway"}),o.jsxs("text",{x:tl,y:u+38,textAnchor:"middle",className:"fill-emerald-500",fontSize:10,fontWeight:600,children:[(a*100).toFixed(1),"%"]}),l.map((x,y)=>{const b=60+y*Bh,w=x.requests/p,E=!x.enabled||x.requests===0;return o.jsxs("g",{opacity:E?.4:1,children:[o.jsx("rect",{x:nl-20,y:b-14,width:Jk,height:50,rx:8,fill:"hsl(var(--card))",stroke:"hsl(var(--border))",strokeWidth:1}),o.jsx("circle",{cx:nl-6,cy:b+10,r:4,className:Wk(x.health)}),o.jsx("text",{x:nl+6,y:b-2,className:"fill-foreground",fontSize:12,fontWeight:500,children:x.name}),o.jsxs("text",{x:nl+6,y:b+12,className:"fill-muted-foreground",fontSize:10,children:[x.modelCount," model",x.modelCount!==1?"s":""," · ",Kb(x.requests)," req"]}),o.jsxs("text",{x:nl+6,y:b+25,className:"fill-muted-foreground",fontSize:10,children:[(w*100).toFixed(1),"% traffic · ",x.avgLatencyMs<1e3?`${Math.round(x.avgLatencyMs)}ms`:`${(x.avgLatencyMs/1e3).toFixed(1)}s`," avg",x.errorRate>0&&o.jsxs("tspan",{className:"fill-red-500",children:[" · ",(x.errorRate*100).toFixed(0),"% err"]})]})]},x.id)})]})})})]})}function Kb(n){return n>=1e6?`${(n/1e6).toFixed(1)}M`:n>=1e3?`${(n/1e3).toFixed(1)}K`:String(n)}function t4({rows:n}){return o.jsxs(nt,{children:[o.jsx(at,{className:"pb-2",children:o.jsx(rt,{className:"text-base",children:"Recent Requests"})}),o.jsx(lt,{children:n.length===0?o.jsx("div",{className:"py-6 text-center text-sm text-muted-foreground",children:"No requests yet — traffic will appear here live."}):o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Model"}),o.jsx(ye,{children:"Provider"}),o.jsx(ye,{children:"Tokens"}),o.jsx(ye,{children:"Status"}),o.jsx(ye,{children:"Time"})]})}),o.jsx(da,{children:n.map(a=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:a.requestedModel}),o.jsx(pe,{className:"text-xs text-muted-foreground",children:a.providerName??"—"}),o.jsxs(pe,{className:"text-xs",children:[o.jsxs("span",{className:"font-mono",children:["in ",Kt(a.inputTokens)," · out ",Kt(a.outputTokens)]}),a.cacheReadTokens>0&&o.jsxs("span",{className:"ml-1 text-amber-600",children:["(+",Kt(a.cacheReadTokens)," cache)"]})]}),o.jsx(pe,{children:o.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[o.jsx("span",{className:a.success?"h-2 w-2 rounded-full bg-emerald-400":"h-2 w-2 rounded-full bg-red-400"}),o.jsx("span",{className:"text-xs",children:a.success?a.httpStatus:`${a.httpStatus} err`})]})}),o.jsx(pe,{className:"text-xs text-muted-foreground",children:nN(a.createdAt)})]},a.id))})]})})]})}const gm=34,Xb=2*Math.PI*gm;function n4(n){return n>=.95?{stroke:"#4ade80",text:"text-emerald-500"}:n>=.8?{stroke:"#fbbf24",text:"text-amber-500"}:{stroke:"#f87171",text:"text-red-500"}}function a4({successRate:n,averageLatencyMs:a,latencySpark:l}){const{stroke:s,text:c}=n4(n),u=Math.min(1,Math.max(0,n)),f=Xb*(1-u);return o.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[o.jsxs(nt,{children:[o.jsx(at,{className:"pb-2",children:o.jsx(rt,{className:"text-base",children:"Success Rate"})}),o.jsxs(lt,{className:"flex items-center gap-4",children:[o.jsxs("div",{className:"relative h-20 w-20",children:[o.jsxs("svg",{viewBox:"0 0 80 80",className:"h-20 w-20 -rotate-90",children:[o.jsx("circle",{cx:"40",cy:"40",r:gm,fill:"none",stroke:"hsl(var(--border))",strokeWidth:7}),o.jsx("circle",{cx:"40",cy:"40",r:gm,fill:"none",stroke:s,strokeWidth:7,strokeLinecap:"round",strokeDasharray:Xb,strokeDashoffset:f,style:{transition:"stroke-dashoffset 0.6s ease, stroke 0.4s ease"}})]}),o.jsx("span",{className:`absolute inset-0 flex items-center justify-center text-sm font-semibold tabular-nums ${c}`,children:Eu(n)})]}),o.jsx("p",{className:"text-sm text-muted-foreground",children:"Share of requests that completed successfully over the selected window. Updated in real time."})]})]}),o.jsxs(nt,{children:[o.jsx(at,{className:"pb-2",children:o.jsx(rt,{className:"text-base",children:"Average Latency"})}),o.jsxs(lt,{className:"flex items-end justify-between",children:[o.jsxs("div",{children:[o.jsx("div",{className:"text-2xl font-semibold tabular-nums",children:Ol(a)}),o.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Live average across the selected window"})]}),o.jsx(DS,{data:l,strokeClass:"stroke-amber-500",fillClass:"fill-amber-500/10",className:"h-10 w-28"})]})]})]})}function r4(){const[n,a]=m.useState("7d"),{snapshot:l,live:s,recent:c,providers:u,pulses:f,activeRoutes:p,loading:g,error:v}=Xk(n);if(g)return o.jsx("div",{className:"text-muted-foreground",children:"Loading…"});if(v||!l)return o.jsxs("div",{className:"text-destructive",children:["Failed to load statistics: ",v??"unknown error"]});const x=s,y=l.previous,b=l.series;function w(C,N){return N>0?(C-N)/N:void 0}const E=b.map(C=>C.requests),j=b.map(C=>C.avgLatency);return o.jsxs("div",{children:[o.jsx($a,{title:"Statistics",description:"Real-time monitoring dashboard",actions:o.jsx(MS,{value:n,onValueChange:C=>void a(C),children:o.jsxs(Up,{children:[o.jsx(mr,{value:"today",children:"Today"}),o.jsx(mr,{value:"7d",children:"7 days"}),o.jsx(mr,{value:"30d",children:"30 days"})]})})}),o.jsxs("div",{className:"grid gap-4 md:grid-cols-2 lg:grid-cols-4",children:[o.jsx(el,{icon:km,label:"Requests",value:x.totalRequests,delta:w(x.totalRequests,y.totalRequests),sparkData:E}),o.jsx(el,{icon:ci,label:"Success rate",format:"percent",value:x.successRate,delta:w(x.successRate,y.successRate),sparkData:E,sparkStroke:"stroke-emerald-500"}),o.jsx(el,{icon:rR,label:"Total tokens",value:x.totalTokens,delta:w(x.totalTokens,y.totalTokens),sparkData:b.map(C=>C.inputTokens+C.outputTokens)}),o.jsx(el,{icon:lR,label:"Cache hit rate",format:"percent",value:x.cacheHitRate,delta:w(x.cacheHitRate,y.cacheHitRate),sparkData:b.map(C=>C.cacheRead)}),o.jsx(el,{icon:tR,label:"Avg latency",format:"latency",value:x.averageLatencyMs,delta:w(x.averageLatencyMs,y.averageLatencyMs),deltaInverse:!0,sparkData:j,sparkStroke:"stroke-amber-500"}),o.jsx(el,{icon:R0,label:"p95 latency",format:"latency",value:x.p95LatencyMs}),o.jsx(el,{icon:bR,label:"Avg TTFT",format:"latency",value:x.averageTtftMs??0}),o.jsx(el,{icon:mR,label:"Fallback rate",format:"percent",value:x.fallbackRate,delta:w(x.fallbackRate,y.fallbackRate),deltaInverse:!0})]}),o.jsx("div",{className:"mt-6",children:o.jsx(e4,{liveRequests:x.totalRequests,successRate:x.successRate,providers:u,pulses:f,activeRoutes:p})}),o.jsxs("div",{className:"mt-6 grid gap-4 lg:grid-cols-3",children:[o.jsx("div",{className:"lg:col-span-2",children:o.jsx(t4,{rows:c})}),o.jsxs("div",{className:"space-y-4",children:[o.jsxs(nt,{children:[o.jsx(at,{className:"pb-2",children:o.jsx(rt,{className:"text-base",children:"Top Models"})}),o.jsx(lt,{children:o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Model"}),o.jsx(ye,{children:"Req"}),o.jsx(ye,{children:"Errors"}),o.jsx(ye,{children:"Tokens"})]})}),o.jsxs(da,{children:[l.topModels.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:4,className:"text-muted-foreground text-center",children:"No data"})}),l.topModels.map(C=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:C.publicId}),o.jsx(pe,{className:"text-xs",children:Kt(C.requests)}),o.jsx(pe,{className:"text-xs",children:o.jsx("span",{className:C.errorRate>.1?"text-destructive":"text-muted-foreground",children:Eu(C.errorRate)})}),o.jsx(pe,{className:"text-xs",children:Kt(C.totalTokens)})]},C.publicId))]})]})})]}),o.jsxs(nt,{children:[o.jsx(at,{className:"pb-2",children:o.jsx(rt,{className:"text-base",children:"Top API Keys"})}),o.jsx(lt,{children:o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Key"}),o.jsx(ye,{children:"Requests"}),o.jsx(ye,{children:"Tokens"})]})}),o.jsxs(da,{children:[l.topApiKeys.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:3,className:"text-muted-foreground text-center",children:"No data"})}),l.topApiKeys.map((C,N)=>o.jsxs(We,{children:[o.jsx(pe,{className:"text-xs",children:C.name}),o.jsx(pe,{className:"text-xs",children:Kt(C.requests)}),o.jsx(pe,{className:"text-xs",children:Kt(C.totalTokens)})]},N))]})]})})]})]})]}),o.jsx("div",{className:"mt-6",children:o.jsx(a4,{successRate:x.successRate,averageLatencyMs:x.averageLatencyMs,latencySpark:j})})]})}function l4(){const[n,a]=m.useState([]),[l,s]=m.useState(0);return m.useEffect(()=>{Se.get("/api/admin/audit?limit=200").then(c=>{a(c.rows),s(c.total)})},[]),o.jsxs("div",{children:[o.jsx($a,{title:"Audit Logs",description:`${l} entries · immutable`}),o.jsxs(nt,{children:[o.jsx(at,{children:o.jsx(rt,{className:"text-base",children:"All entries"})}),o.jsx(lt,{children:o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Time"}),o.jsx(ye,{children:"Action"}),o.jsx(ye,{children:"Status"}),o.jsx(ye,{children:"Target"}),o.jsx(ye,{children:"IP"}),o.jsx(ye,{children:"Actor"})]})}),o.jsxs(da,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:6,className:"text-center text-muted-foreground",children:"No audit events yet."})}),n.map(c=>o.jsxs(We,{children:[o.jsx(pe,{className:"text-xs",children:Lm(c.createdAt)}),o.jsx(pe,{className:"font-mono text-xs",children:c.action}),o.jsx(pe,{children:c.success?o.jsx(Qe,{variant:"success",children:"ok"}):o.jsx(Qe,{variant:"destructive",children:"fail"})}),o.jsx(pe,{className:"text-xs",children:c.targetName??c.targetId??"—"}),o.jsx(pe,{className:"text-xs",children:c.ip}),o.jsx(pe,{className:"text-xs",children:c.actor})]},c.id))]})]})})]})]})}const vm={enabled:!0,sound:!0};let ri=vm,xm=!1,Yc=null;const ym=new Set;function _S(){for(const n of ym)n()}function kS(n=!1){return xm&&!n?Promise.resolve():(!n&&Yc||(Yc=(async()=>{try{const a=await Se.get("/api/admin/settings");ri={enabled:a.settings.notificationsEnabled??vm.enabled,sound:a.settings.notificationSoundEnabled??vm.sound},xm=!0,_S()}catch{}})()),Yc)}async function Fb(n){const a={};n.enabled!==void 0&&(a.notificationsEnabled=n.enabled),n.sound!==void 0&&(a.notificationSoundEnabled=n.sound),await Se.patch("/api/admin/settings",a),ri={...ri,...n},xm=!0,_S()}function s4(n){return ym.add(n),()=>ym.delete(n)}function zS(){return m.useSyncExternalStore(s4,()=>ri,()=>ri)}const bm=m.forwardRef(({className:n,...a},l)=>o.jsx("textarea",{ref:l,className:Ee("flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",n),...a}));bm.displayName="Textarea";function o4(){const[n]=BE(),[a,l]=m.useState(null),[s,c]=m.useState(null),[u,f]=m.useState({current:"",next:""}),[p,g]=m.useState(""),[v,x]=m.useState(""),[y,b]=m.useState(null),[w,E]=m.useState(!1),[j,C]=m.useState("idle"),[N,M]=m.useState(null),T=async(le=!1)=>{C("checking"),M(null);try{const Le=await Se.get(`/api/admin/update/check${le?"?force=1":""}`);b(Le),C("idle")}catch(Le){M(Le.message),C("error")}},D=async()=>{E(!0),C("installing"),M(null);try{const le=await Se.post("/api/admin/update/run");C("restarting"),ve.success(le.message||"Update started — the gateway will restart shortly.");const Le=setInterval(()=>{fetch("/health").then(Ie=>{Ie.ok&&(clearInterval(Le),window.location.reload())}).catch(()=>{})},3e3);setTimeout(()=>clearInterval(Le),12e4)}catch(le){ve.error(le.message),M(le.message),C("error")}finally{E(!1)}},[O,A]=m.useState("disabled"),[U,k]=m.useState(""),[$,X]=m.useState(""),[te,G]=m.useState(""),[ie,ce]=m.useState([]),[se,_]=m.useState(""),[H,Q]=m.useState(""),[J,ee]=m.useState(!1),[z,I]=m.useState(null),[F,re]=m.useState(""),[he,ge]=m.useState(""),[q,oe]=m.useState(""),de=async()=>{const le=await Se.get("/api/admin/settings");l(le.settings),g(le.settings.adminIpAllow??""),x(le.settings.adminIpBlock??"");const Le=await Se.get("/api/admin/settings/system");c(Le);try{const Ie=await Se.get("/api/admin/me");A(Ie.totpEnabled?"enabled":"disabled")}catch{}};if(m.useEffect(()=>{kS(!0)},[]),m.useEffect(()=>{de(),T(!0)},[]),!a)return o.jsx("div",{className:"text-muted-foreground",children:"Loading…"});const fe=async le=>{try{await Se.patch("/api/admin/settings",le),ve.success("Saved"),de()}catch(Le){ve.error(Le.message)}},Te=async()=>{try{const le=await Se.post("/api/admin/account/totp/begin");k(le.secret),X(le.qr),A("setup"),ve.info("Scan the QR code with your authenticator app")}catch(le){ve.error(le.message)}},je=async()=>{if(!te||te.length!==6){ve.error("Enter a 6-digit code");return}try{const le=await Se.post("/api/admin/account/totp/verify",{code:te});ce(le.recoveryCodes),A("showingRecovery"),ve.success("TOTP enabled successfully")}catch(le){ve.error(le.message)}},De=async()=>{if(!se){ve.error("Enter your password");return}if(!H){ve.error("Enter a TOTP code or recovery code");return}try{await Se.post("/api/admin/account/totp/disable",{password:se,totp:H}),A("disabled"),_(""),Q(""),ve.success("TOTP disabled"),de()}catch(le){ve.error(le.message)}},Fe=async()=>{ee(!0);try{const le=await Se.post("/api/admin/account/totp/recovery/regenerate",{password:se,totp:H});ce(le.recoveryCodes),A("showingRecovery"),ve.success("Recovery codes regenerated")}catch(le){ve.error(le.message)}ee(!1)},et=n.get("tab")||"logging";return o.jsxs("div",{children:[o.jsx($a,{title:"Settings",description:"Logging, security, backup, and system info"}),o.jsxs(MS,{defaultValue:et,children:[o.jsxs(Up,{children:[o.jsx(mr,{value:"logging",children:"Logging"}),o.jsx(mr,{value:"access",children:"Access Control"}),o.jsx(mr,{value:"security",children:"Security"}),o.jsx(mr,{value:"backup",children:"Backup"}),o.jsx(mr,{value:"system",children:"System"})]}),o.jsx(Os,{value:"logging",children:o.jsxs(nt,{children:[o.jsx(at,{children:o.jsx(rt,{className:"text-base",children:"Logging policy"})}),o.jsxs(lt,{className:"space-y-3",children:[o.jsxs("div",{className:"space-y-1",children:[o.jsx(we,{children:"Request-content logging"}),o.jsxs(Ua,{value:a.contentLogMode,onValueChange:le=>fe({contentLogMode:le}),children:[o.jsx(Sa,{children:o.jsx(Ba,{})}),o.jsxs(ja,{children:[o.jsx(Rt,{value:"off",children:"Off"}),o.jsx(Rt,{value:"metadata",children:"Metadata only (default)"}),o.jsx(Rt,{value:"prompt",children:"Prompt (sanitized)"}),o.jsx(Rt,{value:"prompt_and_response",children:"Prompt + response (sanitized)"})]})]})]}),o.jsxs("div",{className:"space-y-1",children:[o.jsx(we,{children:"Retention (days)"}),o.jsx(Ae,{type:"number",min:1,max:3650,value:a.retentionDays,onChange:le=>fe({retentionDays:Number(le.target.value)})})]}),o.jsxs("div",{className:"space-y-1",children:[o.jsx(we,{children:"Database size limit (MB)"}),o.jsx(Ae,{type:"number",min:64,value:a.dbSizeLimitMb,onChange:le=>fe({dbSizeLimitMb:Number(le.target.value)})})]}),o.jsx("div",{className:"flex items-center gap-2 pt-2",children:o.jsx(me,{onClick:async()=>{const le=await Se.post("/api/admin/settings/cleanup");ve.success(`Deleted ${le.deletedRequests} old requests`)},children:"Run cleanup now"})})]})]})}),o.jsx(Os,{value:"access",children:o.jsxs(nt,{children:[o.jsxs(at,{children:[o.jsx(rt,{className:"text-base",children:"IP access control"}),o.jsx(gn,{children:"Allowlist / Blocklist for this admin website (not model traffic)"})]}),o.jsxs(lt,{className:"space-y-4",children:[o.jsxs("div",{className:"space-y-2",children:[o.jsx(we,{children:"Allow only these IPs"}),o.jsx(bm,{placeholder:`192.168.1.0/24
|
|
348
|
+
`},H_={onDragStart(n){let{active:a}=n;return"Picked up draggable item "+a.id+"."},onDragOver(n){let{active:a,over:l}=n;return l?"Draggable item "+a.id+" was moved over droppable area "+l.id+".":"Draggable item "+a.id+" is no longer over a droppable area."},onDragEnd(n){let{active:a,over:l}=n;return l?"Draggable item "+a.id+" was dropped over droppable area "+l.id:"Draggable item "+a.id+" was dropped."},onDragCancel(n){let{active:a}=n;return"Dragging was cancelled. Draggable item "+a.id+" was dropped."}};function I_(n){let{announcements:a=H_,container:l,hiddenTextDescribedById:s,screenReaderInstructions:c=B_}=n;const{announce:u,announcement:f}=z_(),p=xi("DndLiveRegion"),[g,v]=m.useState(!1);if(m.useEffect(()=>{v(!0)},[]),L_(m.useMemo(()=>({onDragStart(y){let{active:b}=y;u(a.onDragStart({active:b}))},onDragMove(y){let{active:b,over:w}=y;a.onDragMove&&u(a.onDragMove({active:b,over:w}))},onDragOver(y){let{active:b,over:w}=y;u(a.onDragOver({active:b,over:w}))},onDragEnd(y){let{active:b,over:w}=y;u(a.onDragEnd({active:b,over:w}))},onDragCancel(y){let{active:b,over:w}=y;u(a.onDragCancel({active:b,over:w}))}}),[u,a])),!g)return null;const x=ue.createElement(ue.Fragment,null,ue.createElement(__,{id:s,value:c.draggable}),ue.createElement(k_,{id:p,announcement:f}));return l?ba.createPortal(x,l):x}var Gt;(function(n){n.DragStart="dragStart",n.DragMove="dragMove",n.DragEnd="dragEnd",n.DragCancel="dragCancel",n.DragOver="dragOver",n.RegisterDroppable="registerDroppable",n.SetDroppableDisabled="setDroppableDisabled",n.UnregisterDroppable="unregisterDroppable"})(Gt||(Gt={}));function hu(){}function Mb(n,a){return m.useMemo(()=>({sensor:n,options:a??{}}),[n,a])}function P_(){for(var n=arguments.length,a=new Array(n),l=0;l<n;l++)a[l]=arguments[l];return m.useMemo(()=>[...a].filter(s=>s!=null),[...a])}const Ea=Object.freeze({x:0,y:0});function lS(n,a){return Math.sqrt(Math.pow(n.x-a.x,2)+Math.pow(n.y-a.y,2))}function sS(n,a){let{data:{value:l}}=n,{data:{value:s}}=a;return l-s}function q_(n,a){let{data:{value:l}}=n,{data:{value:s}}=a;return s-l}function Ab(n){let{left:a,top:l,height:s,width:c}=n;return[{x:a,y:l},{x:a+c,y:l},{x:a,y:l+s},{x:a+c,y:l+s}]}function oS(n,a){if(!n||n.length===0)return null;const[l]=n;return l[a]}function Db(n,a,l){return a===void 0&&(a=n.left),l===void 0&&(l=n.top),{x:a+n.width*.5,y:l+n.height*.5}}const V_=n=>{let{collisionRect:a,droppableRects:l,droppableContainers:s}=n;const c=Db(a,a.left,a.top),u=[];for(const f of s){const{id:p}=f,g=l.get(p);if(g){const v=lS(Db(g),c);u.push({id:p,data:{droppableContainer:f,value:v}})}}return u.sort(sS)},$_=n=>{let{collisionRect:a,droppableRects:l,droppableContainers:s}=n;const c=Ab(a),u=[];for(const f of s){const{id:p}=f,g=l.get(p);if(g){const v=Ab(g),x=c.reduce((b,w,E)=>b+lS(v[E],w),0),y=Number((x/4).toFixed(4));u.push({id:p,data:{droppableContainer:f,value:y}})}}return u.sort(sS)};function Y_(n,a){const l=Math.max(a.top,n.top),s=Math.max(a.left,n.left),c=Math.min(a.left+a.width,n.left+n.width),u=Math.min(a.top+a.height,n.top+n.height),f=c-s,p=u-l;if(s<c&&l<u){const g=a.width*a.height,v=n.width*n.height,x=f*p,y=x/(g+v-x);return Number(y.toFixed(4))}return 0}const G_=n=>{let{collisionRect:a,droppableRects:l,droppableContainers:s}=n;const c=[];for(const u of s){const{id:f}=u,p=l.get(f);if(p){const g=Y_(p,a);g>0&&c.push({id:f,data:{droppableContainer:u,value:g}})}}return c.sort(q_)};function K_(n,a,l){return{...n,scaleX:a&&l?a.width/l.width:1,scaleY:a&&l?a.height/l.height:1}}function iS(n,a){return n&&a?{x:n.left-a.left,y:n.top-a.top}:Ea}function X_(n){return function(l){for(var s=arguments.length,c=new Array(s>1?s-1:0),u=1;u<s;u++)c[u-1]=arguments[u];return c.reduce((f,p)=>({...f,top:f.top+n*p.y,bottom:f.bottom+n*p.y,left:f.left+n*p.x,right:f.right+n*p.x}),{...l})}}const F_=X_(1);function Q_(n){if(n.startsWith("matrix3d(")){const a=n.slice(9,-1).split(/, /);return{x:+a[12],y:+a[13],scaleX:+a[0],scaleY:+a[5]}}else if(n.startsWith("matrix(")){const a=n.slice(7,-1).split(/, /);return{x:+a[4],y:+a[5],scaleX:+a[0],scaleY:+a[3]}}return null}function Z_(n,a,l){const s=Q_(a);if(!s)return n;const{scaleX:c,scaleY:u,x:f,y:p}=s,g=n.left-f-(1-c)*parseFloat(l),v=n.top-p-(1-u)*parseFloat(l.slice(l.indexOf(" ")+1)),x=c?n.width/c:n.width,y=u?n.height/u:n.height;return{width:x,height:y,top:v,right:g+x,bottom:v+y,left:g}}const J_={ignoreTransform:!1};function Qs(n,a){a===void 0&&(a=J_);let l=n.getBoundingClientRect();if(a.ignoreTransform){const{transform:v,transformOrigin:x}=zn(n).getComputedStyle(n);v&&(l=Z_(l,v,x))}const{top:s,left:c,width:u,height:f,bottom:p,right:g}=l;return{top:s,left:c,width:u,height:f,bottom:p,right:g}}function Ob(n){return Qs(n,{ignoreTransform:!0})}function W_(n){const a=n.innerWidth,l=n.innerHeight;return{top:0,left:0,right:a,bottom:l,width:a,height:l}}function e3(n,a){return a===void 0&&(a=zn(n).getComputedStyle(n)),a.position==="fixed"}function t3(n,a){a===void 0&&(a=zn(n).getComputedStyle(n));const l=/(auto|scroll|overlay)/;return["overflow","overflowX","overflowY"].some(c=>{const u=a[c];return typeof u=="string"?l.test(u):!1})}function Fu(n,a){const l=[];function s(c){if(a!=null&&l.length>=a||!c)return l;if(Ep(c)&&c.scrollingElement!=null&&!l.includes(c.scrollingElement))return l.push(c.scrollingElement),l;if(!gi(c)||nS(c)||l.includes(c))return l;const u=zn(n).getComputedStyle(c);return c!==n&&t3(c,u)&&l.push(c),e3(c,u)?l:s(c.parentNode)}return n?s(n):l}function cS(n){const[a]=Fu(n,1);return a??null}function kh(n){return!Xu||!n?null:Xs(n)?n:Cp(n)?Ep(n)||n===Fs(n).scrollingElement?window:gi(n)?n:null:null}function uS(n){return Xs(n)?n.scrollX:n.scrollLeft}function dS(n){return Xs(n)?n.scrollY:n.scrollTop}function hm(n){return{x:uS(n),y:dS(n)}}var Wt;(function(n){n[n.Forward=1]="Forward",n[n.Backward=-1]="Backward"})(Wt||(Wt={}));function fS(n){return!Xu||!n?!1:n===document.scrollingElement}function hS(n){const a={x:0,y:0},l=fS(n)?{height:window.innerHeight,width:window.innerWidth}:{height:n.clientHeight,width:n.clientWidth},s={x:n.scrollWidth-l.width,y:n.scrollHeight-l.height},c=n.scrollTop<=a.y,u=n.scrollLeft<=a.x,f=n.scrollTop>=s.y,p=n.scrollLeft>=s.x;return{isTop:c,isLeft:u,isBottom:f,isRight:p,maxScroll:s,minScroll:a}}const n3={x:.2,y:.2};function a3(n,a,l,s,c){let{top:u,left:f,right:p,bottom:g}=l;s===void 0&&(s=10),c===void 0&&(c=n3);const{isTop:v,isBottom:x,isLeft:y,isRight:b}=hS(n),w={x:0,y:0},E={x:0,y:0},j={height:a.height*c.y,width:a.width*c.x};return!v&&u<=a.top+j.height?(w.y=Wt.Backward,E.y=s*Math.abs((a.top+j.height-u)/j.height)):!x&&g>=a.bottom-j.height&&(w.y=Wt.Forward,E.y=s*Math.abs((a.bottom-j.height-g)/j.height)),!b&&p>=a.right-j.width?(w.x=Wt.Forward,E.x=s*Math.abs((a.right-j.width-p)/j.width)):!y&&f<=a.left+j.width&&(w.x=Wt.Backward,E.x=s*Math.abs((a.left+j.width-f)/j.width)),{direction:w,speed:E}}function r3(n){if(n===document.scrollingElement){const{innerWidth:u,innerHeight:f}=window;return{top:0,left:0,right:u,bottom:f,width:u,height:f}}const{top:a,left:l,right:s,bottom:c}=n.getBoundingClientRect();return{top:a,left:l,right:s,bottom:c,width:n.clientWidth,height:n.clientHeight}}function mS(n){return n.reduce((a,l)=>Us(a,hm(l)),Ea)}function l3(n){return n.reduce((a,l)=>a+uS(l),0)}function s3(n){return n.reduce((a,l)=>a+dS(l),0)}function o3(n,a){if(a===void 0&&(a=Qs),!n)return;const{top:l,left:s,bottom:c,right:u}=a(n);cS(n)&&(c<=0||u<=0||l>=window.innerHeight||s>=window.innerWidth)&&n.scrollIntoView({block:"center",inline:"center"})}const i3=[["x",["left","right"],l3],["y",["top","bottom"],s3]];class Tp{constructor(a,l){this.rect=void 0,this.width=void 0,this.height=void 0,this.top=void 0,this.bottom=void 0,this.right=void 0,this.left=void 0;const s=Fu(l),c=mS(s);this.rect={...a},this.width=a.width,this.height=a.height;for(const[u,f,p]of i3)for(const g of f)Object.defineProperty(this,g,{get:()=>{const v=p(s),x=c[u]-v;return this.rect[g]+x},enumerable:!0});Object.defineProperty(this,"rect",{enumerable:!1})}}class Xo{constructor(a){this.target=void 0,this.listeners=[],this.removeAll=()=>{this.listeners.forEach(l=>{var s;return(s=this.target)==null?void 0:s.removeEventListener(...l)})},this.target=a}add(a,l,s){var c;(c=this.target)==null||c.addEventListener(a,l,s),this.listeners.push([a,l,s])}}function c3(n){const{EventTarget:a}=zn(n);return n instanceof a?n:Fs(n)}function zh(n,a){const l=Math.abs(n.x),s=Math.abs(n.y);return typeof a=="number"?Math.sqrt(l**2+s**2)>a:"x"in a&&"y"in a?l>a.x&&s>a.y:"x"in a?l>a.x:"y"in a?s>a.y:!1}var la;(function(n){n.Click="click",n.DragStart="dragstart",n.Keydown="keydown",n.ContextMenu="contextmenu",n.Resize="resize",n.SelectionChange="selectionchange",n.VisibilityChange="visibilitychange"})(la||(la={}));function _b(n){n.preventDefault()}function u3(n){n.stopPropagation()}var Ke;(function(n){n.Space="Space",n.Down="ArrowDown",n.Right="ArrowRight",n.Left="ArrowLeft",n.Up="ArrowUp",n.Esc="Escape",n.Enter="Enter",n.Tab="Tab"})(Ke||(Ke={}));const pS={start:[Ke.Space,Ke.Enter],cancel:[Ke.Esc],end:[Ke.Space,Ke.Enter,Ke.Tab]},d3=(n,a)=>{let{currentCoordinates:l}=a;switch(n.code){case Ke.Right:return{...l,x:l.x+25};case Ke.Left:return{...l,x:l.x-25};case Ke.Down:return{...l,y:l.y+25};case Ke.Up:return{...l,y:l.y-25}}};class Mp{constructor(a){this.props=void 0,this.autoScrollEnabled=!1,this.referenceCoordinates=void 0,this.listeners=void 0,this.windowListeners=void 0,this.props=a;const{event:{target:l}}=a;this.props=a,this.listeners=new Xo(Fs(l)),this.windowListeners=new Xo(zn(l)),this.handleKeyDown=this.handleKeyDown.bind(this),this.handleCancel=this.handleCancel.bind(this),this.attach()}attach(){this.handleStart(),this.windowListeners.add(la.Resize,this.handleCancel),this.windowListeners.add(la.VisibilityChange,this.handleCancel),setTimeout(()=>this.listeners.add(la.Keydown,this.handleKeyDown))}handleStart(){const{activeNode:a,onStart:l}=this.props,s=a.node.current;s&&o3(s),l(Ea)}handleKeyDown(a){if(Np(a)){const{active:l,context:s,options:c}=this.props,{keyboardCodes:u=pS,coordinateGetter:f=d3,scrollBehavior:p="smooth"}=c,{code:g}=a;if(u.end.includes(g)){this.handleEnd(a);return}if(u.cancel.includes(g)){this.handleCancel(a);return}const{collisionRect:v}=s.current,x=v?{x:v.left,y:v.top}:Ea;this.referenceCoordinates||(this.referenceCoordinates=x);const y=f(a,{active:l,context:s.current,currentCoordinates:x});if(y){const b=ni(y,x),w={x:0,y:0},{scrollableAncestors:E}=s.current;for(const j of E){const C=a.code,{isTop:N,isRight:M,isLeft:T,isBottom:D,maxScroll:O,minScroll:A}=hS(j),U=r3(j),k={x:Math.min(C===Ke.Right?U.right-U.width/2:U.right,Math.max(C===Ke.Right?U.left:U.left+U.width/2,y.x)),y:Math.min(C===Ke.Down?U.bottom-U.height/2:U.bottom,Math.max(C===Ke.Down?U.top:U.top+U.height/2,y.y))},$=C===Ke.Right&&!M||C===Ke.Left&&!T,X=C===Ke.Down&&!D||C===Ke.Up&&!N;if($&&k.x!==y.x){const te=j.scrollLeft+b.x,G=C===Ke.Right&&te<=O.x||C===Ke.Left&&te>=A.x;if(G&&!b.y){j.scrollTo({left:te,behavior:p});return}G?w.x=j.scrollLeft-te:w.x=C===Ke.Right?j.scrollLeft-O.x:j.scrollLeft-A.x,w.x&&j.scrollBy({left:-w.x,behavior:p});break}else if(X&&k.y!==y.y){const te=j.scrollTop+b.y,G=C===Ke.Down&&te<=O.y||C===Ke.Up&&te>=A.y;if(G&&!b.x){j.scrollTo({top:te,behavior:p});return}G?w.y=j.scrollTop-te:w.y=C===Ke.Down?j.scrollTop-O.y:j.scrollTop-A.y,w.y&&j.scrollBy({top:-w.y,behavior:p});break}}this.handleMove(a,Us(ni(y,this.referenceCoordinates),w))}}}handleMove(a,l){const{onMove:s}=this.props;a.preventDefault(),s(l)}handleEnd(a){const{onEnd:l}=this.props;a.preventDefault(),this.detach(),l()}handleCancel(a){const{onCancel:l}=this.props;a.preventDefault(),this.detach(),l()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll()}}Mp.activators=[{eventName:"onKeyDown",handler:(n,a,l)=>{let{keyboardCodes:s=pS,onActivation:c}=a,{active:u}=l;const{code:f}=n.nativeEvent;if(s.start.includes(f)){const p=u.activatorNode.current;return p&&n.target!==p?!1:(n.preventDefault(),c==null||c({event:n.nativeEvent}),!0)}return!1}}];function kb(n){return!!(n&&"distance"in n)}function zb(n){return!!(n&&"delay"in n)}class Ap{constructor(a,l,s){var c;s===void 0&&(s=c3(a.event.target)),this.props=void 0,this.events=void 0,this.autoScrollEnabled=!0,this.document=void 0,this.activated=!1,this.initialCoordinates=void 0,this.timeoutId=null,this.listeners=void 0,this.documentListeners=void 0,this.windowListeners=void 0,this.props=a,this.events=l;const{event:u}=a,{target:f}=u;this.props=a,this.events=l,this.document=Fs(f),this.documentListeners=new Xo(this.document),this.listeners=new Xo(s),this.windowListeners=new Xo(zn(f)),this.initialCoordinates=(c=fm(u))!=null?c:Ea,this.handleStart=this.handleStart.bind(this),this.handleMove=this.handleMove.bind(this),this.handleEnd=this.handleEnd.bind(this),this.handleCancel=this.handleCancel.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.removeTextSelection=this.removeTextSelection.bind(this),this.attach()}attach(){const{events:a,props:{options:{activationConstraint:l,bypassActivationConstraint:s}}}=this;if(this.listeners.add(a.move.name,this.handleMove,{passive:!1}),this.listeners.add(a.end.name,this.handleEnd),a.cancel&&this.listeners.add(a.cancel.name,this.handleCancel),this.windowListeners.add(la.Resize,this.handleCancel),this.windowListeners.add(la.DragStart,_b),this.windowListeners.add(la.VisibilityChange,this.handleCancel),this.windowListeners.add(la.ContextMenu,_b),this.documentListeners.add(la.Keydown,this.handleKeydown),l){if(s!=null&&s({event:this.props.event,activeNode:this.props.activeNode,options:this.props.options}))return this.handleStart();if(zb(l)){this.timeoutId=setTimeout(this.handleStart,l.delay),this.handlePending(l);return}if(kb(l)){this.handlePending(l);return}}this.handleStart()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll(),setTimeout(this.documentListeners.removeAll,50),this.timeoutId!==null&&(clearTimeout(this.timeoutId),this.timeoutId=null)}handlePending(a,l){const{active:s,onPending:c}=this.props;c(s,a,this.initialCoordinates,l)}handleStart(){const{initialCoordinates:a}=this,{onStart:l}=this.props;a&&(this.activated=!0,this.documentListeners.add(la.Click,u3,{capture:!0}),this.removeTextSelection(),this.documentListeners.add(la.SelectionChange,this.removeTextSelection),l(a))}handleMove(a){var l;const{activated:s,initialCoordinates:c,props:u}=this,{onMove:f,options:{activationConstraint:p}}=u;if(!c)return;const g=(l=fm(a))!=null?l:Ea,v=ni(c,g);if(!s&&p){if(kb(p)){if(p.tolerance!=null&&zh(v,p.tolerance))return this.handleCancel();if(zh(v,p.distance))return this.handleStart()}if(zb(p)&&zh(v,p.tolerance))return this.handleCancel();this.handlePending(p,v);return}a.cancelable&&a.preventDefault(),f(g)}handleEnd(){const{onAbort:a,onEnd:l}=this.props;this.detach(),this.activated||a(this.props.active),l()}handleCancel(){const{onAbort:a,onCancel:l}=this.props;this.detach(),this.activated||a(this.props.active),l()}handleKeydown(a){a.code===Ke.Esc&&this.handleCancel()}removeTextSelection(){var a;(a=this.document.getSelection())==null||a.removeAllRanges()}}const f3={cancel:{name:"pointercancel"},move:{name:"pointermove"},end:{name:"pointerup"}};class Dp extends Ap{constructor(a){const{event:l}=a,s=Fs(l.target);super(a,f3,s)}}Dp.activators=[{eventName:"onPointerDown",handler:(n,a)=>{let{nativeEvent:l}=n,{onActivation:s}=a;return!l.isPrimary||l.button!==0?!1:(s==null||s({event:l}),!0)}}];const h3={move:{name:"mousemove"},end:{name:"mouseup"}};var mm;(function(n){n[n.RightClick=2]="RightClick"})(mm||(mm={}));class m3 extends Ap{constructor(a){super(a,h3,Fs(a.event.target))}}m3.activators=[{eventName:"onMouseDown",handler:(n,a)=>{let{nativeEvent:l}=n,{onActivation:s}=a;return l.button===mm.RightClick?!1:(s==null||s({event:l}),!0)}}];const Lh={cancel:{name:"touchcancel"},move:{name:"touchmove"},end:{name:"touchend"}};class p3 extends Ap{constructor(a){super(a,Lh)}static setup(){return window.addEventListener(Lh.move.name,a,{capture:!1,passive:!1}),function(){window.removeEventListener(Lh.move.name,a)};function a(){}}}p3.activators=[{eventName:"onTouchStart",handler:(n,a)=>{let{nativeEvent:l}=n,{onActivation:s}=a;const{touches:c}=l;return c.length>1?!1:(s==null||s({event:l}),!0)}}];var Fo;(function(n){n[n.Pointer=0]="Pointer",n[n.DraggableRect=1]="DraggableRect"})(Fo||(Fo={}));var mu;(function(n){n[n.TreeOrder=0]="TreeOrder",n[n.ReversedTreeOrder=1]="ReversedTreeOrder"})(mu||(mu={}));function g3(n){let{acceleration:a,activator:l=Fo.Pointer,canScroll:s,draggingRect:c,enabled:u,interval:f=5,order:p=mu.TreeOrder,pointerCoordinates:g,scrollableAncestors:v,scrollableAncestorRects:x,delta:y,threshold:b}=n;const w=x3({delta:y,disabled:!u}),[E,j]=T_(),C=m.useRef({x:0,y:0}),N=m.useRef({x:0,y:0}),M=m.useMemo(()=>{switch(l){case Fo.Pointer:return g?{top:g.y,bottom:g.y,left:g.x,right:g.x}:null;case Fo.DraggableRect:return c}},[l,c,g]),T=m.useRef(null),D=m.useCallback(()=>{const A=T.current;if(!A)return;const U=C.current.x*N.current.x,k=C.current.y*N.current.y;A.scrollBy(U,k)},[]),O=m.useMemo(()=>p===mu.TreeOrder?[...v].reverse():v,[p,v]);m.useEffect(()=>{if(!u||!v.length||!M){j();return}for(const A of O){if((s==null?void 0:s(A))===!1)continue;const U=v.indexOf(A),k=x[U];if(!k)continue;const{direction:$,speed:X}=a3(A,k,M,a,b);for(const te of["x","y"])w[te][$[te]]||(X[te]=0,$[te]=0);if(X.x>0||X.y>0){j(),T.current=A,E(D,f),C.current=X,N.current=$;return}}C.current={x:0,y:0},N.current={x:0,y:0},j()},[a,D,s,j,u,f,JSON.stringify(M),JSON.stringify(w),E,v,O,x,JSON.stringify(b)])}const v3={x:{[Wt.Backward]:!1,[Wt.Forward]:!1},y:{[Wt.Backward]:!1,[Wt.Forward]:!1}};function x3(n){let{delta:a,disabled:l}=n;const s=dm(a);return vi(c=>{if(l||!s||!c)return v3;const u={x:Math.sign(a.x-s.x),y:Math.sign(a.y-s.y)};return{x:{[Wt.Backward]:c.x[Wt.Backward]||u.x===-1,[Wt.Forward]:c.x[Wt.Forward]||u.x===1},y:{[Wt.Backward]:c.y[Wt.Backward]||u.y===-1,[Wt.Forward]:c.y[Wt.Forward]||u.y===1}}},[l,a,s])}function y3(n,a){const l=a!=null?n.get(a):void 0,s=l?l.node.current:null;return vi(c=>{var u;return a==null?null:(u=s??c)!=null?u:null},[s,a])}function b3(n,a){return m.useMemo(()=>n.reduce((l,s)=>{const{sensor:c}=s,u=c.activators.map(f=>({eventName:f.eventName,handler:a(f.handler,s)}));return[...l,...u]},[]),[n,a])}var ai;(function(n){n[n.Always=0]="Always",n[n.BeforeDragging=1]="BeforeDragging",n[n.WhileDragging=2]="WhileDragging"})(ai||(ai={}));var pm;(function(n){n.Optimized="optimized"})(pm||(pm={}));const Lb=new Map;function w3(n,a){let{dragging:l,dependencies:s,config:c}=a;const[u,f]=m.useState(null),{frequency:p,measure:g,strategy:v}=c,x=m.useRef(n),y=C(),b=ti(y),w=m.useCallback(function(N){N===void 0&&(N=[]),!b.current&&f(M=>M===null?N:M.concat(N.filter(T=>!M.includes(T))))},[b]),E=m.useRef(null),j=vi(N=>{if(y&&!l)return Lb;if(!N||N===Lb||x.current!==n||u!=null){const M=new Map;for(let T of n){if(!T)continue;if(u&&u.length>0&&!u.includes(T.id)&&T.rect.current){M.set(T.id,T.rect.current);continue}const D=T.node.current,O=D?new Tp(g(D),D):null;T.rect.current=O,O&&M.set(T.id,O)}return M}return N},[n,u,l,y,g]);return m.useEffect(()=>{x.current=n},[n]),m.useEffect(()=>{y||w()},[l,y]),m.useEffect(()=>{u&&u.length>0&&f(null)},[JSON.stringify(u)]),m.useEffect(()=>{y||typeof p!="number"||E.current!==null||(E.current=setTimeout(()=>{w(),E.current=null},p))},[p,y,w,...s]),{droppableRects:j,measureDroppableContainers:w,measuringScheduled:u!=null};function C(){switch(v){case ai.Always:return!1;case ai.BeforeDragging:return l;default:return!l}}}function gS(n,a){return vi(l=>n?l||(typeof a=="function"?a(n):n):null,[a,n])}function S3(n,a){return gS(n,a)}function j3(n){let{callback:a,disabled:l}=n;const s=Rp(a),c=m.useMemo(()=>{if(l||typeof window>"u"||typeof window.MutationObserver>"u")return;const{MutationObserver:u}=window;return new u(s)},[s,l]);return m.useEffect(()=>()=>c==null?void 0:c.disconnect(),[c]),c}function Qu(n){let{callback:a,disabled:l}=n;const s=Rp(a),c=m.useMemo(()=>{if(l||typeof window>"u"||typeof window.ResizeObserver>"u")return;const{ResizeObserver:u}=window;return new u(s)},[l]);return m.useEffect(()=>()=>c==null?void 0:c.disconnect(),[c]),c}function C3(n){return new Tp(Qs(n),n)}function Ub(n,a,l){a===void 0&&(a=C3);const[s,c]=m.useState(null);function u(){c(g=>{if(!n)return null;if(n.isConnected===!1){var v;return(v=g??l)!=null?v:null}const x=a(n);return JSON.stringify(g)===JSON.stringify(x)?g:x})}const f=j3({callback(g){if(n)for(const v of g){const{type:x,target:y}=v;if(x==="childList"&&y instanceof HTMLElement&&y.contains(n)){u();break}}}}),p=Qu({callback:u});return qa(()=>{u(),n?(p==null||p.observe(n),f==null||f.observe(document.body,{childList:!0,subtree:!0})):(p==null||p.disconnect(),f==null||f.disconnect())},[n]),s}function E3(n){const a=gS(n);return iS(n,a)}const Bb=[];function R3(n){const a=m.useRef(n),l=vi(s=>n?s&&s!==Bb&&n&&a.current&&n.parentNode===a.current.parentNode?s:Fu(n):Bb,[n]);return m.useEffect(()=>{a.current=n},[n]),l}function N3(n){const[a,l]=m.useState(null),s=m.useRef(n),c=m.useCallback(u=>{const f=kh(u.target);f&&l(p=>p?(p.set(f,hm(f)),new Map(p)):null)},[]);return m.useEffect(()=>{const u=s.current;if(n!==u){f(u);const p=n.map(g=>{const v=kh(g);return v?(v.addEventListener("scroll",c,{passive:!0}),[v,hm(v)]):null}).filter(g=>g!=null);l(p.length?new Map(p):null),s.current=n}return()=>{f(n),f(u)};function f(p){p.forEach(g=>{const v=kh(g);v==null||v.removeEventListener("scroll",c)})}},[c,n]),m.useMemo(()=>n.length?a?Array.from(a.values()).reduce((u,f)=>Us(u,f),Ea):mS(n):Ea,[n,a])}function Hb(n,a){a===void 0&&(a=[]);const l=m.useRef(null);return m.useEffect(()=>{l.current=null},a),m.useEffect(()=>{const s=n!==Ea;s&&!l.current&&(l.current=n),!s&&l.current&&(l.current=null)},[n]),l.current?ni(n,l.current):Ea}function T3(n){m.useEffect(()=>{if(!Xu)return;const a=n.map(l=>{let{sensor:s}=l;return s.setup==null?void 0:s.setup()});return()=>{for(const l of a)l==null||l()}},n.map(a=>{let{sensor:l}=a;return l}))}function M3(n,a){return m.useMemo(()=>n.reduce((l,s)=>{let{eventName:c,handler:u}=s;return l[c]=f=>{u(f,a)},l},{}),[n,a])}function vS(n){return m.useMemo(()=>n?W_(n):null,[n])}const Ib=[];function A3(n,a){a===void 0&&(a=Qs);const[l]=n,s=vS(l?zn(l):null),[c,u]=m.useState(Ib);function f(){u(()=>n.length?n.map(g=>fS(g)?s:new Tp(a(g),g)):Ib)}const p=Qu({callback:f});return qa(()=>{p==null||p.disconnect(),f(),n.forEach(g=>p==null?void 0:p.observe(g))},[n]),c}function D3(n){if(!n)return null;if(n.children.length>1)return n;const a=n.children[0];return gi(a)?a:n}function O3(n){let{measure:a}=n;const[l,s]=m.useState(null),c=m.useCallback(v=>{for(const{target:x}of v)if(gi(x)){s(y=>{const b=a(x);return y?{...y,width:b.width,height:b.height}:b});break}},[a]),u=Qu({callback:c}),f=m.useCallback(v=>{const x=D3(v);u==null||u.disconnect(),x&&(u==null||u.observe(x)),s(x?a(x):null)},[a,u]),[p,g]=du(f);return m.useMemo(()=>({nodeRef:p,rect:l,setRef:g}),[l,p,g])}const _3=[{sensor:Dp,options:{}},{sensor:Mp,options:{}}],k3={current:{}},eu={draggable:{measure:Ob},droppable:{measure:Ob,strategy:ai.WhileDragging,frequency:pm.Optimized},dragOverlay:{measure:Qs}};class Qo extends Map{get(a){var l;return a!=null&&(l=super.get(a))!=null?l:void 0}toArray(){return Array.from(this.values())}getEnabled(){return this.toArray().filter(a=>{let{disabled:l}=a;return!l})}getNodeFor(a){var l,s;return(l=(s=this.get(a))==null?void 0:s.node.current)!=null?l:void 0}}const z3={activatorEvent:null,active:null,activeNode:null,activeNodeRect:null,collisions:null,containerNodeRect:null,draggableNodes:new Map,droppableRects:new Map,droppableContainers:new Qo,over:null,dragOverlay:{nodeRef:{current:null},rect:null,setRef:hu},scrollableAncestors:[],scrollableAncestorRects:[],measuringConfiguration:eu,measureDroppableContainers:hu,windowRect:null,measuringScheduled:!1},L3={activatorEvent:null,activators:[],active:null,activeNodeRect:null,ariaDescribedById:{draggable:""},dispatch:hu,draggableNodes:new Map,over:null,measureDroppableContainers:hu},Zu=m.createContext(L3),xS=m.createContext(z3);function U3(){return{draggable:{active:null,initialCoordinates:{x:0,y:0},nodes:new Map,translate:{x:0,y:0}},droppable:{containers:new Qo}}}function B3(n,a){switch(a.type){case Gt.DragStart:return{...n,draggable:{...n.draggable,initialCoordinates:a.initialCoordinates,active:a.active}};case Gt.DragMove:return n.draggable.active==null?n:{...n,draggable:{...n.draggable,translate:{x:a.coordinates.x-n.draggable.initialCoordinates.x,y:a.coordinates.y-n.draggable.initialCoordinates.y}}};case Gt.DragEnd:case Gt.DragCancel:return{...n,draggable:{...n.draggable,active:null,initialCoordinates:{x:0,y:0},translate:{x:0,y:0}}};case Gt.RegisterDroppable:{const{element:l}=a,{id:s}=l,c=new Qo(n.droppable.containers);return c.set(s,l),{...n,droppable:{...n.droppable,containers:c}}}case Gt.SetDroppableDisabled:{const{id:l,key:s,disabled:c}=a,u=n.droppable.containers.get(l);if(!u||s!==u.key)return n;const f=new Qo(n.droppable.containers);return f.set(l,{...u,disabled:c}),{...n,droppable:{...n.droppable,containers:f}}}case Gt.UnregisterDroppable:{const{id:l,key:s}=a,c=n.droppable.containers.get(l);if(!c||s!==c.key)return n;const u=new Qo(n.droppable.containers);return u.delete(l),{...n,droppable:{...n.droppable,containers:u}}}default:return n}}function H3(n){let{disabled:a}=n;const{active:l,activatorEvent:s,draggableNodes:c}=m.useContext(Zu),u=dm(s),f=dm(l==null?void 0:l.id);return m.useEffect(()=>{if(!a&&!s&&u&&f!=null){if(!Np(u)||document.activeElement===u.target)return;const p=c.get(f);if(!p)return;const{activatorNode:g,node:v}=p;if(!g.current&&!v.current)return;requestAnimationFrame(()=>{for(const x of[g.current,v.current]){if(!x)continue;const y=D_(x);if(y){y.focus();break}}})}},[s,a,c,f,u]),null}function I3(n,a){let{transform:l,...s}=a;return n!=null&&n.length?n.reduce((c,u)=>u({transform:c,...s}),l):l}function P3(n){return m.useMemo(()=>({draggable:{...eu.draggable,...n==null?void 0:n.draggable},droppable:{...eu.droppable,...n==null?void 0:n.droppable},dragOverlay:{...eu.dragOverlay,...n==null?void 0:n.dragOverlay}}),[n==null?void 0:n.draggable,n==null?void 0:n.droppable,n==null?void 0:n.dragOverlay])}function q3(n){let{activeNode:a,measure:l,initialRect:s,config:c=!0}=n;const u=m.useRef(!1),{x:f,y:p}=typeof c=="boolean"?{x:c,y:c}:c;qa(()=>{if(!f&&!p||!a){u.current=!1;return}if(u.current||!s)return;const v=a==null?void 0:a.node.current;if(!v||v.isConnected===!1)return;const x=l(v),y=iS(x,s);if(f||(y.x=0),p||(y.y=0),u.current=!0,Math.abs(y.x)>0||Math.abs(y.y)>0){const b=cS(v);b&&b.scrollBy({top:y.y,left:y.x})}},[a,f,p,s,l])}const yS=m.createContext({...Ea,scaleX:1,scaleY:1});var al;(function(n){n[n.Uninitialized=0]="Uninitialized",n[n.Initializing=1]="Initializing",n[n.Initialized=2]="Initialized"})(al||(al={}));const V3=m.memo(function(a){var l,s,c,u;let{id:f,accessibility:p,autoScroll:g=!0,children:v,sensors:x=_3,collisionDetection:y=G_,measuring:b,modifiers:w,...E}=a;const j=m.useReducer(B3,void 0,U3),[C,N]=j,[M,T]=U_(),[D,O]=m.useState(al.Uninitialized),A=D===al.Initialized,{draggable:{active:U,nodes:k,translate:$},droppable:{containers:X}}=C,te=U!=null?k.get(U):null,G=m.useRef({initial:null,translated:null}),ie=m.useMemo(()=>{var vt;return U!=null?{id:U,data:(vt=te==null?void 0:te.data)!=null?vt:k3,rect:G}:null},[U,te]),ce=m.useRef(null),[se,_]=m.useState(null),[H,Q]=m.useState(null),J=ti(E,Object.values(E)),ee=xi("DndDescribedBy",f),z=m.useMemo(()=>X.getEnabled(),[X]),I=P3(b),{droppableRects:F,measureDroppableContainers:re,measuringScheduled:he}=w3(z,{dragging:A,dependencies:[$.x,$.y],config:I.droppable}),ge=y3(k,U),q=m.useMemo(()=>H?fm(H):null,[H]),oe=Nr(),de=S3(ge,I.draggable.measure);q3({activeNode:U!=null?k.get(U):null,config:oe.layoutShiftCompensation,initialRect:de,measure:I.draggable.measure});const fe=Ub(ge,I.draggable.measure,de),Te=Ub(ge?ge.parentElement:null),je=m.useRef({activatorEvent:null,active:null,activeNode:ge,collisionRect:null,collisions:null,droppableRects:F,draggableNodes:k,draggingNode:null,draggingNodeRect:null,droppableContainers:X,over:null,scrollableAncestors:[],scrollAdjustedTranslate:null}),De=X.getNodeFor((l=je.current.over)==null?void 0:l.id),Fe=O3({measure:I.dragOverlay.measure}),et=(s=Fe.nodeRef.current)!=null?s:ge,le=A?(c=Fe.rect)!=null?c:fe:null,Le=!!(Fe.nodeRef.current&&Fe.rect),Ie=E3(Le?null:fe),kt=vS(et?zn(et):null),St=R3(A?De??ge:null),Ft=A3(St),on=I3(w,{transform:{x:$.x-Ie.x,y:$.y-Ie.y,scaleX:1,scaleY:1},activatorEvent:H,active:ie,activeNodeRect:fe,containerNodeRect:Te,draggingNodeRect:le,over:je.current.over,overlayNodeRect:Fe.rect,scrollableAncestors:St,scrollableAncestorRects:Ft,windowRect:kt}),Qt=q?Us(q,$):null,jt=N3(St),fn=Hb(jt),Mt=Hb(jt,[fe]),At=Us(on,fn),cn=le?F_(le,on):null,fa=ie&&cn?y({active:ie,collisionRect:cn,droppableRects:F,droppableContainers:z,pointerCoordinates:Qt}):null,Ta=oS(fa,"id"),[Gn,dl]=m.useState(null),ha=Le?on:Us(on,Mt),Dt=K_(ha,(u=Gn==null?void 0:Gn.rect)!=null?u:null,fe),hn=m.useRef(null),Tt=m.useCallback((vt,st)=>{let{sensor:Bt,options:Ce}=st;if(ce.current==null)return;const ke=k.get(ce.current);if(!ke)return;const Ue=vt.nativeEvent,gt=new Bt({active:ce.current,activeNode:ke,event:Ue,options:Ce,context:je,onAbort(ct){if(!k.get(ct))return;const{onDragAbort:xt}=J.current,zt={id:ct};xt==null||xt(zt),M({type:"onDragAbort",event:zt})},onPending(ct,$t,xt,zt){if(!k.get(ct))return;const{onDragPending:Ka}=J.current,ma={id:ct,constraint:$t,initialCoordinates:xt,offset:zt};Ka==null||Ka(ma),M({type:"onDragPending",event:ma})},onStart(ct){const $t=ce.current;if($t==null)return;const xt=k.get($t);if(!xt)return;const{onDragStart:zt}=J.current,Ga={activatorEvent:Ue,active:{id:$t,data:xt.data,rect:G}};ba.unstable_batchedUpdates(()=>{zt==null||zt(Ga),O(al.Initializing),N({type:Gt.DragStart,initialCoordinates:ct,active:$t}),M({type:"onDragStart",event:Ga}),_(hn.current),Q(Ue)})},onMove(ct){N({type:Gt.DragMove,coordinates:ct})},onEnd:Ct(Gt.DragEnd),onCancel:Ct(Gt.DragCancel)});hn.current=gt;function Ct(ct){return async function(){const{active:xt,collisions:zt,over:Ga,scrollAdjustedTranslate:Ka}=je.current;let ma=null;if(xt&&Ka){const{cancelDrop:Tr}=J.current;ma={activatorEvent:Ue,active:xt,collisions:zt,delta:Ka,over:Ga},ct===Gt.DragEnd&&typeof Tr=="function"&&await Promise.resolve(Tr(ma))&&(ct=Gt.DragCancel)}ce.current=null,ba.unstable_batchedUpdates(()=>{N({type:ct}),O(al.Uninitialized),dl(null),_(null),Q(null),hn.current=null;const Tr=ct===Gt.DragEnd?"onDragEnd":"onDragCancel";if(ma){const Kn=J.current[Tr];Kn==null||Kn(ma),M({type:Tr,event:ma})}})}}},[k]),Js=m.useCallback((vt,st)=>(Bt,Ce)=>{const ke=Bt.nativeEvent,Ue=k.get(Ce);if(ce.current!==null||!Ue||ke.dndKit||ke.defaultPrevented)return;const gt={active:Ue};vt(Bt,st.options,gt)===!0&&(ke.dndKit={capturedBy:st.sensor},ce.current=Ce,Tt(Bt,st))},[k,Tt]),Pl=b3(x,Js);T3(x),qa(()=>{fe&&D===al.Initializing&&O(al.Initialized)},[fe,D]),m.useEffect(()=>{const{onDragMove:vt}=J.current,{active:st,activatorEvent:Bt,collisions:Ce,over:ke}=je.current;if(!st||!Bt)return;const Ue={active:st,activatorEvent:Bt,collisions:Ce,delta:{x:At.x,y:At.y},over:ke};ba.unstable_batchedUpdates(()=>{vt==null||vt(Ue),M({type:"onDragMove",event:Ue})})},[At.x,At.y]),m.useEffect(()=>{const{active:vt,activatorEvent:st,collisions:Bt,droppableContainers:Ce,scrollAdjustedTranslate:ke}=je.current;if(!vt||ce.current==null||!st||!ke)return;const{onDragOver:Ue}=J.current,gt=Ce.get(Ta),Ct=gt&>.rect.current?{id:gt.id,rect:gt.rect.current,data:gt.data,disabled:gt.disabled}:null,ct={active:vt,activatorEvent:st,collisions:Bt,delta:{x:ke.x,y:ke.y},over:Ct};ba.unstable_batchedUpdates(()=>{dl(Ct),Ue==null||Ue(ct),M({type:"onDragOver",event:ct})})},[Ta]),qa(()=>{je.current={activatorEvent:H,active:ie,activeNode:ge,collisionRect:cn,collisions:fa,droppableRects:F,draggableNodes:k,draggingNode:et,draggingNodeRect:le,droppableContainers:X,over:Gn,scrollableAncestors:St,scrollAdjustedTranslate:At},G.current={initial:le,translated:cn}},[ie,ge,fa,cn,k,et,le,F,X,Gn,St,At]),g3({...oe,delta:$,draggingRect:cn,pointerCoordinates:Qt,scrollableAncestors:St,scrollableAncestorRects:Ft});const ql=m.useMemo(()=>({active:ie,activeNode:ge,activeNodeRect:fe,activatorEvent:H,collisions:fa,containerNodeRect:Te,dragOverlay:Fe,draggableNodes:k,droppableContainers:X,droppableRects:F,over:Gn,measureDroppableContainers:re,scrollableAncestors:St,scrollableAncestorRects:Ft,measuringConfiguration:I,measuringScheduled:he,windowRect:kt}),[ie,ge,fe,H,fa,Te,Fe,k,X,F,Gn,re,St,Ft,I,he,kt]),Ya=m.useMemo(()=>({activatorEvent:H,activators:Pl,active:ie,activeNodeRect:fe,ariaDescribedById:{draggable:ee},dispatch:N,draggableNodes:k,over:Gn,measureDroppableContainers:re}),[H,Pl,ie,fe,N,ee,k,Gn,re]);return ue.createElement(rS.Provider,{value:T},ue.createElement(Zu.Provider,{value:Ya},ue.createElement(xS.Provider,{value:ql},ue.createElement(yS.Provider,{value:Dt},v)),ue.createElement(H3,{disabled:(p==null?void 0:p.restoreFocus)===!1})),ue.createElement(I_,{...p,hiddenTextDescribedById:ee}));function Nr(){const vt=(se==null?void 0:se.autoScrollEnabled)===!1,st=typeof g=="object"?g.enabled===!1:g===!1,Bt=A&&!vt&&!st;return typeof g=="object"?{...g,enabled:Bt}:{enabled:Bt}}}),$3=m.createContext(null),Pb="button",Y3="Draggable";function G3(n){let{id:a,data:l,disabled:s=!1,attributes:c}=n;const u=xi(Y3),{activators:f,activatorEvent:p,active:g,activeNodeRect:v,ariaDescribedById:x,draggableNodes:y,over:b}=m.useContext(Zu),{role:w=Pb,roleDescription:E="draggable",tabIndex:j=0}=c??{},C=(g==null?void 0:g.id)===a,N=m.useContext(C?yS:$3),[M,T]=du(),[D,O]=du(),A=M3(f,a),U=ti(l);qa(()=>(y.set(a,{id:a,key:u,node:M,activatorNode:D,data:U}),()=>{const $=y.get(a);$&&$.key===u&&y.delete(a)}),[y,a]);const k=m.useMemo(()=>({role:w,tabIndex:j,"aria-disabled":s,"aria-pressed":C&&w===Pb?!0:void 0,"aria-roledescription":E,"aria-describedby":x.draggable}),[s,w,j,C,E,x.draggable]);return{active:g,activatorEvent:p,activeNodeRect:v,attributes:k,isDragging:C,listeners:s?void 0:A,node:M,over:b,setNodeRef:T,setActivatorNodeRef:O,transform:N}}function K3(){return m.useContext(xS)}const X3="Droppable",F3={timeout:25};function Q3(n){let{data:a,disabled:l=!1,id:s,resizeObserverConfig:c}=n;const u=xi(X3),{active:f,dispatch:p,over:g,measureDroppableContainers:v}=m.useContext(Zu),x=m.useRef({disabled:l}),y=m.useRef(!1),b=m.useRef(null),w=m.useRef(null),{disabled:E,updateMeasurementsFor:j,timeout:C}={...F3,...c},N=ti(j??s),M=m.useCallback(()=>{if(!y.current){y.current=!0;return}w.current!=null&&clearTimeout(w.current),w.current=setTimeout(()=>{v(Array.isArray(N.current)?N.current:[N.current]),w.current=null},C)},[C]),T=Qu({callback:M,disabled:E||!f}),D=m.useCallback((k,$)=>{T&&($&&(T.unobserve($),y.current=!1),k&&T.observe(k))},[T]),[O,A]=du(D),U=ti(a);return m.useEffect(()=>{!T||!O.current||(T.disconnect(),y.current=!1,T.observe(O.current))},[O,T]),m.useEffect(()=>(p({type:Gt.RegisterDroppable,element:{id:s,key:u,disabled:l,node:O,rect:b,data:U}}),()=>p({type:Gt.UnregisterDroppable,key:u,id:s})),[s]),m.useEffect(()=>{l!==x.current.disabled&&(p({type:Gt.SetDroppableDisabled,id:s,key:u,disabled:l}),x.current.disabled=l)},[s,u,l,p]),{active:f,rect:b,isOver:(g==null?void 0:g.id)===s,node:O,over:g,setNodeRef:A}}function Z3(n,a,l){const s={...n};return a.top+n.y<=l.top?s.y=l.top-a.top:a.bottom+n.y>=l.top+l.height&&(s.y=l.top+l.height-a.bottom),a.left+n.x<=l.left?s.x=l.left-a.left:a.right+n.x>=l.left+l.width&&(s.x=l.left+l.width-a.right),s}const J3=n=>{let{containerNodeRect:a,draggingNodeRect:l,transform:s}=n;return!l||!a?s:Z3(s,l,a)},W3=n=>{let{transform:a}=n;return{...a,x:0}};function Op(n,a,l){const s=n.slice();return s.splice(l<0?s.length+l:l,0,s.splice(a,1)[0]),s}function ek(n,a){return n.reduce((l,s,c)=>{const u=a.get(s);return u&&(l[c]=u),l},Array(n.length))}function Pc(n){return n!==null&&n>=0}function tk(n,a){if(n===a)return!0;if(n.length!==a.length)return!1;for(let l=0;l<n.length;l++)if(n[l]!==a[l])return!1;return!0}function nk(n){return typeof n=="boolean"?{draggable:n,droppable:n}:n}const bS=n=>{let{rects:a,activeIndex:l,overIndex:s,index:c}=n;const u=Op(a,s,l),f=a[c],p=u[c];return!p||!f?null:{x:p.left-f.left,y:p.top-f.top,scaleX:p.width/f.width,scaleY:p.height/f.height}},qc={scaleX:1,scaleY:1},ak=n=>{var a;let{activeIndex:l,activeNodeRect:s,index:c,rects:u,overIndex:f}=n;const p=(a=u[l])!=null?a:s;if(!p)return null;if(c===l){const v=u[f];return v?{x:0,y:l<f?v.top+v.height-(p.top+p.height):v.top-p.top,...qc}:null}const g=rk(u,c,l);return c>l&&c<=f?{x:0,y:-p.height-g,...qc}:c<l&&c>=f?{x:0,y:p.height+g,...qc}:{x:0,y:0,...qc}};function rk(n,a,l){const s=n[a],c=n[a-1],u=n[a+1];return s?l<a?c?s.top-(c.top+c.height):u?u.top-(s.top+s.height):0:u?u.top-(s.top+s.height):c?s.top-(c.top+c.height):0:0}const wS="Sortable",SS=ue.createContext({activeIndex:-1,containerId:wS,disableTransforms:!1,items:[],overIndex:-1,useDragOverlay:!1,sortedRects:[],strategy:bS,disabled:{draggable:!1,droppable:!1}});function lk(n){let{children:a,id:l,items:s,strategy:c=bS,disabled:u=!1}=n;const{active:f,dragOverlay:p,droppableRects:g,over:v,measureDroppableContainers:x}=K3(),y=xi(wS,l),b=p.rect!==null,w=m.useMemo(()=>s.map(A=>typeof A=="object"&&"id"in A?A.id:A),[s]),E=f!=null,j=f?w.indexOf(f.id):-1,C=v?w.indexOf(v.id):-1,N=m.useRef(w),M=!tk(w,N.current),T=C!==-1&&j===-1||M,D=nk(u);qa(()=>{M&&E&&x(w)},[M,w,E,x]),m.useEffect(()=>{N.current=w},[w]);const O=m.useMemo(()=>({activeIndex:j,containerId:y,disabled:D,disableTransforms:T,items:w,overIndex:C,useDragOverlay:b,sortedRects:ek(w,g),strategy:c}),[j,y,D.draggable,D.droppable,T,w,C,g,b,c]);return ue.createElement(SS.Provider,{value:O},a)}const sk=n=>{let{id:a,items:l,activeIndex:s,overIndex:c}=n;return Op(l,s,c).indexOf(a)},ok=n=>{let{containerId:a,isSorting:l,wasDragging:s,index:c,items:u,newIndex:f,previousItems:p,previousContainerId:g,transition:v}=n;return!v||!s||p!==u&&c===f?!1:l?!0:f!==c&&a===g},ik={duration:200,easing:"ease"},jS="transform",ck=fu.Transition.toString({property:jS,duration:0,easing:"linear"}),uk={roleDescription:"sortable"};function dk(n){let{disabled:a,index:l,node:s,rect:c}=n;const[u,f]=m.useState(null),p=m.useRef(l);return qa(()=>{if(!a&&l!==p.current&&s.current){const g=c.current;if(g){const v=Qs(s.current,{ignoreTransform:!0}),x={x:g.left-v.left,y:g.top-v.top,scaleX:g.width/v.width,scaleY:g.height/v.height};(x.x||x.y)&&f(x)}}l!==p.current&&(p.current=l)},[a,l,s,c]),m.useEffect(()=>{u&&f(null)},[u]),u}function fk(n){let{animateLayoutChanges:a=ok,attributes:l,disabled:s,data:c,getNewIndex:u=sk,id:f,strategy:p,resizeObserverConfig:g,transition:v=ik}=n;const{items:x,containerId:y,activeIndex:b,disabled:w,disableTransforms:E,sortedRects:j,overIndex:C,useDragOverlay:N,strategy:M}=m.useContext(SS),T=hk(s,w),D=x.indexOf(f),O=m.useMemo(()=>({sortable:{containerId:y,index:D,items:x},...c}),[y,c,D,x]),A=m.useMemo(()=>x.slice(x.indexOf(f)),[x,f]),{rect:U,node:k,isOver:$,setNodeRef:X}=Q3({id:f,data:O,disabled:T.droppable,resizeObserverConfig:{updateMeasurementsFor:A,...g}}),{active:te,activatorEvent:G,activeNodeRect:ie,attributes:ce,setNodeRef:se,listeners:_,isDragging:H,over:Q,setActivatorNodeRef:J,transform:ee}=G3({id:f,data:O,attributes:{...uk,...l},disabled:T.draggable}),z=N_(X,se),I=!!te,F=I&&!E&&Pc(b)&&Pc(C),re=!N&&H,he=re&&F?ee:null,q=F?he??(p??M)({rects:j,activeNodeRect:ie,activeIndex:b,overIndex:C,index:D}):null,oe=Pc(b)&&Pc(C)?u({id:f,items:x,activeIndex:b,overIndex:C}):D,de=te==null?void 0:te.id,fe=m.useRef({activeId:de,items:x,newIndex:oe,containerId:y}),Te=x!==fe.current.items,je=a({active:te,containerId:y,isDragging:H,isSorting:I,id:f,index:D,items:x,newIndex:fe.current.newIndex,previousItems:fe.current.items,previousContainerId:fe.current.containerId,transition:v,wasDragging:fe.current.activeId!=null}),De=dk({disabled:!je,index:D,node:k,rect:U});return m.useEffect(()=>{I&&fe.current.newIndex!==oe&&(fe.current.newIndex=oe),y!==fe.current.containerId&&(fe.current.containerId=y),x!==fe.current.items&&(fe.current.items=x)},[I,oe,y,x]),m.useEffect(()=>{if(de===fe.current.activeId)return;if(de!=null&&fe.current.activeId==null){fe.current.activeId=de;return}const et=setTimeout(()=>{fe.current.activeId=de},50);return()=>clearTimeout(et)},[de]),{active:te,activeIndex:b,attributes:ce,data:O,rect:U,index:D,newIndex:oe,items:x,isOver:$,isSorting:I,isDragging:H,listeners:_,node:k,overIndex:C,over:Q,setNodeRef:z,setActivatorNodeRef:J,setDroppableNodeRef:X,setDraggableNodeRef:se,transform:De??q,transition:Fe()};function Fe(){if(De||Te&&fe.current.newIndex===D)return ck;if(!(re&&!Np(G)||!v)&&(I||je))return fu.Transition.toString({...v,property:jS})}}function hk(n,a){var l,s;return typeof n=="boolean"?{draggable:n,droppable:!1}:{draggable:(l=n==null?void 0:n.draggable)!=null?l:a.draggable,droppable:(s=n==null?void 0:n.droppable)!=null?s:a.droppable}}function pu(n){if(!n)return!1;const a=n.data.current;return!!(a&&"sortable"in a&&typeof a.sortable=="object"&&"containerId"in a.sortable&&"items"in a.sortable&&"index"in a.sortable)}const mk=[Ke.Down,Ke.Right,Ke.Up,Ke.Left],pk=(n,a)=>{let{context:{active:l,collisionRect:s,droppableRects:c,droppableContainers:u,over:f,scrollableAncestors:p}}=a;if(mk.includes(n.code)){if(n.preventDefault(),!l||!s)return;const g=[];u.getEnabled().forEach(y=>{if(!y||y!=null&&y.disabled)return;const b=c.get(y.id);if(b)switch(n.code){case Ke.Down:s.top<b.top&&g.push(y);break;case Ke.Up:s.top>b.top&&g.push(y);break;case Ke.Left:s.left>b.left&&g.push(y);break;case Ke.Right:s.left<b.left&&g.push(y);break}});const v=$_({collisionRect:s,droppableRects:c,droppableContainers:g});let x=oS(v,"id");if(x===(f==null?void 0:f.id)&&v.length>1&&(x=v[1].id),x!=null){const y=u.get(l.id),b=u.get(x),w=b?c.get(b.id):null,E=b==null?void 0:b.node.current;if(E&&w&&y&&b){const C=Fu(E).some((A,U)=>p[U]!==A),N=CS(y,b),M=gk(y,b),T=C||!N?{x:0,y:0}:{x:M?s.width-w.width:0,y:M?s.height-w.height:0},D={x:w.left,y:w.top};return T.x&&T.y?D:ni(D,T)}}}};function CS(n,a){return!pu(n)||!pu(a)?!1:n.data.current.sortable.containerId===a.data.current.sortable.containerId}function gk(n,a){return!pu(n)||!pu(a)||!CS(n,a)?!1:n.data.current.sortable.index<a.data.current.sortable.index}const Uh={maxTotalAttempts:3,fallbackOnConnection:!0,fallbackOnConnectTimeout:!0,fallbackOnFirstTokenTimeout:!0,fallbackOn408:!0,fallbackOn429:!0,fallbackOn5xx:!0},vk={member_disabled:"member disabled",model_missing:"model missing",provider_disabled:"provider disabled",provider_down:"provider down",model_disabled:"model disabled",upstream_unavailable:"upstream unavailable",circuit_open:"circuit open",chat_capability_unavailable:"chat capability unavailable"},gu=n=>n.map((a,l)=>({...a,position:l}));function xk(){const[n,a]=m.useState([]),[l,s]=m.useState([]),[c,u]=m.useState(!1),[f,p]=m.useState(!1),[g,v]=m.useState(null),[x,y]=m.useState(!1),[b,w]=m.useState(!1),[E,j]=m.useState(null),[C,N]=m.useState(null),[M,T]=m.useState({name:"",slug:"",enabled:!0,...Uh,members:[]}),[D,O]=m.useState({name:"",slug:"",enabled:!0,...Uh,members:[]}),[A,U]=m.useState(null),k=async()=>{const[_,H]=await Promise.all([Se.get("/api/admin/combos"),Se.get("/api/admin/models")]);a(_.combos),s(H.models)};m.useEffect(()=>{k()},[]);const $=async _=>{j(_.id);try{N(await Se.post("/api/admin/combos/"+_.id+"/test"))}catch(H){ve.error(H.message)}finally{j(null)}},X=async()=>{if(M.members.length===0){ve.error("Add at least one member");return}y(!0);try{await Se.post("/api/admin/combos",{name:M.name,slug:M.slug.trim()||void 0,enabled:M.enabled,...M,members:M.members}),ve.success("Combo created"),u(!1),T({name:"",slug:"",enabled:!0,...Uh,members:[]}),k()}catch(_){ve.error(_.message)}finally{y(!1)}},te=async _=>{try{const Q=(await Se.get(`/api/admin/combos/${_.id}`)).combo;v(Q.id),O({name:Q.name,slug:Q.publicModelId.startsWith("combo/")?Q.slug:"",enabled:Q.enabled,maxTotalAttempts:Q.maxTotalAttempts,fallbackOnConnection:Q.fallbackOnConnection,fallbackOnConnectTimeout:Q.fallbackOnConnectTimeout,fallbackOnFirstTokenTimeout:Q.fallbackOnFirstTokenTimeout,fallbackOn408:Q.fallbackOn408,fallbackOn429:Q.fallbackOn429,fallbackOn5xx:Q.fallbackOn5xx,members:Q.members.map(J=>({modelId:J.modelId,position:J.position,enabled:J.enabled}))}),p(!0)}catch(H){ve.error(H.message)}},G=async()=>{if(g){if(D.members.length===0){ve.error("Add at least one member");return}w(!0);try{await Se.patch("/api/admin/combos",{id:g,name:D.name,slug:D.slug.trim()||void 0,enabled:D.enabled,...D,members:D.members}),ve.success("Combo updated"),p(!1),v(null),k()}catch(_){ve.error(_.message)}finally{w(!1)}}},ie=_=>{T(H=>({...H,members:gu([...H.members,{modelId:_,position:H.members.length,enabled:!0}])}))},ce=_=>{O(H=>({...H,members:gu([...H.members,{modelId:_,position:H.members.length,enabled:!0}])}))},se=async _=>{try{await Se.del(`/api/admin/combos/${_}`),ve.success("Combo removed"),U(null),k()}catch(H){ve.error(H.message)}};return o.jsxs("div",{children:[o.jsx($a,{title:"Combos",description:"Virtual models combining physical models",actions:o.jsxs(Mn,{open:c,onOpenChange:u,children:[o.jsx(mi,{asChild:!0,children:o.jsxs(me,{children:[o.jsx(Su,{className:"mr-1 h-4 w-4"})," New combo"]})}),o.jsxs(vn,{className:"max-h-[calc(100vh-2rem)] max-w-2xl grid-rows-[auto_minmax(0,1fr)_auto] overflow-hidden",children:[o.jsx(xn,{children:o.jsx(yn,{children:"New combo"})}),o.jsxs("div",{className:"min-h-0 space-y-3 overflow-y-auto pr-1",children:[o.jsxs("div",{children:[o.jsx(we,{children:"Name"}),o.jsx(Ae,{value:M.name,onChange:_=>T({...M,name:_.target.value})})]}),o.jsxs("div",{children:[o.jsx(we,{children:"Slug (optional — empty uses the name as the model ID)"}),o.jsx(Ae,{value:M.slug,onChange:_=>T({...M,slug:_.target.value}),placeholder:"empty → gpt-5.5 · set → combo/gpt-5.5"})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ca,{checked:M.enabled,onCheckedChange:_=>T({...M,enabled:_})}),o.jsx(we,{children:"Enabled"})]}),o.jsx(qb,{value:M,onChange:_=>T(H=>({...H,..._}))}),o.jsxs("div",{children:[o.jsx(we,{children:"Members — priority order · drag to reorder"}),o.jsx(Yb,{models:l,addedIds:M.members.map(_=>_.modelId),onAdd:ie}),o.jsx(Vb,{members:M.members,modelFor:_=>l.find(H=>H.id===_.modelId)??null}),o.jsx($b,{className:"mt-2",members:M.members,label:_=>{var H;return((H=l.find(Q=>Q.id===_.modelId))==null?void 0:H.publicModelId)??_.modelId},modelFor:_=>l.find(H=>H.id===_.modelId)??null,onChange:_=>T(H=>({...H,members:_}))})]})]}),o.jsxs(An,{children:[o.jsx(me,{variant:"outline",onClick:()=>u(!1),children:"Cancel"}),o.jsx(me,{disabled:!M.name||x,onClick:X,children:x?"Creating…":"Create"})]})]})]})}),o.jsxs(nt,{children:[o.jsxs(at,{children:[o.jsx(rt,{className:"text-base",children:"All combos"}),o.jsxs(gn,{children:[n.length," total"]})]}),o.jsx(lt,{children:o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Public ID"}),o.jsx(ye,{children:"Members"}),o.jsx(ye,{children:"Status"}),o.jsx(ye,{children:"Enabled"}),o.jsx(ye,{})]})}),o.jsxs(da,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:5,className:"text-center text-muted-foreground",children:"No combos yet."})}),n.map(_=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:_.publicModelId}),o.jsx(pe,{children:_.memberCount}),o.jsxs(pe,{children:[o.jsxs(Qe,{variant:_.status==="ready"?"success":_.status==="disabled"?"secondary":"destructive",children:[_.healthyMemberCount,"/",_.memberCount," ready"]}),_.capabilityWarnings.length>0&&o.jsx("div",{className:"text-xs text-amber-600",children:"Capability metadata differs"}),_.status==="unavailable"&&_.unavailableReasons.length>0&&o.jsx("div",{className:"text-xs text-muted-foreground",children:_.unavailableReasons.map(H=>vk[H]??H).join(", ")})]}),o.jsx(pe,{children:_.enabled?"Yes":"No"}),o.jsx(pe,{className:"text-right",children:o.jsxs("div",{className:"flex items-center justify-end gap-1",children:[o.jsxs(me,{size:"sm",variant:"outline",title:"Sends a real non-streaming inference request",onClick:()=>void $(_),disabled:E===_.id,children:[E===_.id?o.jsx(_s,{className:"mr-1 h-3.5 w-3.5 animate-spin"}):o.jsx(A0,{className:"mr-1 h-3.5 w-3.5"})," Test"]}),o.jsxs(me,{size:"sm",variant:"outline",onClick:()=>void te(_),children:[o.jsx(xR,{className:"h-3.5 w-3.5"})," Sửa"]}),o.jsxs(me,{size:"sm",variant:"destructive",onClick:()=>U(_),children:[o.jsx(ju,{className:"h-3.5 w-3.5"})," Delete"]})]})})]},_.id))]})]})})]}),o.jsx(Mn,{open:f,onOpenChange:p,children:o.jsxs(vn,{className:"max-h-[calc(100vh-2rem)] max-w-2xl grid-rows-[auto_minmax(0,1fr)_auto] overflow-hidden",children:[o.jsx(xn,{children:o.jsx(yn,{children:"Edit combo"})}),o.jsxs("div",{className:"min-h-0 space-y-3 overflow-y-auto pr-1",children:[o.jsxs("div",{children:[o.jsx(we,{children:"Name"}),o.jsx(Ae,{value:D.name,onChange:_=>O({...D,name:_.target.value})})]}),o.jsxs("div",{children:[o.jsx(we,{children:"Slug (optional — leave empty to use the name as the model ID)"}),o.jsx(Ae,{value:D.slug,onChange:_=>O({...D,slug:_.target.value}),placeholder:"empty → gpt-5.5 · set → combo/gpt-5.5"})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ca,{checked:D.enabled,onCheckedChange:_=>O({...D,enabled:_})}),o.jsx(we,{children:"Enabled"})]}),o.jsx(qb,{value:D,onChange:_=>O(H=>({...H,..._}))}),o.jsxs("div",{children:[o.jsx(we,{children:"Members — priority order · drag to reorder"}),o.jsx(Yb,{models:l,addedIds:D.members.map(_=>_.modelId),onAdd:ce}),o.jsx(Vb,{members:D.members,modelFor:_=>l.find(H=>H.id===_.modelId)??null}),o.jsx($b,{className:"mt-2",members:D.members,label:_=>{var H;return((H=l.find(Q=>Q.id===_.modelId))==null?void 0:H.publicModelId)??_.modelId},modelFor:_=>l.find(H=>H.id===_.modelId)??null,onChange:_=>O(H=>({...H,members:_}))})]})]}),o.jsxs(An,{children:[o.jsx(me,{variant:"outline",onClick:()=>p(!1),children:"Cancel"}),o.jsx(me,{disabled:!D.name||b,onClick:G,children:b?"Saving…":"Save"})]})]})}),o.jsx(Mn,{open:C!==null,onOpenChange:_=>{_||N(null)},children:o.jsxs(vn,{className:"max-w-2xl",children:[o.jsxs(xn,{children:[o.jsx(yn,{children:"Combo test result"}),o.jsx("p",{className:"text-sm text-muted-foreground",children:"Test sends a real non-streaming inference request through this combo."})]}),C&&o.jsx(yk,{result:C}),o.jsx(An,{children:o.jsx(me,{onClick:()=>N(null),children:"Close"})})]})}),o.jsx(up,{open:A!==null,onOpenChange:_=>{_||U(null)},children:o.jsxs(Pu,{children:[o.jsxs(dp,{children:[o.jsx(qu,{children:"Delete combo?"}),o.jsx(Vu,{children:"This removes the virtual model and its ordered fallback configuration. Request history is preserved."})]}),o.jsxs(fp,{children:[o.jsx(Yu,{children:"Cancel"}),o.jsx($u,{onClick:()=>A&&void se(A.id),children:"Delete"})]})]})})]})}function qb({value:n,onChange:a}){const l=[["fallbackOnConnection","Connection failure"],["fallbackOnConnectTimeout","Connect timeout"],["fallbackOnFirstTokenTimeout","First-token timeout"],["fallbackOn408","HTTP 408"],["fallbackOn429","HTTP 429"],["fallbackOn5xx","HTTP 5xx"]];return o.jsxs("div",{className:"rounded border bg-muted/20 p-3",children:[o.jsx("div",{className:"mb-2 text-sm font-medium",children:"Fallback policy"}),o.jsxs("div",{className:"grid gap-3 sm:grid-cols-[10rem_1fr]",children:[o.jsxs("div",{children:[o.jsx(we,{children:"Max total attempts"}),o.jsx(Ae,{type:"number",min:1,max:8,value:n.maxTotalAttempts,onChange:s=>a({maxTotalAttempts:Math.min(8,Math.max(1,Number(s.target.value)||1))})})]}),o.jsx("div",{className:"grid gap-2 sm:grid-cols-2",children:l.map(([s,c])=>o.jsxs("label",{className:"flex items-center gap-2 text-xs",children:[o.jsx(Ca,{checked:!!n[s],onCheckedChange:u=>a({[s]:u})}),o.jsx("span",{children:c})]},s))})]})]})}function Vb({members:n,modelFor:a}){if(n.length===0)return null;const l=n.map(a).filter(c=>!!c),s=["chat","streaming","tools","structured_output","image_input","reasoning"].filter(c=>new Set(l.map(u=>u.capabilities[c]===!0?"yes":u.capabilities[c]===!1?"no":"unknown")).size>1);return o.jsxs("div",{className:"rounded border bg-muted/20 p-2 text-xs",children:[o.jsxs("div",{className:"mb-1 font-medium",children:["Route preview ",o.jsx("span",{className:"font-normal text-muted-foreground",children:"(first available member wins)"})]}),s.length>0&&o.jsxs("div",{className:"mb-2 flex items-center gap-1 text-amber-600",children:[o.jsx(O0,{className:"h-3.5 w-3.5"})," Members differ on: ",s.join(", ")]}),o.jsx("div",{className:"space-y-1",children:n.map((c,u)=>{const f=a(c);return o.jsxs("div",{className:"flex items-center gap-2 font-mono",children:[o.jsxs("span",{className:"w-4 text-muted-foreground",children:[u+1,"."]}),o.jsx("span",{children:(f==null?void 0:f.publicModelId)??c.modelId}),o.jsxs("span",{className:"text-muted-foreground",children:["→ ",(f==null?void 0:f.upstreamModelId)??"upstream model unknown"]})]},c.id??c.modelId)})})]})}function yk({result:n}){return o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{className:"flex items-center justify-between rounded border p-3",children:[o.jsxs("div",{className:"flex items-center gap-2",children:[n.success?o.jsx(ci,{className:"h-4 w-4 text-emerald-600"}):o.jsx(O0,{className:"h-4 w-4 text-amber-600"}),o.jsx(Qe,{variant:n.success?"success":"warning",children:n.success?"Success":"Failed"})]}),o.jsxs("span",{className:"text-xs text-muted-foreground",children:[n.latencyMs," ms total"]})]}),o.jsxs("div",{children:[o.jsx("div",{className:"mb-1 text-sm font-medium",children:"Selected upstream"}),n.selectedModel?o.jsxs("div",{className:"rounded border bg-muted/20 p-2 font-mono text-xs",children:[n.selectedModel.publicModelId," → ",n.selectedModel.upstreamModelId,o.jsxs("span",{className:"ml-2 text-muted-foreground",children:["(",n.selectedModel.providerSlug,")"]})]}):o.jsx("p",{className:"text-sm text-muted-foreground",children:"No member completed successfully."})]}),o.jsxs("div",{children:[o.jsx("div",{className:"mb-1 text-sm font-medium",children:"Attempts"}),o.jsx("div",{className:"space-y-1",children:n.attempts.map((a,l)=>o.jsxs("div",{className:"flex items-center gap-2 rounded border p-2 text-xs",children:[o.jsxs("span",{className:"w-4 text-muted-foreground",children:[l+1,"."]}),o.jsxs("span",{className:"min-w-0 flex-1 font-mono",children:[a.publicModelId," → ",a.upstreamModelId]}),o.jsxs("span",{className:"text-muted-foreground",children:[a.latencyMs," ms"]}),o.jsx(Qe,{variant:a.success?"success":"warning",children:a.success?"Used":a.failureReason??"Skipped"})]},a.publicModelId+"-"+l))})]}),n.text&&o.jsx("pre",{className:"max-h-32 overflow-auto whitespace-pre-wrap rounded border bg-muted/20 p-2 text-xs",children:n.text})]})}function $b({members:n,label:a,modelFor:l,onChange:s,className:c}){const u=P_(Mb(Dp,{activationConstraint:{distance:4}}),Mb(Mp,{coordinateGetter:pk}));if(n.length===0)return o.jsx("p",{className:Ee("text-xs text-muted-foreground",c),children:"No members yet — add at least one."});const f=({active:p,over:g})=>{!g||p.id===g.id||s(gu(Op(n,Number(p.id),Number(g.id))))};return o.jsx(V3,{sensors:u,collisionDetection:V_,modifiers:[W3,J3],onDragEnd:f,children:o.jsx(lk,{items:n.map((p,g)=>g),strategy:ak,children:o.jsx("div",{className:Ee("space-y-1",c),children:n.map((p,g)=>o.jsx(bk,{index:g,label:a(p),model:l(p),onRemove:()=>s(gu(n.filter((v,x)=>x!==g)))},p.id??p.modelId))})})})}function bk({index:n,label:a,model:l,onRemove:s}){const{attributes:c,listeners:u,setNodeRef:f,transform:p,transition:g,isDragging:v}=fk({id:n});return o.jsxs("div",{ref:f,style:{transform:p?`translate3d(${p.x}px, ${p.y}px, 0)`:void 0,transition:g},className:Ee("flex items-center gap-2 rounded border p-2 text-sm",v&&"relative z-10 bg-muted/60 shadow-sm"),children:[o.jsx("button",{type:"button",...c,...u,"aria-label":`Reorder ${a}`,title:"Drag to change priority",className:"cursor-grab touch-none rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground active:cursor-grabbing",children:o.jsx(cR,{className:"h-4 w-4"})}),o.jsx("span",{className:"w-5 text-xs tabular-nums text-muted-foreground",children:n+1}),o.jsxs("div",{className:"min-w-0 flex-1",children:[o.jsx("div",{className:"truncate font-mono text-xs",children:a}),o.jsxs("div",{className:"truncate text-[11px] text-muted-foreground",children:[(l==null?void 0:l.providerSlug)||"provider"," · upstream: ",(l==null?void 0:l.upstreamModelId)??"unknown"]})]}),o.jsx(Qe,{variant:l&&l.enabled&&l.providerEnabled&&l.providerHealth!=="down"&&l.providerHealth!=="circuit_open"&&!l.circuitOpen&&l.upstreamAvailable&&l.capabilities.chat!==!1?"success":"warning",children:l&&l.enabled&&l.providerEnabled&&l.providerHealth!=="down"&&l.providerHealth!=="circuit_open"&&!l.circuitOpen&&l.upstreamAvailable&&l.capabilities.chat!==!1?"Ready":"Unavailable"}),o.jsx(me,{size:"sm",variant:"outline",onClick:s,children:"Remove"})]})}function Yb({models:n,addedIds:a,onAdd:l}){const[s,c]=m.useState(""),f=(s?n.filter(p=>{const g=s.toLowerCase();return p.publicModelId.toLowerCase().includes(g)||p.displayName.toLowerCase().includes(g)}):n).filter(p=>!a.includes(p.id));return o.jsxs("div",{className:"space-y-1",children:[o.jsxs("div",{className:"relative",children:[o.jsx(D0,{className:"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground"}),o.jsx(Ae,{className:"pl-8",placeholder:"Search models…",value:s,onChange:p=>c(p.target.value)}),s&&o.jsx("button",{className:"absolute right-2 top-2.5 text-muted-foreground hover:text-foreground",onClick:()=>c(""),children:o.jsx(Cu,{className:"h-4 w-4"})})]}),f.length===0?o.jsx("p",{className:"text-xs text-muted-foreground",children:"No models match."}):o.jsx("div",{className:"max-h-40 space-y-1 overflow-auto rounded border p-1",children:f.map(p=>o.jsxs("div",{className:"flex items-center justify-between rounded p-1 text-sm hover:bg-accent",children:[o.jsx("span",{className:"font-mono text-xs",children:p.publicModelId}),o.jsx(me,{size:"sm",variant:"ghost",onClick:()=>l(p.id),children:"+ Add"})]},p.id))})]})}function wk(){const[n,a]=m.useState([]),[l,s]=m.useState([]),[c,u]=m.useState([]),[f,p]=m.useState(!1),[g,v]=m.useState({alias:"",targetKind:"model",targetId:"",enabled:!0}),x=async()=>{const[b,w,E]=await Promise.all([Se.get("/api/admin/aliases"),Se.get("/api/admin/models"),Se.get("/api/admin/combos")]);a(b.aliases),s(w.models),u(E.combos)};m.useEffect(()=>{x()},[]);const y=async()=>{try{await Se.post("/api/admin/aliases",g),ve.success("Alias created"),p(!1),v({alias:"",targetKind:"model",targetId:"",enabled:!0}),x()}catch(b){ve.error(b.message)}};return o.jsxs("div",{children:[o.jsx($a,{title:"Aliases",description:"Stable client-visible names for models or combos",actions:o.jsxs(Mn,{open:f,onOpenChange:p,children:[o.jsx(mi,{asChild:!0,children:o.jsxs(me,{children:[o.jsx(Su,{className:"mr-1 h-4 w-4"})," New alias"]})}),o.jsxs(vn,{children:[o.jsx(xn,{children:o.jsx(yn,{children:"New alias"})}),o.jsxs("div",{className:"space-y-3",children:[o.jsxs("div",{children:[o.jsx(we,{children:"Alias"}),o.jsx(Ae,{value:g.alias,onChange:b=>v({...g,alias:b.target.value}),placeholder:"coding"})]}),o.jsxs("div",{children:[o.jsx(we,{children:"Target type"}),o.jsxs(Ua,{value:g.targetKind,onValueChange:b=>v({...g,targetKind:b}),children:[o.jsx(Sa,{children:o.jsx(Ba,{})}),o.jsxs(ja,{children:[o.jsx(Rt,{value:"model",children:"Model"}),o.jsx(Rt,{value:"combo",children:"Combo"})]})]})]}),o.jsxs("div",{children:[o.jsx(we,{children:"Target"}),o.jsxs(Ua,{value:g.targetId,onValueChange:b=>v({...g,targetId:b}),children:[o.jsx(Sa,{children:o.jsx(Ba,{placeholder:"Choose target"})}),o.jsx(ja,{children:(g.targetKind==="model"?l:c).map(b=>o.jsx(Rt,{value:b.id,children:b.publicModelId},b.id))})]})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ca,{checked:g.enabled,onCheckedChange:b=>v({...g,enabled:b})}),o.jsx(we,{children:"Enabled"})]})]}),o.jsxs(An,{children:[o.jsx(me,{variant:"outline",onClick:()=>p(!1),children:"Cancel"}),o.jsx(me,{disabled:!g.alias||!g.targetId,onClick:y,children:"Create"})]})]})]})}),o.jsxs(nt,{children:[o.jsxs(at,{children:[o.jsx(rt,{className:"text-base",children:"All aliases"}),o.jsxs(gn,{children:[n.length," total"]})]}),o.jsx(lt,{children:o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Alias"}),o.jsx(ye,{children:"Target"}),o.jsx(ye,{children:"Type"}),o.jsx(ye,{children:"Enabled"}),o.jsx(ye,{})]})}),o.jsxs(da,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:5,className:"text-center text-muted-foreground",children:"No aliases yet."})}),n.map(b=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:b.alias}),o.jsx(pe,{className:"font-mono text-xs",children:b.targetName??b.targetId}),o.jsx(pe,{children:o.jsx(Qe,{variant:"outline",children:b.targetKind})}),o.jsx(pe,{children:b.enabled?"Yes":"No"}),o.jsx(pe,{className:"text-right",children:o.jsx(me,{size:"sm",variant:"outline",onClick:async()=>{await Se.del(`/api/admin/aliases/${b.id}`),ve.success("Removed"),x()},children:"Delete"})})]},b.id))]})]})})]})]})}function Sk(){const[n,a]=m.useState([]),[l,s]=m.useState([]),[c,u]=m.useState([]),[f,p]=m.useState(!1),[g,v]=m.useState(null),[x,y]=m.useState(null),[b,w]=m.useState(null),[E,j]=m.useState({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""}),C=async()=>{const[A,U,k]=await Promise.all([Se.get("/api/admin/api-keys"),Se.get("/api/admin/models"),Se.get("/api/admin/combos")]);a(A.apiKeys),s(U.models),u(k.combos)};m.useEffect(()=>{C()},[]);const N=async()=>{try{if(g){await Se.patch("/api/admin/api-keys",{id:g,name:E.name,expiresAt:E.expiresAt||null,allowAllModels:E.allowAll,permissions:E.allowAll?[]:E.permissions,rpmLimit:E.rpmLimit?Number(E.rpmLimit):null,tpmLimit:E.tpmLimit?Number(E.tpmLimit):null,maxConcurrent:E.concurrency?Number(E.concurrency):null}),p(!1),v(null),j({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""}),ve.success("Key updated"),C();return}const A=await Se.post("/api/admin/api-keys",{name:E.name,expiresAt:E.expiresAt||null,allowAllModels:E.allowAll,permissions:E.allowAll?void 0:E.permissions,rpmLimit:E.rpmLimit?Number(E.rpmLimit):null,tpmLimit:E.tpmLimit?Number(E.tpmLimit):null,maxConcurrent:E.concurrency?Number(E.concurrency):null,...E.customSecret.trim()?{secret:E.customSecret.trim()}:{}});p(!1),y({secret:A.secret,name:A.name}),j({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""}),C()}catch(A){ve.error(A.message)}},M=async A=>{try{const k=((await Se.get(`/api/admin/api-keys/${A.id}`)).apiKey.permissions??[]).filter($=>$.targetKind==="model"||$.targetKind==="combo");v(A.id),j({name:A.name,expiresAt:A.expiresAt?A.expiresAt.slice(0,16):"",allowAll:A.allowAllModels,permissions:k,rpmLimit:A.rpmLimit!=null?String(A.rpmLimit):"",tpmLimit:A.tpmLimit!=null?String(A.tpmLimit):"",concurrency:A.concurrencyLimit!=null?String(A.concurrencyLimit):"",customSecret:""}),p(!0)}catch(U){ve.error(U.message)}},T=()=>{p(!1),v(null),j({name:"",expiresAt:"",allowAll:!0,permissions:[],rpmLimit:"",tpmLimit:"",concurrency:"",customSecret:""})},D=async(A,U)=>{try{await Se.patch("/api/admin/api-keys",{id:A,enabled:!U}),ve.success(U?"Key disabled":"Key enabled"),C()}catch(k){ve.error(k.message)}},O=async A=>{if(window.confirm("Delete this API key? This cannot be undone."))try{await Se.del(`/api/admin/api-keys/${A}`),ve.success("Key deleted"),C()}catch(U){ve.error(U.message)}};return o.jsxs("div",{children:[o.jsx($a,{title:"API Keys",description:"Gateway bearer keys for client applications",actions:o.jsxs(Mn,{open:f,onOpenChange:A=>{A?p(!0):T()},children:[o.jsx(mi,{asChild:!0,children:o.jsxs(me,{children:[o.jsx(Su,{className:"mr-1 h-4 w-4"})," New key"]})}),o.jsxs(vn,{className:"max-w-2xl",children:[o.jsx(xn,{children:o.jsx(yn,{children:g?"Edit API key":"New API key"})}),o.jsxs("div",{className:"space-y-3",children:[o.jsxs("div",{children:[o.jsx(we,{children:"Name"}),o.jsx(Ae,{value:E.name,onChange:A=>j({...E,name:A.target.value})})]}),o.jsxs("div",{children:[o.jsx(we,{children:"Expires (optional)"}),o.jsx(Ae,{type:"datetime-local",value:E.expiresAt,onChange:A=>j({...E,expiresAt:A.target.value})})]}),o.jsxs("div",{className:"grid grid-cols-3 gap-2",children:[o.jsxs("div",{children:[o.jsx(we,{children:"RPM limit"}),o.jsx(Ae,{value:E.rpmLimit,onChange:A=>j({...E,rpmLimit:A.target.value}),type:"number"})]}),o.jsxs("div",{children:[o.jsx(we,{children:"TPM limit"}),o.jsx(Ae,{value:E.tpmLimit,onChange:A=>j({...E,tpmLimit:A.target.value}),type:"number"})]}),o.jsxs("div",{children:[o.jsx(we,{children:"Concurrency"}),o.jsx(Ae,{value:E.concurrency,onChange:A=>j({...E,concurrency:A.target.value}),type:"number"})]})]}),!g&&o.jsxs("div",{children:[o.jsx(we,{children:"Key value (optional)"}),o.jsx(Ae,{value:E.customSecret,onChange:A=>j({...E,customSecret:A.target.value}),placeholder:"Leave empty to auto-generate ld-…"}),o.jsx("p",{className:"text-xs text-muted-foreground",children:"If provided, this exact value is stored as the key. Otherwise a random ld-… key is generated."})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Ca,{checked:E.allowAll,onCheckedChange:A=>j({...E,allowAll:A})}),o.jsx(we,{children:"Allow all current and future models"})]}),!E.allowAll&&o.jsxs("div",{children:[o.jsx(we,{children:"Scope"}),o.jsx("div",{className:"max-h-48 space-y-1 overflow-auto rounded border p-2",children:[...l.map(A=>({targetKind:"model",targetId:A.id,label:A.publicModelId})),...c.map(A=>({targetKind:"combo",targetId:A.id,label:A.publicModelId}))].map(A=>{const U=E.permissions.some(k=>k.targetKind===A.targetKind&&k.targetId===A.targetId);return o.jsxs("label",{className:"flex items-center gap-2 rounded p-1 text-sm hover:bg-accent",children:[o.jsx(jp,{checked:U,onCheckedChange:k=>{j($=>({...$,permissions:k?[...$.permissions,{targetKind:A.targetKind,targetId:A.targetId}]:$.permissions.filter(X=>!(X.targetKind===A.targetKind&&X.targetId===A.targetId))}))}}),o.jsx("span",{className:"font-mono text-xs",children:A.label}),o.jsx(Qe,{variant:"outline",className:"ml-1",children:A.targetKind})]},`${A.targetKind}:${A.targetId}`)})})]})]}),o.jsxs(An,{children:[o.jsx(me,{variant:"outline",onClick:T,children:"Cancel"}),o.jsx(me,{disabled:!E.name,onClick:N,children:g?"Save changes":"Create"})]})]})]})}),o.jsxs(nt,{children:[o.jsxs(at,{children:[o.jsx(rt,{className:"text-base",children:"All keys"}),o.jsxs(gn,{children:[n.length," total"]})]}),o.jsx(lt,{children:o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Name"}),o.jsx(ye,{children:"Prefix"}),o.jsx(ye,{children:"Status"}),o.jsx(ye,{children:"Scope"}),o.jsx(ye,{children:"RPM/TPM/Conc"}),o.jsx(ye,{})]})}),o.jsxs(da,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:6,className:"text-center text-muted-foreground",children:"No API keys yet."})}),n.map(A=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-medium",children:A.name}),o.jsxs(pe,{className:"font-mono text-xs",children:[A.keyPrefix,"…"]}),o.jsx(pe,{children:A.enabled?o.jsx(Qe,{variant:"success",children:"enabled"}):o.jsx(Qe,{variant:"destructive",children:"disabled"})}),o.jsx(pe,{children:A.allowAllModels?"all":`${A.modelScopeCount} scoped`}),o.jsx(pe,{className:"text-xs",children:[A.rpmLimit,A.tpmLimit,A.concurrencyLimit].map((U,k)=>U?["","RPM","TPM","Conc"][k+1]:null).filter(Boolean).join(" / ")||"—"}),o.jsx(pe,{className:"text-right",children:o.jsxs("div",{className:"flex items-center justify-end gap-1",children:[A.secret&&o.jsxs(o.Fragment,{children:[o.jsx(me,{size:"sm",variant:"ghost",title:"Copy secret",onClick:()=>{navigator.clipboard.writeText(A.secret),ve.success("Copied")},children:o.jsx(Fc,{className:"h-3.5 w-3.5"})}),o.jsx(me,{size:"sm",variant:"ghost",title:"Show secret",onClick:()=>w({secret:A.secret,name:A.name}),children:o.jsx(sR,{className:"h-3.5 w-3.5"})})]}),o.jsx(me,{size:"sm",variant:"ghost",title:"Edit",onClick:()=>void M(A),children:o.jsx(hR,{className:"h-3.5 w-3.5"})}),o.jsxs(me,{size:"sm",variant:"outline",onClick:()=>D(A.id,A.enabled),children:[A.enabled?o.jsx(FE,{className:"mr-1 h-3.5 w-3.5"}):o.jsx(ci,{className:"mr-1 h-3.5 w-3.5"}),A.enabled?"Disable":"Enable"]}),o.jsx(me,{size:"sm",variant:"destructive",onClick:()=>O(A.id),children:o.jsx(ju,{className:"h-3.5 w-3.5"})})]})})]},A.id))]})]})})]}),o.jsx(Mn,{open:!!x,onOpenChange:A=>{A||y(null)},children:o.jsxs(vn,{children:[o.jsxs(xn,{children:[o.jsx(yn,{children:"API key created"}),o.jsx(uu,{children:"Copy now — this secret will not be shown again."})]}),o.jsx("div",{className:"rounded border bg-muted p-3 font-mono text-xs break-all",children:x==null?void 0:x.secret}),o.jsxs(An,{children:[o.jsxs(me,{onClick:()=>{x&&(navigator.clipboard.writeText(x.secret),ve.success("Copied"))},children:[o.jsx(Fc,{className:"mr-1 h-4 w-4"})," Copy"]}),o.jsx(me,{variant:"outline",onClick:()=>y(null),children:"I have saved it"})]})]})}),o.jsx(Mn,{open:!!b,onOpenChange:A=>{A||w(null)},children:o.jsxs(vn,{children:[o.jsxs(xn,{children:[o.jsxs(yn,{children:["API key: ",b==null?void 0:b.name]}),o.jsx(uu,{children:"Full secret for this key, readable any time."})]}),o.jsx("div",{className:"rounded border bg-muted p-3 font-mono text-xs break-all",children:b==null?void 0:b.secret}),o.jsxs(An,{children:[o.jsxs(me,{onClick:()=>{b&&(navigator.clipboard.writeText(b.secret),ve.success("Copied"))},children:[o.jsx(Fc,{className:"mr-1 h-4 w-4"})," Copy"]}),o.jsx(me,{variant:"outline",onClick:()=>w(null),children:"Close"})]})]})})]})}const jk=3e3;function Ck(n,a){return!(a.success!=="all"&&n.success!==(a.success==="true")||a.protocol!=="all"&&n.protocol!==a.protocol||a.streaming!=="all"&&n.streaming!==(a.streaming==="true")||a.model&&!n.requestedModel.toLowerCase().includes(a.model.toLowerCase()))}function Ek(){const[n,a]=m.useState([]),[l,s]=m.useState(0),[c,u]=m.useState(0),[f,p]=m.useState({success:"all",protocol:"all",streaming:"all",model:""}),[g,v]=m.useState(null),[x,y]=m.useState(null),[b,w]=m.useState(0),E=50,j=m.useRef(Date.now()),C=m.useRef(new Set),N=m.useRef(f);N.current=f;const M=m.useRef(c);M.current=c;const T=m.useCallback(async()=>{const O=new URLSearchParams;O.set("limit",String(E)),O.set("offset",String(c)),f.success!=="all"&&O.set("success",f.success),f.protocol!=="all"&&O.set("protocol",f.protocol),f.streaming!=="all"&&O.set("streaming",f.streaming),f.model&&O.set("requestedModel",f.model);const A=await Se.get(`/api/admin/requests?${O.toString()}`);a(A.requests),s(A.total);for(const U of A.requests)C.current.add(U.id)},[c,f]);m.useEffect(()=>{T()},[T]),m.useEffect(()=>{w(0)},[c,f]),m.useEffect(()=>{let O=!1,A=null;const U=new Set,k=()=>{O||(A=new EventSource(`/api/admin/requests/stream?since=${j.current}`),A.addEventListener("request",$=>{if(!O)try{const X=JSON.parse($.data),te=new Date(X.createdAt).getTime();if(Number.isFinite(te)&&(j.current=Math.max(j.current,te)),C.current.has(X.id))return;C.current.add(X.id),w(G=>G+1),M.current===0&&Ck(X,N.current)&&(a(G=>G.some(ie=>ie.id===X.id)?G:[X,...G].slice(0,E)),s(G=>G+1))}catch{}}),A.onerror=()=>{A==null||A.close(),A=null,O||U.add(setTimeout(k,jk))})};return k(),()=>{O=!0,A==null||A.close();for(const $ of U)clearTimeout($);U.clear()}},[]);const D=async O=>{v(O);const A=await Se.get(`/api/admin/requests/${O}`);y(A)};return o.jsxs("div",{children:[o.jsx($a,{title:"Requests",description:`${l} matching · live updates`}),o.jsxs(nt,{children:[o.jsxs(at,{children:[o.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[o.jsxs(Ua,{value:f.success,onValueChange:O=>{u(0),p({...f,success:O})},children:[o.jsx(Sa,{className:"w-36",children:o.jsx(Ba,{})}),o.jsxs(ja,{children:[o.jsx(Rt,{value:"all",children:"All"}),o.jsx(Rt,{value:"true",children:"Success"}),o.jsx(Rt,{value:"false",children:"Failed"})]})]}),o.jsxs(Ua,{value:f.protocol,onValueChange:O=>{u(0),p({...f,protocol:O})},children:[o.jsx(Sa,{className:"w-32",children:o.jsx(Ba,{})}),o.jsxs(ja,{children:[o.jsx(Rt,{value:"all",children:"Any protocol"}),o.jsx(Rt,{value:"openai",children:"OpenAI"}),o.jsx(Rt,{value:"anthropic",children:"Anthropic"})]})]}),o.jsxs(Ua,{value:f.streaming,onValueChange:O=>{u(0),p({...f,streaming:O})},children:[o.jsx(Sa,{className:"w-32",children:o.jsx(Ba,{})}),o.jsxs(ja,{children:[o.jsx(Rt,{value:"all",children:"Any"}),o.jsx(Rt,{value:"true",children:"Streaming"}),o.jsx(Rt,{value:"false",children:"Non-stream"})]})]}),o.jsx(Ae,{className:"max-w-xs",placeholder:"Model contains…",value:f.model,onChange:O=>{u(0),p({...f,model:O.target.value})}}),b>0&&o.jsxs(me,{size:"sm",variant:"secondary",onClick:()=>{w(0),T()},children:[b," new request",b>1?"s":""," — refresh"]})]}),o.jsx(rt,{className:"mt-3 text-base",children:"Results"})]}),o.jsxs(lt,{children:[o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Time"}),o.jsx(ye,{children:"Status"}),o.jsx(ye,{children:"Requested"}),o.jsx(ye,{children:"Final"}),o.jsx(ye,{children:"Tokens"}),o.jsx(ye,{children:"Latency"}),o.jsx(ye,{children:"Attempts"}),o.jsx(ye,{children:"Key"}),o.jsx(ye,{children:"IP"}),o.jsx(ye,{})]})}),o.jsxs(da,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:10,className:"text-center text-muted-foreground",children:"No requests yet."})}),n.map(O=>o.jsxs(We,{className:"cursor-pointer",onClick:()=>D(O.id),children:[o.jsx(pe,{className:"text-xs",children:Lm(O.createdAt)}),o.jsx(pe,{children:O.success?o.jsx(Qe,{variant:"success",children:O.httpStatus}):o.jsx(Qe,{variant:"destructive",children:O.httpStatus})}),o.jsx(pe,{className:"font-mono text-xs",children:O.requestedModel}),o.jsx(pe,{className:"font-mono text-xs text-muted-foreground",children:O.finalModelPublicId??"—"}),o.jsxs(pe,{className:"text-xs",children:[Kt(O.inputTokens+O.outputTokens)," ",O.cacheReadTokens?o.jsxs("span",{className:"text-amber-600",children:["(+",O.cacheReadTokens," cache)"]}):null]}),o.jsxs(pe,{className:"text-xs",children:[Ol(O.totalLatencyMs),O.ttftMs?o.jsxs("span",{className:"text-muted-foreground",children:[" · ttft ",O.ttftMs,"ms"]}):null]}),o.jsxs(pe,{className:"text-xs",children:[O.attemptsCount,O.gatewayCacheHit?o.jsx(Qe,{variant:"secondary",className:"ml-1",children:"cache"}):null]}),o.jsx(pe,{className:"text-xs",children:O.apiKeyName??"—"}),o.jsx(pe,{className:"text-xs",children:O.clientIp}),o.jsx(pe,{className:"text-right",children:o.jsx(me,{size:"sm",variant:"ghost",children:"View"})})]},O.id))]})]}),o.jsxs("div",{className:"mt-3 flex items-center justify-between",children:[o.jsxs("span",{className:"text-xs text-muted-foreground",children:["Showing ",c+1,"–",Math.min(c+E,l)," of ",l]}),o.jsxs("div",{className:"flex gap-2",children:[o.jsx(me,{size:"sm",variant:"outline",disabled:c===0,onClick:()=>u(Math.max(0,c-E)),children:"Prev"}),o.jsx(me,{size:"sm",variant:"outline",disabled:c+E>=l,onClick:()=>u(c+E),children:"Next"})]})]})]})]}),o.jsx(Mn,{open:!!g,onOpenChange:O=>{O||(v(null),y(null))},children:o.jsxs(vn,{className:"max-w-3xl",children:[o.jsx(xn,{children:o.jsxs(yn,{children:["Request ",tN(g,16)]})}),x?o.jsxs("div",{className:"space-y-3 text-sm",children:[o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Requested model"}),o.jsx("span",{className:"font-mono text-xs",children:x.request.requestedModel})]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Upstream model"}),o.jsx("span",{className:"font-mono text-xs",children:x.request.finalModelUpstreamId??"—"})]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Provider"}),x.request.providerId?o.jsx(ra,{className:"text-primary underline",to:`/providers?providerId=${encodeURIComponent(x.request.providerId)}`,children:x.request.providerName??x.request.providerSlug??x.request.providerId}):"—"]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Route"}),x.request.resolvedTargetId?o.jsx(ra,{className:"text-primary underline",to:x.request.resolvedTargetKind==="combo"?"/combos":"/models",children:x.request.resolvedTargetKind??"target"}):"—"]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Status"}),x.request.success?o.jsx(Qe,{variant:"success",children:x.request.httpStatus}):o.jsx(Qe,{variant:"destructive",children:x.request.httpStatus})]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Latency"}),Ol(x.request.totalLatencyMs)]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Tokens"}),"in ",Kt(x.request.inputTokens)," · out ",Kt(x.request.outputTokens)," · cache ",Kt(x.request.cacheReadTokens)]}),o.jsxs("div",{children:[o.jsx("div",{className:"text-muted-foreground text-xs",children:"Attempts"}),x.request.attemptsCount]})]}),x.request.errorType&&o.jsxs("div",{className:"rounded border border-destructive/40 bg-destructive/10 p-2",children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Error"}),o.jsxs("div",{className:"font-mono text-xs",children:[x.request.errorType,": ",x.request.errorMessage]})]}),x.request.fallbackReasons.length>0&&o.jsxs("div",{className:"rounded border border-amber-500/40 bg-amber-500/10 p-2",children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Fallback reasons"}),o.jsx("div",{className:"text-xs",children:x.request.fallbackReasons.join(", ")})]}),o.jsxs("div",{children:[o.jsxs("div",{className:"mb-1 flex items-center justify-between text-xs text-muted-foreground",children:[o.jsx("span",{children:"Safe replay curl"}),o.jsxs(me,{size:"sm",variant:"ghost",onClick:()=>{navigator.clipboard.writeText(x.request.reproductionCurl).then(()=>ve.success("Curl copied"))},children:[o.jsx(Fc,{className:"mr-1 h-3.5 w-3.5"})," Copy"]})]}),o.jsx("pre",{className:"max-h-36 overflow-auto whitespace-pre-wrap rounded bg-muted p-2 font-mono text-xs",children:x.request.reproductionCurl}),o.jsx("p",{className:"mt-1 text-xs text-muted-foreground",children:"Replace the placeholder key before running. No stored secret is included."})]}),x.request.requestPayload&&o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Request content"}),o.jsx("pre",{className:"max-h-60 overflow-auto rounded bg-muted p-2 font-mono text-xs whitespace-pre-wrap",children:x.request.requestPayload})]}),x.request.responsePayload&&o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Response content"}),o.jsx("pre",{className:"max-h-60 overflow-auto rounded bg-muted p-2 font-mono text-xs whitespace-pre-wrap",children:x.request.responsePayload})]}),x.attempts.length>0&&o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Attempts"}),o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"#"}),o.jsx(ye,{children:"Provider"}),o.jsx(ye,{children:"Model"}),o.jsx(ye,{children:"Status"}),o.jsx(ye,{children:"Latency"}),o.jsx(ye,{children:"Reason"})]})}),o.jsx(da,{children:x.attempts.map(O=>o.jsxs(We,{children:[o.jsx(pe,{children:O.attemptNumber}),o.jsx(pe,{children:O.providerName}),o.jsxs(pe,{children:[o.jsx("div",{className:"font-mono text-xs",children:O.modelPublicId}),o.jsxs("div",{className:"text-[11px] text-muted-foreground",children:["upstream: ",O.upstreamModelId]})]}),o.jsx(pe,{children:O.success?o.jsx(Qe,{variant:"success",children:String(O.statusCode??"OK")}):o.jsx(Qe,{variant:"destructive",children:String(O.statusCode??"err")})}),o.jsx(pe,{className:"text-xs",children:Ol(O.latencyMs)}),o.jsx(pe,{className:"text-xs",children:O.failureReason??O.selectionReason})]},O.id))})]})]})]}):o.jsx("div",{className:"text-muted-foreground",children:"Loading…"})]})})]})}var Rk=Object.defineProperty,Zs=(n,a)=>Rk(n,"name",{value:a,configurable:!0}),_p="Tabs",[Nk,Z4]=kn(_p,[Lu]),ES=Lu(),[Tk,kp]=Nk(_p),Mk=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,value:c,onValueChange:u,defaultValue:f,orientation:p="horizontal",dir:g,activationMode:v="automatic",...x}=a,y=di(g),[b,w]=yr({prop:c,onChange:u,defaultProp:f??"",caller:_p});return o.jsx(Tk,{scope:s,baseId:La(),value:b,onValueChange:w,orientation:p,dir:y,activationMode:v,children:o.jsx(Ve.div,{dir:y,"data-orientation":p,...x,ref:l})})},"Tabs")),Ak="TabsList",Dk=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,loop:c=!0,...u}=a,f=kp(Ak,s),p=ES(s);return o.jsx(G1,{asChild:!0,...p,orientation:f.orientation,dir:f.dir,loop:c,children:o.jsx(Ve.div,{role:"tablist","aria-orientation":f.orientation,...u,ref:l})})},"TabsList")),Ok="TabsTrigger",_k=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,value:c,disabled:u=!1,...f}=a,p=kp(Ok,s),g=ES(s),v=zp(p.baseId,c),x=Lp(p.baseId,c),y=c===p.value;return o.jsx(K1,{asChild:!0,...g,focusable:!u,active:y,children:o.jsx(Ve.button,{type:"button",role:"tab","aria-selected":y,"aria-controls":x,"data-state":y?"active":"inactive","data-disabled":u?"":void 0,disabled:u,id:v,...f,ref:l,onMouseDown:Ne(a.onMouseDown,b=>{!u&&b.button===0&&b.ctrlKey===!1?p.onValueChange(c):b.preventDefault()}),onKeyDown:Ne(a.onKeyDown,b=>{u||b.target!==b.currentTarget||[" ","Enter"].includes(b.key)&&p.onValueChange(c)}),onFocus:Ne(a.onFocus,()=>{const b=p.activationMode!=="manual";!y&&!u&&b&&p.onValueChange(c)})})})},"TabsTrigger")),kk="TabsContent",zk=m.forwardRef(Zs(function(a,l){const{__scopeTabs:s,value:c,forceMount:u,children:f,...p}=a,g=kp(kk,s),v=zp(g.baseId,c),x=Lp(g.baseId,c),y=c===g.value,b=m.useRef(y);return m.useEffect(()=>{const w=requestAnimationFrame(()=>b.current=!1);return()=>cancelAnimationFrame(w)},[]),o.jsx(Cr,{present:u||y,children:({present:w})=>o.jsx(Ve.div,{"data-state":y?"active":"inactive","data-orientation":g.orientation,role:"tabpanel","aria-labelledby":v,hidden:!w,id:x,tabIndex:0,...p,ref:l,style:{...a.style,animationDuration:b.current?"0s":void 0},children:w&&f})})},"TabsContent"));function zp(n,a){return`${n}-trigger-${a}`}Zs(zp,"makeTriggerId");function Lp(n,a){return`${n}-content-${a}`}Zs(Lp,"makeContentId");var Lk=Mk,RS=Dk,NS=_k,TS=zk;const MS=Lk,Up=m.forwardRef(({className:n,...a},l)=>o.jsx(RS,{ref:l,className:Ee("inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",n),...a}));Up.displayName=RS.displayName;const mr=m.forwardRef(({className:n,...a},l)=>o.jsx(NS,{ref:l,className:Ee("inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",n),...a}));mr.displayName=NS.displayName;const Os=m.forwardRef(({className:n,...a},l)=>o.jsx(TS,{ref:l,className:Ee("mt-2 ring-offset-background focus-visible:outline-none",n),...a}));Os.displayName=TS.displayName;const Uk=3e3,Bk=1600,Hk=10,Ik=3,Pk=12,qk=10*6e4,Vk={cacheReadTokens:0,promptTokens:0,gatewayCacheHits:0,fallbacks:0};function AS(n,a,l){return l==="anthropic"?n+a:n}function $k(n){return n.promptTokens>0?n.cacheReadTokens/n.promptTokens:0}function Yk(n,a){return a>0?n.fallbacks/a:0}function Gk(n,a){return a>0?n.gatewayCacheHits/a:0}function Kk(n,a,l){const s=n.totalRequests+1,c=n.successfulRequests+(l.success?1:0),u={cacheReadTokens:a.cacheReadTokens+l.cacheReadTokens,promptTokens:a.promptTokens+AS(l.inputTokens,l.cacheReadTokens,l.providerType),gatewayCacheHits:a.gatewayCacheHits+(l.gatewayCacheHit?1:0),fallbacks:a.fallbacks+(l.attemptsCount>1?1:0)};return{...n,...u,totalRequests:s,successfulRequests:c,failedRequests:n.failedRequests+(l.success?0:1),successRate:c/s,inputTokens:n.inputTokens+l.inputTokens,outputTokens:n.outputTokens+l.outputTokens,totalTokens:n.totalTokens+l.inputTokens+l.outputTokens,cacheHitRate:$k(u),gatewayCacheHitRate:Gk(u,s),fallbackRate:Yk(u,s),averageLatencyMs:(n.averageLatencyMs*n.totalRequests+l.totalLatencyMs)/s}}function Xk(n){const[a,l]=m.useState(null),[s,c]=m.useState(null),[u,f]=m.useState([]),[p,g]=m.useState([]),[v,x]=m.useState([]),[y,b]=m.useState([]),[w,E]=m.useState(!0),[j,C]=m.useState(null),N=m.useRef([]),M=m.useRef(null),T=m.useRef(Vk),D=m.useRef(new Set),O=m.useRef(Date.now()),A=m.useRef(0),U=m.useRef([]),k=m.useRef([]);return m.useEffect(()=>{let $=!1;return E(!0),C(null),D.current=new Set,O.current=Date.now(),Se.get(`/api/admin/stats?preset=${n}`).then(X=>{if(!$){l(X),c(X.summary),M.current=X.summary,T.current={cacheReadTokens:X.summary.cacheReadTokens,promptTokens:X.summary.cacheHitRate>0?Math.round(X.summary.cacheReadTokens/X.summary.cacheHitRate):X.summary.inputTokens,gatewayCacheHits:Math.round(X.summary.gatewayCacheHitRate*X.summary.totalRequests),fallbacks:Math.round(X.summary.fallbackRate*X.summary.totalRequests)},f(X.recent),g(X.providers),N.current=X.providers;for(const te of X.recent)D.current.add(te.id);E(!1)}}).catch(X=>{$||(C(X.message),E(!1))}),()=>{$=!0}},[n]),m.useEffect(()=>{let $=!1,X=null;const te=new Set,G=()=>{$||(X=new EventSource(`/api/admin/requests/stream?since=${O.current}`),X.addEventListener("request",ce=>{if(!$)try{const se=JSON.parse(ce.data),_=new Date(se.createdAt).getTime();if(Number.isFinite(_)&&(O.current=Math.max(O.current,_)),D.current.has(se.id))return;D.current.add(se.id);const H={cacheReadTokens:T.current.cacheReadTokens+se.cacheReadTokens,promptTokens:T.current.promptTokens+AS(se.inputTokens,se.cacheReadTokens,se.providerType),gatewayCacheHits:T.current.gatewayCacheHits+(se.gatewayCacheHit?1:0),fallbacks:T.current.fallbacks+(se.attemptsCount>1?1:0)};if(T.current=H,M.current&&c(Kk(M.current,H,se)),f(Q=>Q.some(J=>J.id===se.id)?Q:[se,...Q].slice(0,Hk)),se.providerId){N.current=N.current.map(z=>z.id===se.providerId?{...z,requests:z.requests+1,errorRate:z.requests+1?(z.errorRate*z.requests+(se.success?0:1))/(z.requests+1):0}:z),g(N.current);const Q=`p${++A.current}`,J={id:Q,providerId:se.providerId,success:se.success};U.current=[...U.current.slice(-(Ik*4)),J],x(U.current);const ee=setTimeout(()=>{U.current=U.current.filter(z=>z.id!==Q),x(U.current)},Bk);te.add(ee)}k.current.some(Q=>Q.id===se.id)&&(k.current=k.current.filter(Q=>Q.id!==se.id),b(k.current))}catch{}}),X.addEventListener("request_started",ce=>{if(!$)try{const se=JSON.parse(ce.data);if(!se.providerId||se.providerId==="")return;k.current=[...k.current.filter(_=>_.id!==se.requestId).slice(-(Pk-1)),{id:se.requestId,providerId:se.providerId,startedAt:Date.now(),ttftMs:se.ttftMs??0}],b(k.current)}catch{}}),X.onerror=()=>{X==null||X.close(),X=null,$||te.add(setTimeout(G,Uk))})};G();const ie=setInterval(()=>{const ce=Date.now()-qk;k.current.some(se=>se.startedAt<ce)&&(k.current=k.current.filter(se=>se.startedAt>=ce),b(k.current))},3e4);return()=>{$=!0,X==null||X.close();for(const ce of te)clearTimeout(ce);te.clear(),clearInterval(ie)}},[]),m.useEffect(()=>{const $=setInterval(()=>{Se.get("/api/admin/providers").then(X=>{const te=new Map(X.providers.map(G=>[G.id,G]));N.current=N.current.map(G=>{const ie=te.get(G.id);return ie?{...G,health:ie.health,enabled:ie.enabled}:G}),g(N.current)}).catch(()=>{})},3e4);return()=>clearInterval($)},[]),{snapshot:a,live:s??(a==null?void 0:a.summary)??Fk,recent:u,providers:p,pulses:v,activeRoutes:y,loading:w,error:j}}const Fk={totalRequests:0,successfulRequests:0,failedRequests:0,successRate:0,inputTokens:0,outputTokens:0,totalTokens:0,cacheReadTokens:0,cacheWriteTokens:0,reasoningTokens:0,averageLatencyMs:0,p95LatencyMs:0,averageTtftMs:null,p95TtftMs:null,cacheHitRate:0,gatewayCacheHitRate:0,fallbackRate:0};function DS({data:n,className:a,strokeClass:l="stroke-primary",fillClass:s}){if(n.length===0)return o.jsx("svg",{className:Ee("h-6 w-20",a),viewBox:"0 0 80 24"});const f=Math.max(...n),p=Math.min(...n),g=f-p||1,x=n.map((y,b)=>{const w=b/(n.length-1)*78+1,E=22-(y-p)/g*20;return`${w.toFixed(1)},${E.toFixed(1)}`}).join(" ");return o.jsxs("svg",{className:Ee("h-6 w-20",a),viewBox:"0 0 80 24",preserveAspectRatio:"none",children:[s&&o.jsx("polygon",{points:`1,23 ${x} 79,23`,className:s}),o.jsx("polyline",{points:x,fill:"none",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",className:l})]})}function Qk(n,a,l){const s=performance.now();let c=0;const u=f=>{const p=Math.min((f-s)/a,1),g=Math.round(n*p);g!==c&&(c=g,l(g)),p<1&&requestAnimationFrame(u)};requestAnimationFrame(u)}function Zk({delta:n,inverse:a}){if(Math.abs(n)<.005)return null;const l=n>0,s=a?!l:l,c=`${(Math.abs(n)*100).toFixed(1)}%`;return o.jsxs("span",{className:Ee("ml-1.5 inline-flex items-center rounded-full px-1.5 py-0.5 text-[10px] font-semibold leading-none",s?"bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-300":"bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300"),children:[o.jsx("span",{className:"mr-0.5",children:l?"▲":"▼"}),c]})}function el({icon:n,label:a,value:l,format:s="number",delta:c,deltaInverse:u,sparkData:f,sparkStroke:p}){const[g,v]=m.useState(0),x=m.useRef(0);m.useEffect(()=>{const b=x.current,w=l;x.current=l,b!==w&&Qk(Math.abs(w-b),600,E=>v(b+(w>b?E:-E)))},[l]);const y=s==="percent"?Eu(g):s==="latency"?Ol(g):Kt(Math.round(g));return o.jsxs(nt,{children:[o.jsxs(at,{className:"flex flex-row items-center justify-between pb-1",children:[o.jsxs(rt,{className:"flex items-center gap-2 text-sm font-medium text-muted-foreground",children:[o.jsx(n,{className:"h-4 w-4"}),a]}),c!==void 0&&o.jsx(Zk,{delta:c,inverse:u})]}),o.jsxs(lt,{className:"flex items-end justify-between",children:[o.jsx("span",{className:"text-2xl font-semibold tabular-nums",children:y}),f&&f.length>1&&o.jsx(DS,{data:f,strokeClass:p??"stroke-primary",fillClass:"fill-primary/10"})]})]})}const OS=1e3,Gb=380,Vc=60,tl=OS/2,nl=720,Bh=62,Jk=260;function Wk(n){return n==="healthy"?"fill-emerald-400":n==="degraded"?"fill-amber-400":"fill-red-400"}function $c(n,a,l,s){const c=n+(l-n)*.45,u=n+(l-n)*.55;return`M${n},${a} C${c},${a} ${u},${s} ${l},${s}`}function e4({liveRequests:n,successRate:a,providers:l,pulses:s,activeRoutes:c}){const u=Gb/2,f=u,p=Math.max(1,l.reduce((x,y)=>x+y.requests,0)),g=new Set(c.map(x=>x.providerId)),v=g.size>0;return o.jsxs(nt,{children:[o.jsx(at,{className:"pb-2",children:o.jsxs("div",{className:"flex items-center justify-between",children:[o.jsx(rt,{className:"text-base",children:"Real-time Request Routing"}),o.jsxs("div",{className:"flex items-center gap-3 text-xs text-muted-foreground",children:[o.jsxs("span",{className:"flex items-center gap-1",children:[o.jsx("span",{className:"inline-block h-2 w-2 rounded-full bg-emerald-400"})," healthy"]}),o.jsxs("span",{className:"flex items-center gap-1",children:[o.jsx("span",{className:"inline-block h-2 w-2 rounded-full bg-amber-400"})," degraded"]}),o.jsxs("span",{className:"flex items-center gap-1",children:[o.jsx("span",{className:"inline-block h-2 w-2 rounded-full bg-red-400"})," down"]})]})]})}),o.jsx(lt,{className:"pt-0",children:o.jsx("div",{className:"relative w-full",children:o.jsxs("svg",{viewBox:`0 0 ${OS} ${Gb}`,className:"w-full h-auto",preserveAspectRatio:"xMidYMid meet",children:[o.jsx("defs",{children:o.jsxs("filter",{id:"glow",x:"-50%",y:"-50%",width:"200%",height:"200%",children:[o.jsx("feGaussianBlur",{stdDeviation:"3",result:"blur"}),o.jsxs("feMerge",{children:[o.jsx("feMergeNode",{in:"blur"}),o.jsx("feMergeNode",{in:"SourceGraphic"})]})]})}),l.map(x=>{const b=60+l.indexOf(x)*Bh,w=x.requests/p,E=Math.max(1.5,Math.min(6,2+w*8)),j=g.has(x.id);return o.jsxs("g",{children:[j&&o.jsx("path",{d:$c(tl,u,nl-20,b),fill:"none",stroke:"hsl(var(--primary) / 0.25)",strokeWidth:E+6,strokeLinecap:"round"}),o.jsx("path",{d:$c(tl,u,nl-20,b),fill:"none",stroke:j?"hsl(var(--primary))":"hsl(var(--border))",strokeWidth:j?E+1:E,strokeLinecap:"round",opacity:j?.95:.6,className:j?"route-active":void 0})]},x.id)}),o.jsx("path",{d:$c(Vc+30,f,tl-30,u),fill:"none",stroke:v?"hsl(var(--primary))":"hsl(var(--border))",strokeWidth:3,strokeLinecap:"round",strokeDasharray:"6 3",opacity:v?.9:.5,className:v?"route-active":void 0}),s.map(x=>{const y=l.findIndex(j=>j.id===x.providerId);if(y===-1)return null;const b=60+y*Bh,w=$c(tl,u,nl-20,b),E=x.success?"var(--primary)":"#f87171";return o.jsxs("g",{filter:"url(#glow)",children:[o.jsx("circle",{r:5,fill:E,opacity:.9,children:o.jsx("animateMotion",{dur:"1.4s",fill:"freeze",path:w})}),o.jsx("circle",{r:9,fill:E,opacity:.25,children:o.jsx("animateMotion",{dur:"1.4s",fill:"freeze",path:w})})]},x.id)}),o.jsx("circle",{cx:Vc,cy:f,r:28,fill:"hsl(var(--card))",stroke:"hsl(var(--border))",strokeWidth:1.5}),o.jsx("text",{x:Vc,y:f-4,textAnchor:"middle",className:"fill-foreground",fontSize:12,fontWeight:600,children:Kb(n)}),o.jsx("text",{x:Vc,y:f+10,textAnchor:"middle",className:"fill-muted-foreground",fontSize:9,children:"requests"}),o.jsx("circle",{cx:tl,cy:u,r:36,fill:"hsl(var(--card))",stroke:"var(--primary)",strokeWidth:2}),o.jsx("image",{x:tl-12,y:u-16,width:24,height:24,href:"/logo.png"}),o.jsx("text",{x:tl,y:u+28,textAnchor:"middle",className:"fill-muted-foreground",fontSize:9,children:"AI Gateway"}),o.jsxs("text",{x:tl,y:u+38,textAnchor:"middle",className:"fill-emerald-500",fontSize:10,fontWeight:600,children:[(a*100).toFixed(1),"%"]}),l.map((x,y)=>{const b=60+y*Bh,w=x.requests/p,E=!x.enabled||x.requests===0;return o.jsxs("g",{opacity:E?.4:1,children:[o.jsx("rect",{x:nl-20,y:b-14,width:Jk,height:50,rx:8,fill:"hsl(var(--card))",stroke:"hsl(var(--border))",strokeWidth:1}),o.jsx("circle",{cx:nl-6,cy:b+10,r:4,className:Wk(x.health)}),o.jsx("text",{x:nl+6,y:b-2,className:"fill-foreground",fontSize:12,fontWeight:500,children:x.name}),o.jsxs("text",{x:nl+6,y:b+12,className:"fill-muted-foreground",fontSize:10,children:[x.modelCount," model",x.modelCount!==1?"s":""," · ",Kb(x.requests)," req"]}),o.jsxs("text",{x:nl+6,y:b+25,className:"fill-muted-foreground",fontSize:10,children:[(w*100).toFixed(1),"% traffic · ",x.avgLatencyMs<1e3?`${Math.round(x.avgLatencyMs)}ms`:`${(x.avgLatencyMs/1e3).toFixed(1)}s`," avg",x.errorRate>0&&o.jsxs("tspan",{className:"fill-red-500",children:[" · ",(x.errorRate*100).toFixed(0),"% err"]})]})]},x.id)})]})})})]})}function Kb(n){return n>=1e6?`${(n/1e6).toFixed(1)}M`:n>=1e3?`${(n/1e3).toFixed(1)}K`:String(n)}function t4({rows:n}){return o.jsxs(nt,{children:[o.jsx(at,{className:"pb-2",children:o.jsx(rt,{className:"text-base",children:"Recent Requests"})}),o.jsx(lt,{children:n.length===0?o.jsx("div",{className:"py-6 text-center text-sm text-muted-foreground",children:"No requests yet — traffic will appear here live."}):o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Model"}),o.jsx(ye,{children:"Provider"}),o.jsx(ye,{children:"Tokens"}),o.jsx(ye,{children:"Status"}),o.jsx(ye,{children:"Time"})]})}),o.jsx(da,{children:n.map(a=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:a.requestedModel}),o.jsx(pe,{className:"text-xs text-muted-foreground",children:a.providerName??"—"}),o.jsxs(pe,{className:"text-xs",children:[o.jsxs("span",{className:"font-mono",children:["in ",Kt(a.inputTokens)," · out ",Kt(a.outputTokens)]}),a.cacheReadTokens>0&&o.jsxs("span",{className:"ml-1 text-amber-600",children:["(+",Kt(a.cacheReadTokens)," cache)"]})]}),o.jsx(pe,{children:o.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[o.jsx("span",{className:a.success?"h-2 w-2 rounded-full bg-emerald-400":"h-2 w-2 rounded-full bg-red-400"}),o.jsx("span",{className:"text-xs",children:a.success?a.httpStatus:`${a.httpStatus} err`})]})}),o.jsx(pe,{className:"text-xs text-muted-foreground",children:nN(a.createdAt)})]},a.id))})]})})]})}const gm=34,Xb=2*Math.PI*gm;function n4(n){return n>=.95?{stroke:"#4ade80",text:"text-emerald-500"}:n>=.8?{stroke:"#fbbf24",text:"text-amber-500"}:{stroke:"#f87171",text:"text-red-500"}}function a4({successRate:n,averageLatencyMs:a,latencySpark:l}){const{stroke:s,text:c}=n4(n),u=Math.min(1,Math.max(0,n)),f=Xb*(1-u);return o.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[o.jsxs(nt,{children:[o.jsx(at,{className:"pb-2",children:o.jsx(rt,{className:"text-base",children:"Success Rate"})}),o.jsxs(lt,{className:"flex items-center gap-4",children:[o.jsxs("div",{className:"relative h-20 w-20",children:[o.jsxs("svg",{viewBox:"0 0 80 80",className:"h-20 w-20 -rotate-90",children:[o.jsx("circle",{cx:"40",cy:"40",r:gm,fill:"none",stroke:"hsl(var(--border))",strokeWidth:7}),o.jsx("circle",{cx:"40",cy:"40",r:gm,fill:"none",stroke:s,strokeWidth:7,strokeLinecap:"round",strokeDasharray:Xb,strokeDashoffset:f,style:{transition:"stroke-dashoffset 0.6s ease, stroke 0.4s ease"}})]}),o.jsx("span",{className:`absolute inset-0 flex items-center justify-center text-sm font-semibold tabular-nums ${c}`,children:Eu(n)})]}),o.jsx("p",{className:"text-sm text-muted-foreground",children:"Share of requests that completed successfully over the selected window. Updated in real time."})]})]}),o.jsxs(nt,{children:[o.jsx(at,{className:"pb-2",children:o.jsx(rt,{className:"text-base",children:"Average Latency"})}),o.jsxs(lt,{className:"flex items-end justify-between",children:[o.jsxs("div",{children:[o.jsx("div",{className:"text-2xl font-semibold tabular-nums",children:Ol(a)}),o.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Live average across the selected window"})]}),o.jsx(DS,{data:l,strokeClass:"stroke-amber-500",fillClass:"fill-amber-500/10",className:"h-10 w-28"})]})]})]})}function r4(){const[n,a]=m.useState("7d"),{snapshot:l,live:s,recent:c,providers:u,pulses:f,activeRoutes:p,loading:g,error:v}=Xk(n);if(g)return o.jsx("div",{className:"text-muted-foreground",children:"Loading…"});if(v||!l)return o.jsxs("div",{className:"text-destructive",children:["Failed to load statistics: ",v??"unknown error"]});const x=s,y=l.previous,b=l.series;function w(C,N){return N>0?(C-N)/N:void 0}const E=b.map(C=>C.requests),j=b.map(C=>C.avgLatency);return o.jsxs("div",{children:[o.jsx($a,{title:"Statistics",description:"Real-time monitoring dashboard",actions:o.jsx(MS,{value:n,onValueChange:C=>void a(C),children:o.jsxs(Up,{children:[o.jsx(mr,{value:"today",children:"Today"}),o.jsx(mr,{value:"7d",children:"7 days"}),o.jsx(mr,{value:"30d",children:"30 days"})]})})}),o.jsxs("div",{className:"grid gap-4 md:grid-cols-2 lg:grid-cols-4",children:[o.jsx(el,{icon:km,label:"Requests",value:x.totalRequests,delta:w(x.totalRequests,y.totalRequests),sparkData:E}),o.jsx(el,{icon:ci,label:"Success rate",format:"percent",value:x.successRate,delta:w(x.successRate,y.successRate),sparkData:E,sparkStroke:"stroke-emerald-500"}),o.jsx(el,{icon:rR,label:"Total tokens",value:x.totalTokens,delta:w(x.totalTokens,y.totalTokens),sparkData:b.map(C=>C.inputTokens+C.outputTokens)}),o.jsx(el,{icon:lR,label:"Cache hit rate",format:"percent",value:x.cacheHitRate,delta:w(x.cacheHitRate,y.cacheHitRate),sparkData:b.map(C=>C.cacheRead)}),o.jsx(el,{icon:tR,label:"Avg latency",format:"latency",value:x.averageLatencyMs,delta:w(x.averageLatencyMs,y.averageLatencyMs),deltaInverse:!0,sparkData:j,sparkStroke:"stroke-amber-500"}),o.jsx(el,{icon:R0,label:"p95 latency",format:"latency",value:x.p95LatencyMs}),o.jsx(el,{icon:bR,label:"Avg TTFT",format:"latency",value:x.averageTtftMs??0}),o.jsx(el,{icon:mR,label:"Fallback rate",format:"percent",value:x.fallbackRate,delta:w(x.fallbackRate,y.fallbackRate),deltaInverse:!0})]}),o.jsx("div",{className:"mt-6",children:o.jsx(e4,{liveRequests:x.totalRequests,successRate:x.successRate,providers:u,pulses:f,activeRoutes:p})}),o.jsxs("div",{className:"mt-6 grid gap-4 lg:grid-cols-3",children:[o.jsx("div",{className:"lg:col-span-2",children:o.jsx(t4,{rows:c})}),o.jsxs("div",{className:"space-y-4",children:[o.jsxs(nt,{children:[o.jsx(at,{className:"pb-2",children:o.jsx(rt,{className:"text-base",children:"Top Models"})}),o.jsx(lt,{children:o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Model"}),o.jsx(ye,{children:"Req"}),o.jsx(ye,{children:"Errors"}),o.jsx(ye,{children:"Tokens"})]})}),o.jsxs(da,{children:[l.topModels.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:4,className:"text-muted-foreground text-center",children:"No data"})}),l.topModels.map(C=>o.jsxs(We,{children:[o.jsx(pe,{className:"font-mono text-xs",children:C.publicId}),o.jsx(pe,{className:"text-xs",children:Kt(C.requests)}),o.jsx(pe,{className:"text-xs",children:o.jsx("span",{className:C.errorRate>.1?"text-destructive":"text-muted-foreground",children:Eu(C.errorRate)})}),o.jsx(pe,{className:"text-xs",children:Kt(C.totalTokens)})]},C.publicId))]})]})})]}),o.jsxs(nt,{children:[o.jsx(at,{className:"pb-2",children:o.jsx(rt,{className:"text-base",children:"Top API Keys"})}),o.jsx(lt,{children:o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Key"}),o.jsx(ye,{children:"Requests"}),o.jsx(ye,{children:"Tokens"})]})}),o.jsxs(da,{children:[l.topApiKeys.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:3,className:"text-muted-foreground text-center",children:"No data"})}),l.topApiKeys.map((C,N)=>o.jsxs(We,{children:[o.jsx(pe,{className:"text-xs",children:C.name}),o.jsx(pe,{className:"text-xs",children:Kt(C.requests)}),o.jsx(pe,{className:"text-xs",children:Kt(C.totalTokens)})]},N))]})]})})]})]})]}),o.jsx("div",{className:"mt-6",children:o.jsx(a4,{successRate:x.successRate,averageLatencyMs:x.averageLatencyMs,latencySpark:j})})]})}function l4(){const[n,a]=m.useState([]),[l,s]=m.useState(0);return m.useEffect(()=>{Se.get("/api/admin/audit?limit=200").then(c=>{a(c.rows),s(c.total)})},[]),o.jsxs("div",{children:[o.jsx($a,{title:"Audit Logs",description:`${l} entries · immutable`}),o.jsxs(nt,{children:[o.jsx(at,{children:o.jsx(rt,{className:"text-base",children:"All entries"})}),o.jsx(lt,{children:o.jsxs(ca,{children:[o.jsx(ua,{children:o.jsxs(We,{children:[o.jsx(ye,{children:"Time"}),o.jsx(ye,{children:"Action"}),o.jsx(ye,{children:"Status"}),o.jsx(ye,{children:"Target"}),o.jsx(ye,{children:"IP"}),o.jsx(ye,{children:"Actor"})]})}),o.jsxs(da,{children:[n.length===0&&o.jsx(We,{children:o.jsx(pe,{colSpan:6,className:"text-center text-muted-foreground",children:"No audit events yet."})}),n.map(c=>o.jsxs(We,{children:[o.jsx(pe,{className:"text-xs",children:Lm(c.createdAt)}),o.jsx(pe,{className:"font-mono text-xs",children:c.action}),o.jsx(pe,{children:c.success?o.jsx(Qe,{variant:"success",children:"ok"}):o.jsx(Qe,{variant:"destructive",children:"fail"})}),o.jsx(pe,{className:"text-xs",children:c.targetName??c.targetId??"—"}),o.jsx(pe,{className:"text-xs",children:c.ip}),o.jsx(pe,{className:"text-xs",children:c.actor})]},c.id))]})]})})]})]})}const vm={enabled:!0,sound:!0};let ri=vm,xm=!1,Yc=null;const ym=new Set;function _S(){for(const n of ym)n()}function kS(n=!1){return xm&&!n?Promise.resolve():(!n&&Yc||(Yc=(async()=>{try{const a=await Se.get("/api/admin/settings");ri={enabled:a.settings.notificationsEnabled??vm.enabled,sound:a.settings.notificationSoundEnabled??vm.sound},xm=!0,_S()}catch{}})()),Yc)}async function Fb(n){const a={};n.enabled!==void 0&&(a.notificationsEnabled=n.enabled),n.sound!==void 0&&(a.notificationSoundEnabled=n.sound),await Se.patch("/api/admin/settings",a),ri={...ri,...n},xm=!0,_S()}function s4(n){return ym.add(n),()=>ym.delete(n)}function zS(){return m.useSyncExternalStore(s4,()=>ri,()=>ri)}const bm=m.forwardRef(({className:n,...a},l)=>o.jsx("textarea",{ref:l,className:Ee("flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",n),...a}));bm.displayName="Textarea";function o4(){const[n]=BE(),[a,l]=m.useState(null),[s,c]=m.useState(null),[u,f]=m.useState({current:"",next:""}),[p,g]=m.useState(""),[v,x]=m.useState(""),[y,b]=m.useState(null),[w,E]=m.useState(!1),[j,C]=m.useState("idle"),[N,M]=m.useState(null),T=async(le=!1)=>{C("checking"),M(null);try{const Le=await Se.get(`/api/admin/update/check${le?"?force=1":""}`);b(Le),C("idle")}catch(Le){M(Le.message),C("error")}},D=async()=>{E(!0),C("installing"),M(null);try{const le=await Se.post("/api/admin/update/run");C("restarting"),ve.success(le.message||"Update started — the gateway will restart shortly.");const Le=setInterval(()=>{fetch("/health").then(Ie=>{Ie.ok&&(clearInterval(Le),window.location.reload())}).catch(()=>{})},3e3);setTimeout(()=>clearInterval(Le),12e4)}catch(le){ve.error(le.message),M(le.message),C("error")}finally{E(!1)}},[O,A]=m.useState("disabled"),[U,k]=m.useState(""),[$,X]=m.useState(""),[te,G]=m.useState(""),[ie,ce]=m.useState([]),[se,_]=m.useState(""),[H,Q]=m.useState(""),[J,ee]=m.useState(!1),[z,I]=m.useState(null),[F,re]=m.useState(""),[he,ge]=m.useState(""),[q,oe]=m.useState(""),de=async()=>{const le=await Se.get("/api/admin/settings");l(le.settings),g(le.settings.adminIpAllow??""),x(le.settings.adminIpBlock??"");const Le=await Se.get("/api/admin/settings/system");c(Le);try{const Ie=await Se.get("/api/admin/me");A(Ie.totpEnabled?"enabled":"disabled")}catch{}};if(m.useEffect(()=>{kS(!0)},[]),m.useEffect(()=>{de(),T(!0)},[]),!a)return o.jsx("div",{className:"text-muted-foreground",children:"Loading…"});const fe=async le=>{try{await Se.patch("/api/admin/settings",le),ve.success("Saved"),de()}catch(Le){ve.error(Le.message)}},Te=async()=>{try{const le=await Se.post("/api/admin/account/totp/begin");k(le.secret),X(le.qr),A("setup"),ve.info("Scan the QR code with your authenticator app")}catch(le){ve.error(le.message)}},je=async()=>{if(!te||te.length!==6){ve.error("Enter a 6-digit code");return}try{const le=await Se.post("/api/admin/account/totp/verify",{code:te});ce(le.recoveryCodes),A("showingRecovery"),ve.success("TOTP enabled successfully")}catch(le){ve.error(le.message)}},De=async()=>{if(!se){ve.error("Enter your password");return}if(!H){ve.error("Enter a TOTP code or recovery code");return}try{await Se.post("/api/admin/account/totp/disable",{password:se,totp:H}),A("disabled"),_(""),Q(""),ve.success("TOTP disabled"),de()}catch(le){ve.error(le.message)}},Fe=async()=>{ee(!0);try{const le=await Se.post("/api/admin/account/totp/recovery/regenerate",{password:se,totp:H});ce(le.recoveryCodes),A("showingRecovery"),ve.success("Recovery codes regenerated")}catch(le){ve.error(le.message)}ee(!1)},et=n.get("tab")||"logging";return o.jsxs("div",{children:[o.jsx($a,{title:"Settings",description:"Logging, security, backup, and system info"}),o.jsxs(MS,{defaultValue:et,children:[o.jsxs(Up,{children:[o.jsx(mr,{value:"logging",children:"Logging"}),o.jsx(mr,{value:"access",children:"Access Control"}),o.jsx(mr,{value:"security",children:"Security"}),o.jsx(mr,{value:"backup",children:"Backup"}),o.jsx(mr,{value:"system",children:"System"})]}),o.jsx(Os,{value:"logging",children:o.jsxs(nt,{children:[o.jsx(at,{children:o.jsx(rt,{className:"text-base",children:"Logging policy"})}),o.jsxs(lt,{className:"space-y-3",children:[o.jsxs("div",{className:"space-y-1",children:[o.jsx(we,{children:"Request-content logging"}),o.jsxs(Ua,{value:a.contentLogMode,onValueChange:le=>fe({contentLogMode:le}),children:[o.jsx(Sa,{children:o.jsx(Ba,{})}),o.jsxs(ja,{children:[o.jsx(Rt,{value:"off",children:"Off"}),o.jsx(Rt,{value:"metadata",children:"Metadata only (default)"}),o.jsx(Rt,{value:"prompt",children:"Prompt (sanitized)"}),o.jsx(Rt,{value:"prompt_and_response",children:"Prompt + response (sanitized)"})]})]})]}),o.jsxs("div",{className:"space-y-1",children:[o.jsx(we,{children:"Retention (days)"}),o.jsx(Ae,{type:"number",min:1,max:3650,value:a.retentionDays,onChange:le=>fe({retentionDays:Number(le.target.value)})})]}),o.jsxs("div",{className:"space-y-1",children:[o.jsx(we,{children:"Database size limit (MB)"}),o.jsx(Ae,{type:"number",min:64,value:a.dbSizeLimitMb,onChange:le=>fe({dbSizeLimitMb:Number(le.target.value)})})]}),o.jsx("div",{className:"flex items-center gap-2 pt-2",children:o.jsx(me,{onClick:async()=>{const le=await Se.post("/api/admin/settings/cleanup");ve.success(`Deleted ${le.deletedRequests} old requests`)},children:"Run cleanup now"})})]})]})}),o.jsx(Os,{value:"access",children:o.jsxs(nt,{children:[o.jsxs(at,{children:[o.jsx(rt,{className:"text-base",children:"IP access control"}),o.jsx(gn,{children:"Allowlist / Blocklist for this admin website (not model traffic)"})]}),o.jsxs(lt,{className:"space-y-4",children:[o.jsxs("div",{className:"space-y-2",children:[o.jsx(we,{children:"Allow only these IPs"}),o.jsx(bm,{placeholder:`192.168.1.0/24
|
|
349
349
|
10.0.0.1`,value:p,onChange:le=>g(le.target.value)}),o.jsx("p",{className:"text-xs text-muted-foreground",children:"Newlines-delimited CIDR ranges (IPv4 only). Leave empty = no allow restrictions. When you save a non-empty list, your current IP is auto-added to prevent lockout."})]}),o.jsxs("div",{className:"space-y-2",children:[o.jsx(we,{children:"Block these IPs"}),o.jsx(bm,{placeholder:"192.168.1.100",value:v,onChange:le=>x(le.target.value)}),o.jsx("p",{className:"text-xs text-muted-foreground",children:'Newlines-delimited CIDR ranges (IPv4 only). Blocked IPs are rejected with "Không có quyền truy cập" before any login page.'})]}),o.jsx(me,{onClick:()=>{const le={};p!==((a==null?void 0:a.adminIpAllow)??"")&&(le.adminIpAllow=p||null),v!==((a==null?void 0:a.adminIpBlock)??"")&&(le.adminIpBlock=v||null),Se.patch("/api/admin/settings",le).then(Le=>{ve.success("Saved"+(Le.addedIp?` — added your IP: ${Le.addedIp}`:"")),de(),g(""),x("")}).catch(Le=>ve.error(Le.message))},children:"Save access control"}),o.jsxs("div",{className:"rounded bg-amber-50 border border-amber-200 p-3 dark:bg-amber-950/20 dark:border-amber-800",children:[o.jsx("p",{className:"text-sm font-medium text-amber-900 dark:text-amber-200",children:"⚠️ If you enable an allow list, you cannot access the gateway unless your IP matches."}),o.jsx("p",{className:"text-xs text-amber-800 dark:text-amber-300",children:"The server automatically adds your current IP when you save — but if you configure it from a different machine, that machine will be locked out immediately."})]})]})]})}),o.jsx(Os,{value:"security",children:o.jsxs(nt,{children:[o.jsxs(at,{children:[o.jsx(rt,{className:"text-base",children:"Security"}),o.jsx(gn,{children:"Change password, 2FA, and trusted proxy configuration"})]}),o.jsxs(lt,{className:"space-y-4",children:[o.jsxs("div",{className:"space-y-2",children:[o.jsx(we,{children:"Trusted proxy hops"}),o.jsx(Ae,{type:"number",min:0,max:8,value:a.trustProxyHops,onChange:le=>fe({trustProxyHops:Number(le.target.value)})}),o.jsx("p",{className:"text-xs text-muted-foreground",children:"0 = never trust X-Forwarded-For (direct exposure). 1+ only when behind a single trusted reverse proxy."})]}),o.jsxs("div",{className:"space-y-2 border-t pt-4",children:[o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(we,{className:"text-base",children:"TOTP 2FA"}),O==="enabled"?o.jsx("span",{className:"rounded bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800 dark:bg-green-900 dark:text-green-200",children:"Enabled"}):null,O==="disabled"?o.jsx("span",{className:"rounded bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground",children:"Disabled"}):null]}),O==="disabled"&&o.jsx(me,{variant:"outline",onClick:Te,children:"Enable TOTP"}),O==="setup"&&o.jsxs("div",{className:"space-y-3 rounded border p-3",children:[o.jsx("p",{className:"text-sm text-muted-foreground",children:"Scan this QR code with your authenticator app, or enter the secret manually."}),$&&o.jsx("img",{src:$,alt:"TOTP QR code",className:"h-40 w-40"}),o.jsxs("div",{className:"text-xs font-mono text-muted-foreground",children:["Secret: ",U]}),o.jsxs("div",{className:"flex items-end gap-2",children:[o.jsxs("div",{className:"flex-1",children:[o.jsx(we,{children:"Verify code"}),o.jsx(Ae,{value:te,onChange:le=>G(le.target.value),placeholder:"123456",maxLength:6})]}),o.jsx(me,{disabled:te.length<6,onClick:je,children:"Verify & enable"})]})]}),O==="showingRecovery"&&o.jsxs("div",{className:"space-y-3 rounded border border-amber-500/40 bg-amber-50 p-3 dark:bg-amber-950/20",children:[o.jsx("p",{className:"text-sm font-medium",children:"Recovery codes — save these now!"}),o.jsx("p",{className:"text-xs text-muted-foreground",children:"Each code can be used once to log in without your TOTP device. They will not be shown again."}),o.jsx("div",{className:"space-y-1",children:ie.map((le,Le)=>o.jsx("div",{className:"font-mono text-xs",children:le},Le))}),o.jsx(me,{onClick:()=>{A("enabled"),ve.success("Recovery codes saved")},children:"I have saved them"})]}),O==="enabled"&&o.jsxs("div",{className:"space-y-3 rounded border p-3",children:[o.jsxs("div",{className:"grid gap-2 sm:grid-cols-2",children:[o.jsxs("div",{children:[o.jsx(we,{children:"Password"}),o.jsx(Ae,{type:"password",value:se,onChange:le=>_(le.target.value),placeholder:"Current password"})]}),o.jsxs("div",{children:[o.jsx(we,{children:"TOTP code"}),o.jsx(Ae,{value:H,onChange:le=>Q(le.target.value),placeholder:"123456",maxLength:6})]})]}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(me,{variant:"outline",size:"sm",disabled:J||!se||H.length<6,onClick:Fe,children:"Regenerate recovery codes"}),o.jsx(me,{variant:"destructive",size:"sm",disabled:!se||H.length<6,onClick:De,children:"Disable TOTP"})]})]})]}),o.jsxs("div",{className:"space-y-2 border-t pt-4",children:[o.jsx(we,{children:"Change password"}),o.jsx(Ae,{type:"password",placeholder:"Current password",value:u.current,onChange:le=>f({...u,current:le.target.value})}),o.jsx(Ae,{type:"password",placeholder:"New password (12+ chars)",value:u.next,onChange:le=>f({...u,next:le.target.value})}),o.jsx(me,{disabled:!u.current||u.next.length<12,onClick:async()=>{try{await Se.post("/api/admin/account/password",{currentPassword:u.current,newPassword:u.next}),ve.success("Password changed"),f({current:"",next:""})}catch(le){ve.error(le.message)}},children:"Change password"})]})]})]})}),o.jsx(Os,{value:"backup",children:o.jsxs(nt,{children:[o.jsxs(at,{children:[o.jsx(rt,{className:"text-base",children:"Backup & restore"}),o.jsx(gn,{children:"Download a snapshot or restore from a previous backup"})]}),o.jsxs(lt,{className:"space-y-3",children:[o.jsxs("div",{className:"space-y-2 rounded border p-3",children:[o.jsx(we,{children:"Backup passphrase (6 digits)"}),o.jsx(Ae,{inputMode:"numeric",maxLength:6,value:F,onChange:le=>re(le.target.value.replace(/\D/g,"")),placeholder:"123456"}),o.jsx(Ae,{inputMode:"numeric",maxLength:6,value:he,onChange:le=>ge(le.target.value.replace(/\D/g,"")),placeholder:"Repeat passphrase"}),o.jsx("p",{className:"text-xs text-muted-foreground",children:"This passphrase encrypts the master key inside the backup. You must enter the same 6 digits when importing on a new instance. Without it, encrypted provider credentials cannot be recovered."})]}),o.jsx(me,{disabled:F.length!==6||F!==he,onClick:async()=>{try{const le=await ru("/api/admin/backup/create",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({passphrase:F})});if(!le.ok)throw new Error("Backup failed");const Le=await le.blob(),Ie=URL.createObjectURL(Le),kt=document.createElement("a");kt.href=Ie,kt.download="latedev-backup.json",kt.click(),URL.revokeObjectURL(Ie),ve.success("Backup downloaded"),re(""),ge("")}catch(le){ve.error(le.message)}},children:"Download backup"}),o.jsxs("div",{className:"space-y-2 rounded border p-3",children:[o.jsx(we,{children:"Backup passphrase for restore"}),o.jsx(Ae,{inputMode:"numeric",maxLength:6,value:q,onChange:le=>oe(le.target.value.replace(/\D/g,"")),placeholder:"123456"}),o.jsx("p",{className:"text-xs text-muted-foreground",children:"Use the 6-digit passphrase entered when the backup was created. It is required to restore the master key and administrator access."})]}),o.jsxs(up,{open:z!==null,onOpenChange:le=>{le||I(null)},children:[o.jsx(vO,{asChild:!0,children:o.jsxs("div",{children:[o.jsx(we,{children:"Restore from backup file"}),o.jsx(Ae,{type:"file",accept:".json,application/json","data-testid":"restore-file",onChange:le=>{var Ie;const Le=(Ie=le.target.files)==null?void 0:Ie[0];I(Le??null)}})]})}),o.jsxs(Pu,{children:[o.jsxs(dp,{children:[o.jsx(qu,{children:"Restore backup?"}),o.jsxs(Vu,{children:["Restoring will replace the entire current database with the selected backup (",(z==null?void 0:z.name)??"file","). This cannot be undone. A snapshot of the current database is kept for rollback only if validation fails."]})]}),o.jsxs(fp,{children:[o.jsx(Yu,{children:"Cancel"}),o.jsx($u,{onClick:async()=>{var Le,Ie;const le=z;if(le)try{const kt=JSON.parse(await le.text()),St=await ru("/api/admin/backup/restore",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({backup:kt,passphrase:q})});if(!St.ok)throw new Error(((Ie=(Le=await St.json())==null?void 0:Le.error)==null?void 0:Ie.message)??"Restore failed");ve.success("Restored. Reloading…"),I(null),setTimeout(()=>location.reload(),600)}catch(kt){ve.error(kt.message)}},children:"Restore"})]})]})]})]})]})}),o.jsxs(Os,{value:"system",children:[o.jsxs(nt,{children:[o.jsx(at,{children:o.jsx(rt,{className:"text-base",children:"System"})}),o.jsxs(lt,{className:"space-y-2 text-sm",children:[o.jsxs("div",{children:[o.jsx("span",{className:"text-muted-foreground",children:"App version:"})," ",s==null?void 0:s.appVersion]}),o.jsxs("div",{children:[o.jsx("span",{className:"text-muted-foreground",children:"Data directory:"})," ",o.jsx("span",{className:"font-mono",children:s==null?void 0:s.dataDir})]}),o.jsxs("div",{children:[o.jsx("span",{className:"text-muted-foreground",children:"Encryption:"})," ",s!=null&&s.masterKeyConfigured?"Configured":"Not configured"," (v",s==null?void 0:s.masterKeyVersion,")"]}),o.jsxs("div",{children:[o.jsx("span",{className:"text-muted-foreground",children:"Environment:"})," ",s==null?void 0:s.environment]}),o.jsxs("div",{className:"flex items-center gap-2 pt-2",children:[o.jsx(Ca,{checked:a.gatewayCacheEnabled,onCheckedChange:le=>fe({gatewayCacheEnabled:le})}),o.jsx(we,{children:"Gateway response cache (disabled by default)"})]}),o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsxs("div",{children:[o.jsx(we,{children:"Cache TTL (s)"}),o.jsx(Ae,{type:"number",min:1,value:a.gatewayCacheDefaultTtlSeconds,onChange:le=>fe({gatewayCacheDefaultTtlSeconds:Number(le.target.value)})})]}),o.jsxs("div",{children:[o.jsx(we,{children:"Cache max size (MB)"}),o.jsx(Ae,{type:"number",min:1,value:a.gatewayCacheMaxSizeMb,onChange:le=>fe({gatewayCacheMaxSizeMb:Number(le.target.value)})})]})]}),o.jsx(me,{variant:"outline",onClick:async()=>{const le=await Se.post("/api/admin/settings/cache/clear");ve.success(`Cleared ${le.deleted} entries`)},children:"Clear gateway cache"})]})]}),o.jsx(i4,{}),o.jsxs(nt,{className:"mt-4",children:[o.jsxs(at,{children:[o.jsx(rt,{className:"text-base",children:"Updates"}),o.jsx(gn,{children:"Automatic updates from the npm registry"})]}),o.jsxs(lt,{className:"space-y-3 text-sm",children:[j==="checking"&&!y&&o.jsxs("div",{className:"flex items-center gap-2 text-muted-foreground",children:[o.jsx(_s,{className:"h-4 w-4 animate-spin"})," Checking for updates…"]}),y&&o.jsxs(o.Fragment,{children:[o.jsxs("div",{className:"flex flex-wrap items-center gap-4",children:[o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Current version"}),o.jsxs("div",{className:"font-mono",children:["v",y.currentVersion]})]}),o.jsx("span",{className:"text-muted-foreground",children:"→"}),o.jsxs("div",{children:[o.jsx("div",{className:"text-xs text-muted-foreground",children:"Latest version"}),o.jsx("div",{className:"font-mono",children:y.latestVersion?`v${y.latestVersion}`:"—"})]}),y.status.docker?o.jsx(Qe,{variant:"secondary",children:y.status.watchtower?"Docker + Watchtower":"Docker"}):y.latestVersion===null?o.jsx(Qe,{variant:"secondary",children:"Registry unreachable"}):y.hasUpdate?o.jsx(Qe,{variant:"success",children:"Update available"}):o.jsxs(Qe,{variant:"outline",children:[o.jsx(ci,{className:"mr-1 h-3 w-3"})," Up to date"]})]}),y.status.docker&&y.status.watchtower&&y.watchtowerReachable&&o.jsx("p",{className:"text-muted-foreground",children:"Watchtower pulls new images automatically every hour — or use Update now for an instant update."}),y.status.docker&&y.status.watchtower&&y.watchtowerReachable===!1&&o.jsxs("p",{className:"text-muted-foreground",children:["The Watchtower sidecar is configured but not running — start it with ",o.jsx("code",{className:"rounded bg-muted px-1 text-xs",children:"docker compose --profile updater up -d"}),"."]}),y.status.docker&&!y.status.watchtower&&o.jsx("p",{className:"text-muted-foreground",children:y.status.reason??"This instance runs in Docker — update by pulling the new image tag."}),!y.status.docker&&y.latestVersion===null&&o.jsxs("p",{className:"text-muted-foreground",children:["Could not reach the npm registry (offline or blocked). ",N&&o.jsx("span",{className:"text-destructive",children:N})]}),j==="installing"&&o.jsxs("div",{className:"flex items-center gap-2 text-muted-foreground",children:[o.jsx(_s,{className:"h-4 w-4 animate-spin"})," Applying the update… this can take a minute."]}),j==="restarting"&&o.jsxs("div",{className:"flex items-center gap-2 text-muted-foreground",children:[o.jsx(_s,{className:"h-4 w-4 animate-spin"})," Update applied — the gateway is restarting on the new version. This page reloads automatically."]}),o.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[y.hasUpdate&&j==="idle"&&(!y.status.docker||y.status.watchtower&&y.watchtowerReachable!==!1)&&o.jsxs(me,{disabled:w||y.status.docker&&y.watchtowerReachable===!1,onClick:D,children:[o.jsx(E0,{className:"mr-1 h-4 w-4"})," Update now"]}),y.hasUpdate&&y.changelogUrl&&o.jsx(me,{variant:"outline",asChild:!0,children:o.jsx("a",{href:y.changelogUrl,target:"_blank",rel:"noreferrer",children:"View changes"})}),j==="idle"&&o.jsx(me,{variant:"ghost",disabled:w,onClick:()=>T(!0),children:"Check again"})]})]})]})]})]})]})]})}function i4(){const n=zS();return o.jsxs(nt,{className:"mt-4",children:[o.jsx(at,{children:o.jsxs(rt,{className:"text-base flex items-center gap-2",children:[o.jsx(QE,{className:"h-4 w-4"})," Notifications"]})}),o.jsxs(lt,{className:"space-y-3 text-sm",children:[o.jsxs("div",{className:"flex items-center justify-between",children:[o.jsx("span",{children:"Show request notifications"}),o.jsx(Ca,{checked:n.enabled,onCheckedChange:a=>void Fb({enabled:a})})]}),o.jsxs("div",{className:"flex items-center justify-between",children:[o.jsxs("span",{className:"flex items-center gap-1",children:[o.jsx(wR,{className:"h-3 w-3"})," Play notification sound"]}),o.jsx(Ca,{checked:n.sound,onCheckedChange:a=>void Fb({sound:a})})]}),o.jsx("p",{className:"text-xs text-muted-foreground mt-2",children:"Notifications are disabled while muted. Changes apply immediately."})]})]})}function c4({items:n,onDismiss:a}){return n.length?o.jsx("div",{className:"fixed top-16 right-4 z-50 flex max-h-[calc(100vh-8rem)] w-80 flex-col gap-2 overflow-y-auto",children:n.map(l=>{const s=!l.success,c=l.success&&l.totalLatencyMs>15e3,u=Ee("rounded-md border shadow-lg transition-all",s&&"bg-destructive text-destructive-foreground border-destructive",c&&"bg-amber-500/90 text-amber-950 border-amber-600/50",!s&&!c&&"bg-card text-card-foreground border-border");return o.jsxs(ra,{to:"/requests",className:Ee("block shrink-0 p-3 hover:opacity-95",u),children:[o.jsxs("div",{className:"flex items-start justify-between gap-2",children:[o.jsxs("div",{className:"flex min-w-0 flex-1 items-center gap-2",children:[s?o.jsx(eR,{className:"h-4 w-4 shrink-0"}):l.success?o.jsx(ci,{className:"h-4 w-4 shrink-0"}):o.jsx(SR,{className:"h-4 w-4 shrink-0 opacity-70"}),o.jsx("div",{className:"min-w-0 truncate text-sm font-medium",title:l.requestedModel,children:l.requestedModel})]}),o.jsx("button",{className:"shrink-0 opacity-60 hover:opacity-100",onClick:f=>{f.preventDefault(),f.stopPropagation(),a(l.id)},"aria-label":"Dismiss",type:"button",children:o.jsx(Cu,{className:"h-3.5 w-3.5"})})]}),o.jsxs("div",{className:"mt-1 text-xs",children:[l.success?"Thành công":"Thất bại",!l.success&&l.errorType&&o.jsx("span",{className:"ml-1 inline-block rounded bg-black/15 px-1 py-0.5 align-text-bottom text-[10px]",children:l.errorType})]}),o.jsxs("div",{className:"mt-1 text-[11px] opacity-90",children:["in ",Kt(l.inputTokens)," · out ",Kt(l.outputTokens),(l.cacheReadTokens>0||l.cacheWriteTokens>0)&&o.jsxs(o.Fragment,{children:[" · cache ",l.cacheReadTokens>0&&o.jsxs("span",{children:["r",Kt(l.cacheReadTokens)]}),l.cacheReadTokens>0&&l.cacheWriteTokens>0&&"/",l.cacheWriteTokens>0&&o.jsxs("span",{children:["w",Kt(l.cacheWriteTokens)]})]})]}),o.jsxs("div",{className:"mt-1 text-[11px] opacity-90",children:[Ol(l.totalLatencyMs),l.ttftMs!=null&&l.ttftMs>=0&&o.jsxs("span",{children:[" · TTFT ",Ol(l.ttftMs)]})]})]},l.id)})}):null}const u4=5e3,d4=8,f4=3e3;let Gc=null;function h4(){try{Gc||(Gc=new Audio("/notification.mp3")),Gc.currentTime=0,Gc.play().catch(()=>{})}catch{}}function m4(){const[n,a]=m.useState([]),l=m.useRef(null),s=m.useRef(new Map),c=m.useRef(Date.now()),u=m.useRef(new Set),f=zS(),p=m.useRef(f.sound);p.current=f.sound,m.useEffect(()=>{kS()},[]);const g=f.enabled;return m.useEffect(()=>{var w;if(!g){(w=l.current)==null||w.close(),l.current=null;const E=s.current;for(const j of E.values())clearTimeout(j);E.clear(),a([]);return}let x=!1;const y=s.current,b=()=>{if(x)return;const E=new EventSource(`/api/admin/requests/stream?since=${c.current}`);l.current=E,E.addEventListener("request",j=>{if(!x)try{const C=JSON.parse(j.data),N=new Date(C.createdAt).getTime();if(Number.isFinite(N)&&(c.current=Math.max(c.current,N)),u.current.has(C.id))return;u.current.add(C.id),a(T=>T.some(D=>D.id===C.id)?T:[C,...T].slice(0,d4));const M=setTimeout(()=>{a(T=>T.filter(D=>D.id!==C.id)),y.delete(C.id)},u4);y.set(C.id,M),p.current&&h4()}catch{}}),E.onerror=()=>{E.close(),l.current=null,x||setTimeout(b,f4)}};return b(),()=>{var E;x=!0,(E=l.current)==null||E.close(),l.current=null;for(const j of y.values())clearTimeout(j);y.clear()}},[g]),{items:n,dismiss:x=>{const y=s.current.get(x);y&&(clearTimeout(y),s.current.delete(x)),a(b=>b.filter(w=>w.id!==x))}}}function p4({children:n}){const{user:a,loading:l}=_m(),s=_n();return l?o.jsx("div",{className:"flex h-screen items-center justify-center text-muted-foreground",children:"Loading…"}):a?o.jsx(o.Fragment,{children:n}):o.jsx(Ih,{to:"/login",state:{from:s},replace:!0})}function g4(){const{items:n,dismiss:a}=m4();return o.jsxs("div",{className:"flex h-screen bg-background text-foreground",children:[o.jsx(rN,{}),o.jsxs("div",{className:"flex flex-1 flex-col overflow-hidden",children:[o.jsx(lD,{}),o.jsx("main",{className:"flex-1 overflow-auto p-6",children:o.jsxs(g0,{children:[o.jsx(Nn,{index:!0,element:o.jsx(HD,{})}),o.jsx(Nn,{path:"/providers",element:o.jsx(h_,{})}),o.jsx(Nn,{path:"/models",element:o.jsx(R_,{})}),o.jsx(Nn,{path:"/combos",element:o.jsx(xk,{})}),o.jsx(Nn,{path:"/aliases",element:o.jsx(wk,{})}),o.jsx(Nn,{path:"/api-keys",element:o.jsx(Sk,{})}),o.jsx(Nn,{path:"/requests",element:o.jsx(Ek,{})}),o.jsx(Nn,{path:"/statistics",element:o.jsx(r4,{})}),o.jsx(Nn,{path:"/audit",element:o.jsx(l4,{})}),o.jsx(Nn,{path:"/settings/*",element:o.jsx(o4,{})})]})})]}),o.jsx(c4,{items:n,onDismiss:a})]})}function v4({children:n}){const[a,l]=m.useState(null),s=_n();return m.useEffect(()=>{Se.get("/api/admin/setup/status").then(c=>l(c.setupComplete)).catch(()=>l(!0))},[]),a===null?o.jsx("div",{className:"flex h-screen items-center justify-center text-muted-foreground",children:"Loading…"}):!a&&s.pathname!=="/setup"?o.jsx(Ih,{to:"/setup",replace:!0}):a&&s.pathname==="/setup"?o.jsx(Ih,{to:"/",replace:!0}):o.jsx(o.Fragment,{children:n})}function x4(){return o.jsx(YE,{children:o.jsx(v4,{children:o.jsxs(g0,{children:[o.jsx(Nn,{path:"/setup",element:o.jsx(UD,{})}),o.jsx(Nn,{path:"/login",element:o.jsx(LD,{})}),o.jsx(Nn,{path:"/*",element:o.jsx(p4,{children:o.jsx(g4,{})})})]})})})}const y4=zD;var b4=Object.defineProperty,Dn=(n,a)=>b4(n,"name",{value:a,configurable:!0}),[Bp,J4]=kn("Tooltip",[Ks]),w4=Ks(),S4="TooltipProvider",j4=700,Qb="tooltip.open",[C4,E4]=Bp(S4),R4=Dn(n=>{const{__scopeTooltip:a,delayDuration:l=j4,skipDelayDuration:s=300,disableHoverableContent:c=!1,children:u}=n,f=m.useRef(!0),p=m.useRef(!1),g=m.useRef(0);return m.useEffect(()=>{const v=g.current;return()=>window.clearTimeout(v)},[]),o.jsx(C4,{scope:a,isOpenDelayedRef:f,delayDuration:l,onOpen:m.useCallback(()=>{s<=0||(window.clearTimeout(g.current),f.current=!1)},[s]),onClose:m.useCallback(()=>{s<=0||(window.clearTimeout(g.current),g.current=window.setTimeout(()=>f.current=!0,s))},[s]),isPointerInTransitRef:p,onPointerInTransitChange:m.useCallback(v=>{p.current=v},[]),disableHoverableContent:c,children:u})},"TooltipProvider"),N4="Tooltip",[W4,Hp]=Bp(N4),T4="TooltipPortal",[e5,M4]=Bp(T4,{forceMount:void 0}),li="TooltipContent",A4=m.forwardRef(Dn(function(a,l){const s=M4(li,a.__scopeTooltip),{forceMount:c=s.forceMount,side:u="top",...f}=a,p=Hp(li,a.__scopeTooltip);return o.jsx(Cr,{present:c||p.open,children:p.disableHoverableContent?o.jsx(LS,{side:u,...f,ref:l}):o.jsx(D4,{side:u,...f,ref:l})})},"TooltipContent")),D4=m.forwardRef(Dn(function(a,l){const s=Hp(li,a.__scopeTooltip),c=E4(li,a.__scopeTooltip),u=m.useRef(null),f=Xe(l,u),[p,g]=m.useState(null),{trigger:v,onClose:x}=s,y=u.current,{onPointerInTransitChange:b}=c,w=m.useCallback(()=>{g(null),b(!1)},[b]),E=m.useCallback((j,C)=>{const N=j.currentTarget,M={x:j.clientX,y:j.clientY},T=US(M,N.getBoundingClientRect()),D=BS(M,T),O=HS(C.getBoundingClientRect()),A=PS([...D,...O]);g(A),b(!0)},[b]);return m.useEffect(()=>()=>w(),[w]),m.useEffect(()=>{if(v&&y){const j=Dn(N=>E(N,y),"handleTriggerLeave"),C=Dn(N=>E(N,v),"handleContentLeave");return v.addEventListener("pointerleave",j),y.addEventListener("pointerleave",C),()=>{v.removeEventListener("pointerleave",j),y.removeEventListener("pointerleave",C)}}},[v,y,E,w]),m.useEffect(()=>{if(p){const j=Dn(C=>{const N=C.target,M={x:C.clientX,y:C.clientY},T=(v==null?void 0:v.contains(N))||(y==null?void 0:y.contains(N)),D=!IS(M,p);T?w():D&&(w(),x())},"handleTrackPointerGrace");return document.addEventListener("pointermove",j),()=>document.removeEventListener("pointermove",j)}},[v,y,p,x,w]),o.jsx(LS,{...a,ref:f})},"TooltipContentHoverable")),O4=q0("TooltipContent"),LS=m.forwardRef(Dn(function(a,l){const{__scopeTooltip:s,children:c,"aria-label":u,id:f,onEscapeKeyDown:p,onPointerDownOutside:g,...v}=a,x=Hp(li,s),y=w4(s),{onClose:b}=x;m.useEffect(()=>(document.addEventListener(Qb,b),()=>document.removeEventListener(Qb,b)),[b]),m.useEffect(()=>{if(x.trigger){const E=Dn(j=>{j.target instanceof Node&&j.target.contains(x.trigger)&&b()},"handleScroll");return window.addEventListener("scroll",E,{capture:!0}),()=>window.removeEventListener("scroll",E,{capture:!0})}},[x.trigger,b]);const{setContentId:w}=x;return Xt(()=>(w(f),()=>{w(void 0)}),[f,w]),o.jsx(Nu,{asChild:!0,disableOutsidePointerEvents:!1,onEscapeKeyDown:p,onPointerDownOutside:g,onFocusOutside:E=>E.preventDefault(),onDismiss:b,children:o.jsxs(Qm,{"data-state":x.stateAttribute,role:u?void 0:"tooltip",id:u?void 0:x.contentId,...y,...v,ref:l,style:{...v.style,"--radix-tooltip-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-tooltip-content-available-width":"var(--radix-popper-available-width)","--radix-tooltip-content-available-height":"var(--radix-popper-available-height)","--radix-tooltip-trigger-width":"var(--radix-popper-anchor-width)","--radix-tooltip-trigger-height":"var(--radix-popper-anchor-height)"},children:[o.jsx(O4,{children:c}),u?o.jsx(RO,{id:x.contentId,role:"tooltip",children:u}):null]})})},"TooltipContentImpl"));function US(n,a){const l=Math.abs(a.top-n.y),s=Math.abs(a.bottom-n.y),c=Math.abs(a.right-n.x),u=Math.abs(a.left-n.x);switch(Math.min(l,s,c,u)){case u:return"left";case c:return"right";case l:return"top";case s:return"bottom";default:throw new Error("unreachable")}}Dn(US,"getExitSideFromRect");function BS(n,a,l=5){const s=[];switch(a){case"top":s.push({x:n.x-l,y:n.y+l},{x:n.x+l,y:n.y+l});break;case"bottom":s.push({x:n.x-l,y:n.y-l},{x:n.x+l,y:n.y-l});break;case"left":s.push({x:n.x+l,y:n.y-l},{x:n.x+l,y:n.y+l});break;case"right":s.push({x:n.x-l,y:n.y-l},{x:n.x-l,y:n.y+l});break}return s}Dn(BS,"getPaddedExitPoints");function HS(n){const{top:a,right:l,bottom:s,left:c}=n;return[{x:c,y:a},{x:l,y:a},{x:l,y:s},{x:c,y:s}]}Dn(HS,"getPointsFromRect");function IS(n,a){const{x:l,y:s}=n;let c=!1;for(let u=0,f=a.length-1;u<a.length;f=u++){const p=a[u],g=a[f],v=p.x,x=p.y,y=g.x,b=g.y;x>s!=b>s&&l<(y-v)*(s-x)/(b-x)+v&&(c=!c)}return c}Dn(IS,"isPointInPolygon");function PS(n){const a=n.slice();return a.sort((l,s)=>l.x<s.x?-1:l.x>s.x?1:l.y<s.y?-1:l.y>s.y?1:0),qS(a)}Dn(PS,"getHull");function qS(n){if(n.length<=1)return n.slice();const a=[];for(let s=0;s<n.length;s++){const c=n[s];for(;a.length>=2;){const u=a[a.length-1],f=a[a.length-2];if((u.x-f.x)*(c.y-f.y)>=(u.y-f.y)*(c.x-f.x))a.pop();else break}a.push(c)}a.pop();const l=[];for(let s=n.length-1;s>=0;s--){const c=n[s];for(;l.length>=2;){const u=l[l.length-1],f=l[l.length-2];if((u.x-f.x)*(c.y-f.y)>=(u.y-f.y)*(c.x-f.x))l.pop();else break}l.push(c)}return l.pop(),a.length===1&&l.length===1&&a[0].x===l[0].x&&a[0].y===l[0].y?a:a.concat(l)}Dn(qS,"getHullPresorted");var _4=R4,VS=A4;const k4=_4,z4=m.forwardRef(({className:n,sideOffset:a=4,...l},s)=>o.jsx(VS,{ref:s,sideOffset:a,className:Ee("z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95",n),...l}));z4.displayName=VS.displayName;d2.createRoot(document.getElementById("root")).render(o.jsx(ue.StrictMode,{children:o.jsx(hN,{defaultTheme:"dark",storageKey:"latedev-theme",children:o.jsxs(k4,{children:[o.jsx(kE,{children:o.jsx(x4,{})}),o.jsx(y4,{position:"top-right"})]})})}));
|
package/dist/web/index.html
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<meta name="color-scheme" content="light dark" />
|
|
8
8
|
<title>LateDev Router</title>
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-C868AUvW.js"></script>
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/assets/index-n9bGQMSj.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|