diff --git a/lightrag/__init__.py b/lightrag/__init__.py index 5433e327..99096ea0 100644 --- a/lightrag/__init__.py +++ b/lightrag/__init__.py @@ -1,5 +1,5 @@ from .lightrag import LightRAG as LightRAG, QueryParam as QueryParam -__version__ = "1.3.5" +__version__ = "1.3.6" __author__ = "Zirui Guo" __url__ = "https://github.com/HKUDS/LightRAG" diff --git a/lightrag/api/__init__.py b/lightrag/api/__init__.py index 244051c6..f43e00be 100644 --- a/lightrag/api/__init__.py +++ b/lightrag/api/__init__.py @@ -1 +1 @@ -__api_version__ = "0163" +__api_version__ = "0164" diff --git a/lightrag/api/webui/assets/feature-documents-DCEXq3Fi.js b/lightrag/api/webui/assets/feature-documents-DMvE8vgg.js similarity index 99% rename from lightrag/api/webui/assets/feature-documents-DCEXq3Fi.js rename to lightrag/api/webui/assets/feature-documents-DMvE8vgg.js index 52da6b23..929355a7 100644 --- a/lightrag/api/webui/assets/feature-documents-DCEXq3Fi.js +++ b/lightrag/api/webui/assets/feature-documents-DMvE8vgg.js @@ -2,7 +2,7 @@ import{j as i,_ as ee,d as Qa}from"./ui-vendor-CeCm8EER.js";import{r as p,g as S In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function $t(e){if(typeof Symbol<"u"&&e[Symbol.iterator]!=null||e["@@iterator"]!=null)return Array.from(e)}function Ht(e){if(Array.isArray(e))return Ke(e)}function wa(e,a){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);a&&(t=t.filter(function(o){return Object.getOwnPropertyDescriptor(e,o).enumerable})),n.push.apply(n,t)}return n}function ja(e){for(var a=1;ae.length)&&(a=e.length);for(var n=0,t=new Array(a);n0&&arguments[0]!==void 0?arguments[0]:"",n=a.split(","),t=n.length>1?"one of ".concat(n.join(", ")):n[0];return{code:Jt,message:"File type must be ".concat(t)}},ka=function(a){return{code:Vt,message:"File is larger than ".concat(a," ").concat(a===1?"byte":"bytes")}},Da=function(a){return{code:Xt,message:"File is smaller than ".concat(a," ").concat(a===1?"byte":"bytes")}},ei={code:Qt,message:"Too many files"};function Ba(e,a){var n=e.type==="application/x-moz-file"||Yt(e,a);return[n,n?null:Zt(a)]}function Ua(e,a,n){if(Z(e.size))if(Z(a)&&Z(n)){if(e.size>n)return[!1,ka(n)];if(e.sizen)return[!1,ka(n)]}return[!0,null]}function Z(e){return e!=null}function ai(e){var a=e.files,n=e.accept,t=e.minSize,o=e.maxSize,l=e.multiple,d=e.maxFiles,r=e.validator;return!l&&a.length>1||l&&d>=1&&a.length>d?!1:a.every(function(h){var b=Ba(h,n),v=pe(b,1),A=v[0],f=Ua(h,t,o),C=pe(f,1),P=C[0],M=r?r(h):null;return A&&P&&!M})}function be(e){return typeof e.isPropagationStopped=="function"?e.isPropagationStopped():typeof e.cancelBubble<"u"?e.cancelBubble:!1}function ge(e){return e.dataTransfer?Array.prototype.some.call(e.dataTransfer.types,function(a){return a==="Files"||a==="application/x-moz-file"}):!!e.target&&!!e.target.files}function za(e){e.preventDefault()}function ti(e){return e.indexOf("MSIE")!==-1||e.indexOf("Trident/")!==-1}function ii(e){return e.indexOf("Edge/")!==-1}function ni(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:window.navigator.userAgent;return ti(e)||ii(e)}function K(){for(var e=arguments.length,a=new Array(e),n=0;n1?o-1:0),d=1;de.length)&&(a=e.length);for(var n=0,t=new Array(a);n=0)&&Object.prototype.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}function wi(e,a){if(e==null)return{};var n={},t=Object.keys(e),o,l;for(l=0;l=0)&&(n[o]=e[o]);return n}var we=p.forwardRef(function(e,a){var n=e.children,t=ye(e,si),o=ji(t),l=o.open,d=ye(o,di);return p.useImperativeHandle(a,function(){return{open:l}},[l]),Za.createElement(p.Fragment,null,n(S(S({},d),{},{open:l})))});we.displayName="Dropzone";var Wa={disabled:!1,getFilesFromEvent:Ft,maxSize:1/0,minSize:0,multiple:!0,maxFiles:0,preventDropOnDocument:!0,noClick:!1,noKeyboard:!1,noDrag:!1,noDragEventsBubbling:!1,validator:null,useFsAccessApi:!1,autoFocus:!1};we.defaultProps=Wa;we.propTypes={children:z.func,accept:z.objectOf(z.arrayOf(z.string)),multiple:z.bool,preventDropOnDocument:z.bool,noClick:z.bool,noKeyboard:z.bool,noDrag:z.bool,noDragEventsBubbling:z.bool,minSize:z.number,maxSize:z.number,maxFiles:z.number,disabled:z.bool,getFilesFromEvent:z.func,onFileDialogCancel:z.func,onFileDialogOpen:z.func,useFsAccessApi:z.bool,autoFocus:z.bool,onDragEnter:z.func,onDragLeave:z.func,onDragOver:z.func,onDrop:z.func,onDropAccepted:z.func,onDropRejected:z.func,onError:z.func,validator:z.func};var Ye={isFocused:!1,isFileDialogActive:!1,isDragActive:!1,isDragAccept:!1,isDragReject:!1,acceptedFiles:[],fileRejections:[]};function ji(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},a=S(S({},Wa),e),n=a.accept,t=a.disabled,o=a.getFilesFromEvent,l=a.maxSize,d=a.minSize,r=a.multiple,h=a.maxFiles,b=a.onDragEnter,v=a.onDragLeave,A=a.onDragOver,f=a.onDrop,C=a.onDropAccepted,P=a.onDropRejected,M=a.onFileDialogCancel,x=a.onFileDialogOpen,N=a.useFsAccessApi,B=a.autoFocus,H=a.preventDropOnDocument,W=a.noClick,m=a.noKeyboard,g=a.noDrag,k=a.noDragEventsBubbling,E=a.onError,U=a.validator,c=p.useMemo(function(){return ri(n)},[n]),F=p.useMemo(function(){return li(n)},[n]),y=p.useMemo(function(){return typeof x=="function"?x:Na},[x]),D=p.useMemo(function(){return typeof M=="function"?M:Na},[M]),w=p.useRef(null),j=p.useRef(null),L=p.useReducer(ki,Ye),G=qe(L,2),Y=G[0],_=G[1],ce=Y.isFocused,aa=Y.isFileDialogActive,se=p.useRef(typeof window<"u"&&window.isSecureContext&&N&&oi()),ta=function(){!se.current&&aa&&setTimeout(function(){if(j.current){var u=j.current.files;u.length||(_({type:"closeDialog"}),D())}},300)};p.useEffect(function(){return window.addEventListener("focus",ta,!1),function(){window.removeEventListener("focus",ta,!1)}},[j,aa,D,se]);var ae=p.useRef([]),ia=function(u){w.current&&w.current.contains(u.target)||(u.preventDefault(),ae.current=[])};p.useEffect(function(){return H&&(document.addEventListener("dragover",za,!1),document.addEventListener("drop",ia,!1)),function(){H&&(document.removeEventListener("dragover",za),document.removeEventListener("drop",ia))}},[w,H]),p.useEffect(function(){return!t&&B&&w.current&&w.current.focus(),function(){}},[w,B,t]);var Q=p.useCallback(function(s){E?E(s):console.error(s)},[E]),na=p.useCallback(function(s){s.preventDefault(),s.persist(),fe(s),ae.current=[].concat(fi(ae.current),[s.target]),ge(s)&&Promise.resolve(o(s)).then(function(u){if(!(be(s)&&!k)){var T=u.length,R=T>0&&ai({files:u,accept:c,minSize:d,maxSize:l,multiple:r,maxFiles:h,validator:U}),$=T>0&&!R;_({isDragAccept:R,isDragReject:$,isDragActive:!0,type:"setDraggedFiles"}),b&&b(s)}}).catch(function(u){return Q(u)})},[o,b,Q,k,c,d,l,r,h,U]),oa=p.useCallback(function(s){s.preventDefault(),s.persist(),fe(s);var u=ge(s);if(u&&s.dataTransfer)try{s.dataTransfer.dropEffect="copy"}catch{}return u&&A&&A(s),!1},[A,k]),la=p.useCallback(function(s){s.preventDefault(),s.persist(),fe(s);var u=ae.current.filter(function(R){return w.current&&w.current.contains(R)}),T=u.indexOf(s.target);T!==-1&&u.splice(T,1),ae.current=u,!(u.length>0)&&(_({type:"setDraggedFiles",isDragActive:!1,isDragAccept:!1,isDragReject:!1}),ge(s)&&v&&v(s))},[w,v,k]),de=p.useCallback(function(s,u){var T=[],R=[];s.forEach(function($){var re=Ba($,c),ne=qe(re,2),ke=ne[0],De=ne[1],ze=Ua($,d,l),xe=qe(ze,2),Pe=xe[0],Ne=xe[1],Ee=U?U($):null;if(ke&&Pe&&!Ee)T.push($);else{var Ce=[De,Ne];Ee&&(Ce=Ce.concat(Ee)),R.push({file:$,errors:Ce.filter(function(Xa){return Xa})})}}),(!r&&T.length>1||r&&h>=1&&T.length>h)&&(T.forEach(function($){R.push({file:$,errors:[ei]})}),T.splice(0)),_({acceptedFiles:T,fileRejections:R,isDragReject:R.length>0,type:"setFiles"}),f&&f(T,R,u),R.length>0&&P&&P(R,u),T.length>0&&C&&C(T,u)},[_,r,c,d,l,h,f,C,P,U]),me=p.useCallback(function(s){s.preventDefault(),s.persist(),fe(s),ae.current=[],ge(s)&&Promise.resolve(o(s)).then(function(u){be(s)&&!k||de(u,s)}).catch(function(u){return Q(u)}),_({type:"reset"})},[o,de,Q,k]),te=p.useCallback(function(){if(se.current){_({type:"openDialog"}),y();var s={multiple:r,types:F};window.showOpenFilePicker(s).then(function(u){return o(u)}).then(function(u){de(u,null),_({type:"closeDialog"})}).catch(function(u){pi(u)?(D(u),_({type:"closeDialog"})):ci(u)?(se.current=!1,j.current?(j.current.value=null,j.current.click()):Q(new Error("Cannot open the file picker because the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API is not supported and no was provided."))):Q(u)});return}j.current&&(_({type:"openDialog"}),y(),j.current.value=null,j.current.click())},[_,y,D,N,de,Q,F,r]),ra=p.useCallback(function(s){!w.current||!w.current.isEqualNode(s.target)||(s.key===" "||s.key==="Enter"||s.keyCode===32||s.keyCode===13)&&(s.preventDefault(),te())},[w,te]),pa=p.useCallback(function(){_({type:"focus"})},[]),ca=p.useCallback(function(){_({type:"blur"})},[]),sa=p.useCallback(function(){W||(ni()?setTimeout(te,0):te())},[W,te]),ie=function(u){return t?null:u},je=function(u){return m?null:ie(u)},ue=function(u){return g?null:ie(u)},fe=function(u){k&&u.stopPropagation()},Ya=p.useMemo(function(){return function(){var s=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},u=s.refKey,T=u===void 0?"ref":u,R=s.role,$=s.onKeyDown,re=s.onFocus,ne=s.onBlur,ke=s.onClick,De=s.onDragEnter,ze=s.onDragOver,xe=s.onDragLeave,Pe=s.onDrop,Ne=ye(s,mi);return S(S(Ge({onKeyDown:je(K($,ra)),onFocus:je(K(re,pa)),onBlur:je(K(ne,ca)),onClick:ie(K(ke,sa)),onDragEnter:ue(K(De,na)),onDragOver:ue(K(ze,oa)),onDragLeave:ue(K(xe,la)),onDrop:ue(K(Pe,me)),role:typeof R=="string"&&R!==""?R:"presentation"},T,w),!t&&!m?{tabIndex:0}:{}),Ne)}},[w,ra,pa,ca,sa,na,oa,la,me,m,g,t]),Ja=p.useCallback(function(s){s.stopPropagation()},[]),Va=p.useMemo(function(){return function(){var s=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},u=s.refKey,T=u===void 0?"ref":u,R=s.onChange,$=s.onClick,re=ye(s,ui),ne=Ge({accept:c,multiple:r,type:"file",style:{border:0,clip:"rect(0, 0, 0, 0)",clipPath:"inset(50%)",height:"1px",margin:"0 -1px -1px 0",overflow:"hidden",padding:0,position:"absolute",width:"1px",whiteSpace:"nowrap"},onChange:ie(K(R,me)),onClick:ie(K($,Ja)),tabIndex:-1},T,j);return S(S({},ne),re)}},[j,n,r,me,t]);return S(S({},Y),{},{isFocused:ce&&!t,getRootProps:Ya,getInputProps:Va,rootRef:w,inputRef:j,open:ie(te)})}function ki(e,a){switch(a.type){case"focus":return S(S({},e),{},{isFocused:!0});case"blur":return S(S({},e),{},{isFocused:!1});case"openDialog":return S(S({},Ye),{},{isFileDialogActive:!0});case"closeDialog":return S(S({},e),{},{isFileDialogActive:!1});case"setDraggedFiles":return S(S({},e),{},{isDragActive:a.isDragActive,isDragAccept:a.isDragAccept,isDragReject:a.isDragReject});case"setFiles":return S(S({},e),{},{acceptedFiles:a.acceptedFiles,fileRejections:a.fileRejections,isDragReject:a.isDragReject});case"reset":return S({},Ye);default:return e}}function Na(){}function Je(e,a={}){const{decimals:n=0,sizeType:t="normal"}=a,o=["Bytes","KB","MB","GB","TB"],l=["Bytes","KiB","MiB","GiB","TiB"];if(e===0)return"0 Byte";const d=Math.floor(Math.log(e)/Math.log(1024));return`${(e/Math.pow(1024,d)).toFixed(n)} ${t==="accurate"?l[d]??"Bytes":o[d]??"Bytes"}`}function Di(e){const{t:a}=le(),{value:n,onValueChange:t,onUpload:o,onReject:l,progresses:d,fileErrors:r,accept:h=at,maxSize:b=1024*1024*200,maxFileCount:v=1,multiple:A=!1,disabled:f=!1,description:C,className:P,...M}=e,[x,N]=Qa({prop:n,onChange:t}),B=p.useCallback((m,g)=>{const k=((x==null?void 0:x.length)??0)+m.length+g.length;if(!A&&v===1&&m.length+g.length>1){q.error(a("documentPanel.uploadDocuments.fileUploader.singleFileLimit"));return}if(k>v){q.error(a("documentPanel.uploadDocuments.fileUploader.maxFilesLimit",{count:v}));return}g.length>0&&(l?l(g):g.forEach(({file:y})=>{q.error(a("documentPanel.uploadDocuments.fileUploader.fileRejected",{name:y.name}))}));const E=m.map(y=>Object.assign(y,{preview:URL.createObjectURL(y)})),U=g.map(({file:y})=>Object.assign(y,{preview:URL.createObjectURL(y),rejected:!0})),c=[...E,...U],F=x?[...x,...c]:c;if(N(F),o&&m.length>0){const y=m.filter(D=>{var G;if(!D.name)return!1;const w=`.${((G=D.name.split(".").pop())==null?void 0:G.toLowerCase())||""}`,j=Object.entries(h||{}).some(([Y,_])=>D.type===Y||Array.isArray(_)&&_.includes(w)),L=D.size<=b;return j&&L});y.length>0&&o(y)}},[x,v,A,o,l,N,a,h,b]);function H(m){if(!x)return;const g=x.filter((k,E)=>E!==m);N(g),t==null||t(g)}p.useEffect(()=>()=>{x&&x.forEach(m=>{Ga(m)&&URL.revokeObjectURL(m.preview)})},[]);const W=f||((x==null?void 0:x.length)??0)>=v;return i.jsxs("div",{className:"relative flex flex-col gap-6 overflow-hidden",children:[i.jsx(we,{onDrop:B,noClick:!1,noKeyboard:!1,maxSize:b,maxFiles:v,multiple:v>1||A,disabled:W,validator:m=>{var E;if(!m.name)return{code:"invalid-file-name",message:a("documentPanel.uploadDocuments.fileUploader.invalidFileName",{fallback:"Invalid file name"})};const g=`.${((E=m.name.split(".").pop())==null?void 0:E.toLowerCase())||""}`;return Object.entries(h||{}).some(([U,c])=>m.type===U||Array.isArray(c)&&c.includes(g))?m.size>b?{code:"file-too-large",message:a("documentPanel.uploadDocuments.fileUploader.fileTooLarge",{maxSize:Je(b)})}:null:{code:"file-invalid-type",message:a("documentPanel.uploadDocuments.fileUploader.unsupportedType")}},children:({getRootProps:m,getInputProps:g,isDragActive:k})=>i.jsxs("div",{...m(),className:O("group border-muted-foreground/25 hover:bg-muted/25 relative grid h-52 w-full cursor-pointer place-items-center rounded-lg border-2 border-dashed px-5 py-2.5 text-center transition","ring-offset-background focus-visible:ring-ring focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none",k&&"border-muted-foreground/50",W&&"pointer-events-none opacity-60",P),...M,children:[i.jsx("input",{...g()}),k?i.jsxs("div",{className:"flex flex-col items-center justify-center gap-4 sm:px-5",children:[i.jsx("div",{className:"rounded-full border border-dashed p-3",children:i.jsx(Ue,{className:"text-muted-foreground size-7","aria-hidden":"true"})}),i.jsx("p",{className:"text-muted-foreground font-medium",children:a("documentPanel.uploadDocuments.fileUploader.dropHere")})]}):i.jsxs("div",{className:"flex flex-col items-center justify-center gap-4 sm:px-5",children:[i.jsx("div",{className:"rounded-full border border-dashed p-3",children:i.jsx(Ue,{className:"text-muted-foreground size-7","aria-hidden":"true"})}),i.jsxs("div",{className:"flex flex-col gap-px",children:[i.jsx("p",{className:"text-muted-foreground font-medium",children:a("documentPanel.uploadDocuments.fileUploader.dragAndDrop")}),C?i.jsx("p",{className:"text-muted-foreground/70 text-sm",children:C}):i.jsxs("p",{className:"text-muted-foreground/70 text-sm",children:[a("documentPanel.uploadDocuments.fileUploader.uploadDescription",{count:v,isMultiple:v===1/0,maxSize:Je(b)}),a("documentPanel.uploadDocuments.fileTypes")]})]})]})]})}),x!=null&&x.length?i.jsx(tt,{className:"h-fit w-full px-3",children:i.jsx("div",{className:"flex max-h-48 flex-col gap-4",children:x==null?void 0:x.map((m,g)=>i.jsx(zi,{file:m,onRemove:()=>H(g),progress:d==null?void 0:d[m.name],error:r==null?void 0:r[m.name]},g))})}):null]})}function Ea({value:e,error:a}){return i.jsx("div",{className:"relative h-2 w-full",children:i.jsx("div",{className:"h-full w-full overflow-hidden rounded-full bg-secondary",children:i.jsx("div",{className:O("h-full transition-all",a?"bg-red-400":"bg-primary"),style:{width:`${e}%`}})})})}function zi({file:e,progress:a,error:n,onRemove:t}){const{t:o}=le();return i.jsxs("div",{className:"relative flex items-center gap-2.5",children:[i.jsxs("div",{className:"flex flex-1 gap-2.5",children:[n?i.jsx(Oa,{className:"text-red-400 size-10","aria-hidden":"true"}):Ga(e)?i.jsx(Pi,{file:e}):null,i.jsxs("div",{className:"flex w-full flex-col gap-2",children:[i.jsxs("div",{className:"flex flex-col gap-px",children:[i.jsx("p",{className:"text-foreground/80 line-clamp-1 text-sm font-medium",children:e.name}),i.jsx("p",{className:"text-muted-foreground text-xs",children:Je(e.size)})]}),n?i.jsxs("div",{className:"text-red-400 text-sm",children:[i.jsx("div",{className:"relative mb-2",children:i.jsx(Ea,{value:100,error:!0})}),i.jsx("p",{children:n})]}):a?i.jsx(Ea,{value:a}):null]})]}),i.jsx("div",{className:"flex items-center gap-2",children:i.jsxs(I,{type:"button",variant:"outline",size:"icon",className:"size-7",onClick:t,children:[i.jsx(it,{className:"size-4","aria-hidden":"true"}),i.jsx("span",{className:"sr-only",children:o("documentPanel.uploadDocuments.fileUploader.removeFile")})]})})]})}function Ga(e){return"preview"in e&&typeof e.preview=="string"}function Pi({file:e}){return e.type.startsWith("image/")?i.jsx("div",{className:"aspect-square shrink-0 rounded-md object-cover"}):i.jsx(Oa,{className:"text-muted-foreground size-10","aria-hidden":"true"})}function Ni({onDocumentsUploaded:e}){const{t:a}=le(),[n,t]=p.useState(!1),[o,l]=p.useState(!1),[d,r]=p.useState({}),[h,b]=p.useState({}),v=p.useCallback(f=>{f.forEach(({file:C,errors:P})=>{var x;let M=((x=P[0])==null?void 0:x.message)||a("documentPanel.uploadDocuments.fileUploader.fileRejected",{name:C.name});M.includes("file-invalid-type")&&(M=a("documentPanel.uploadDocuments.fileUploader.unsupportedType")),r(N=>({...N,[C.name]:100})),b(N=>({...N,[C.name]:M}))})},[r,b,a]),A=p.useCallback(async f=>{var M,x;l(!0);let C=!1;b(N=>{const B={...N};return f.forEach(H=>{delete B[H.name]}),B});const P=q.loading(a("documentPanel.uploadDocuments.batch.uploading"));try{const N={},B=new Intl.Collator(["zh-CN","en"],{sensitivity:"accent",numeric:!0}),H=[...f].sort((m,g)=>B.compare(m.name,g.name));for(const m of H)try{r(k=>({...k,[m.name]:0}));const g=await nt(m,k=>{console.debug(a("documentPanel.uploadDocuments.single.uploading",{name:m.name,percent:k})),r(E=>({...E,[m.name]:k}))});g.status==="duplicated"?(N[m.name]=a("documentPanel.uploadDocuments.fileUploader.duplicateFile"),b(k=>({...k,[m.name]:a("documentPanel.uploadDocuments.fileUploader.duplicateFile")}))):g.status!=="success"?(N[m.name]=g.message,b(k=>({...k,[m.name]:g.message}))):C=!0}catch(g){console.error(`Upload failed for ${m.name}:`,g);let k=X(g);if(g&&typeof g=="object"&&"response"in g){const E=g;((M=E.response)==null?void 0:M.status)===400&&(k=((x=E.response.data)==null?void 0:x.detail)||k),r(U=>({...U,[m.name]:100}))}N[m.name]=k,b(E=>({...E,[m.name]:k}))}Object.keys(N).length>0?q.error(a("documentPanel.uploadDocuments.batch.error"),{id:P}):q.success(a("documentPanel.uploadDocuments.batch.success"),{id:P}),C&&e&&e().catch(m=>{console.error("Error refreshing documents:",m)})}catch(N){console.error("Unexpected error during upload:",N),q.error(a("documentPanel.uploadDocuments.generalError",{error:X(N)}),{id:P})}finally{l(!1)}},[l,r,b,a,e]);return i.jsxs(Ve,{open:n,onOpenChange:f=>{o||(f||(r({}),b({})),t(f))},children:[i.jsx(Aa,{asChild:!0,children:i.jsxs(I,{variant:"default",side:"bottom",tooltip:a("documentPanel.uploadDocuments.tooltip"),size:"sm",children:[i.jsx(Ue,{})," ",a("documentPanel.uploadDocuments.button")]})}),i.jsxs(Xe,{className:"sm:max-w-xl",onCloseAutoFocus:f=>f.preventDefault(),children:[i.jsxs(Qe,{children:[i.jsx(Ze,{children:a("documentPanel.uploadDocuments.title")}),i.jsx(ea,{children:a("documentPanel.uploadDocuments.description")})]}),i.jsx(Di,{maxFileCount:1/0,maxSize:200*1024*1024,description:a("documentPanel.uploadDocuments.fileTypes"),onUpload:A,onReject:v,progresses:d,fileErrors:h,disabled:o})]})]})}const Ca=({htmlFor:e,className:a,children:n,...t})=>i.jsx("label",{htmlFor:e,className:a,...t,children:n});function Ei({onDocumentsCleared:e}){const{t:a}=le(),[n,t]=p.useState(!1),[o,l]=p.useState(""),[d,r]=p.useState(!1),h=o.toLowerCase()==="yes";p.useEffect(()=>{n||(l(""),r(!1))},[n]);const b=p.useCallback(async()=>{if(h)try{const v=await ot();if(v.status!=="success"){q.error(a("documentPanel.clearDocuments.failed",{message:v.message})),l("");return}if(q.success(a("documentPanel.clearDocuments.success")),d)try{await lt(),q.success(a("documentPanel.clearDocuments.cacheCleared"))}catch(A){q.error(a("documentPanel.clearDocuments.cacheClearFailed",{error:X(A)}))}e&&e().catch(console.error),t(!1)}catch(v){q.error(a("documentPanel.clearDocuments.error",{error:X(v)})),l("")}},[h,d,t,a,e]);return i.jsxs(Ve,{open:n,onOpenChange:t,children:[i.jsx(Aa,{asChild:!0,children:i.jsxs(I,{variant:"outline",side:"bottom",tooltip:a("documentPanel.clearDocuments.tooltip"),size:"sm",children:[i.jsx(rt,{})," ",a("documentPanel.clearDocuments.button")]})}),i.jsxs(Xe,{className:"sm:max-w-xl",onCloseAutoFocus:v=>v.preventDefault(),children:[i.jsxs(Qe,{children:[i.jsxs(Ze,{className:"flex items-center gap-2 text-red-500 dark:text-red-400 font-bold",children:[i.jsx(pt,{className:"h-5 w-5"}),a("documentPanel.clearDocuments.title")]}),i.jsx(ea,{className:"pt-2",children:a("documentPanel.clearDocuments.description")})]}),i.jsx("div",{className:"text-red-500 dark:text-red-400 font-semibold mb-4",children:a("documentPanel.clearDocuments.warning")}),i.jsx("div",{className:"mb-4",children:a("documentPanel.clearDocuments.confirm")}),i.jsxs("div",{className:"space-y-4",children:[i.jsxs("div",{className:"space-y-2",children:[i.jsx(Ca,{htmlFor:"confirm-text",className:"text-sm font-medium",children:a("documentPanel.clearDocuments.confirmPrompt")}),i.jsx(ct,{id:"confirm-text",value:o,onChange:v=>l(v.target.value),placeholder:a("documentPanel.clearDocuments.confirmPlaceholder"),className:"w-full"})]}),i.jsxs("div",{className:"flex items-center space-x-2",children:[i.jsx(st,{id:"clear-cache",checked:d,onCheckedChange:v=>r(v===!0)}),i.jsx(Ca,{htmlFor:"clear-cache",className:"text-sm font-medium cursor-pointer",children:a("documentPanel.clearDocuments.clearCache")})]})]}),i.jsxs(dt,{children:[i.jsx(I,{variant:"outline",onClick:()=>t(!1),children:a("common.cancel")}),i.jsx(I,{variant:"destructive",onClick:b,disabled:!h,children:a("documentPanel.clearDocuments.confirmButton")})]})]})]})}function Ci({open:e,onOpenChange:a}){var A;const{t:n}=le(),[t,o]=p.useState(null),[l,d]=p.useState("center"),[r,h]=p.useState(!1),b=p.useRef(null);p.useEffect(()=>{e&&(d("center"),h(!1))},[e]),p.useEffect(()=>{const f=b.current;!f||r||(f.scrollTop=f.scrollHeight)},[t==null?void 0:t.history_messages,r]);const v=()=>{const f=b.current;if(!f)return;const C=Math.abs(f.scrollHeight-f.scrollTop-f.clientHeight)<1;h(!C)};return p.useEffect(()=>{if(!e)return;const f=async()=>{try{const P=await xt();o(P)}catch(P){q.error(n("documentPanel.pipelineStatus.errors.fetchFailed",{error:X(P)}))}};f();const C=setInterval(f,2e3);return()=>clearInterval(C)},[e,n]),i.jsx(Ve,{open:e,onOpenChange:a,children:i.jsxs(Xe,{className:O("sm:max-w-[600px] transition-all duration-200 fixed",l==="left"&&"!left-[25%] !translate-x-[-50%] !mx-4",l==="center"&&"!left-1/2 !-translate-x-1/2",l==="right"&&"!left-[75%] !translate-x-[-50%] !mx-4"),children:[i.jsx(ea,{className:"sr-only",children:t!=null&&t.job_name?`${n("documentPanel.pipelineStatus.jobName")}: ${t.job_name}, ${n("documentPanel.pipelineStatus.progress")}: ${t.cur_batch}/${t.batchs}`:n("documentPanel.pipelineStatus.noActiveJob")}),i.jsxs(Qe,{className:"flex flex-row items-center",children:[i.jsx(Ze,{className:"flex-1",children:n("documentPanel.pipelineStatus.title")}),i.jsxs("div",{className:"flex items-center gap-2 mr-8",children:[i.jsx(I,{variant:"ghost",size:"icon",className:O("h-6 w-6",l==="left"&&"bg-zinc-200 text-zinc-800 hover:bg-zinc-300 dark:bg-zinc-700 dark:text-zinc-200 dark:hover:bg-zinc-600"),onClick:()=>d("left"),children:i.jsx(mt,{className:"h-4 w-4"})}),i.jsx(I,{variant:"ghost",size:"icon",className:O("h-6 w-6",l==="center"&&"bg-zinc-200 text-zinc-800 hover:bg-zinc-300 dark:bg-zinc-700 dark:text-zinc-200 dark:hover:bg-zinc-600"),onClick:()=>d("center"),children:i.jsx(ut,{className:"h-4 w-4"})}),i.jsx(I,{variant:"ghost",size:"icon",className:O("h-6 w-6",l==="right"&&"bg-zinc-200 text-zinc-800 hover:bg-zinc-300 dark:bg-zinc-700 dark:text-zinc-200 dark:hover:bg-zinc-600"),onClick:()=>d("right"),children:i.jsx(ft,{className:"h-4 w-4"})})]})]}),i.jsxs("div",{className:"space-y-4 pt-4",children:[i.jsxs("div",{className:"flex items-center gap-4",children:[i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsxs("div",{className:"text-sm font-medium",children:[n("documentPanel.pipelineStatus.busy"),":"]}),i.jsx("div",{className:`h-2 w-2 rounded-full ${t!=null&&t.busy?"bg-green-500":"bg-gray-300"}`})]}),i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsxs("div",{className:"text-sm font-medium",children:[n("documentPanel.pipelineStatus.requestPending"),":"]}),i.jsx("div",{className:`h-2 w-2 rounded-full ${t!=null&&t.request_pending?"bg-green-500":"bg-gray-300"}`})]})]}),i.jsxs("div",{className:"rounded-md border p-3 space-y-2",children:[i.jsxs("div",{children:[n("documentPanel.pipelineStatus.jobName"),": ",(t==null?void 0:t.job_name)||"-"]}),i.jsxs("div",{className:"flex justify-between",children:[i.jsxs("span",{children:[n("documentPanel.pipelineStatus.startTime"),": ",t!=null&&t.job_start?new Date(t.job_start).toLocaleString():"-"]}),i.jsxs("span",{children:[n("documentPanel.pipelineStatus.progress"),": ",t?`${t.cur_batch}/${t.batchs} ${n("documentPanel.pipelineStatus.unit")}`:"-"]})]})]}),i.jsxs("div",{className:"space-y-2",children:[i.jsxs("div",{className:"text-sm font-medium",children:[n("documentPanel.pipelineStatus.latestMessage"),":"]}),i.jsx("div",{className:"font-mono text-xs rounded-md bg-zinc-800 text-zinc-100 p-3",children:(t==null?void 0:t.latest_message)||"-"})]}),i.jsxs("div",{className:"space-y-2",children:[i.jsxs("div",{className:"text-sm font-medium",children:[n("documentPanel.pipelineStatus.historyMessages"),":"]}),i.jsx("div",{ref:b,onScroll:v,className:"font-mono text-xs rounded-md bg-zinc-800 text-zinc-100 p-3 overflow-y-auto min-h-[7.5em] max-h-[40vh]",children:(A=t==null?void 0:t.history_messages)!=null&&A.length?t.history_messages.map((f,C)=>i.jsx("div",{children:f},C)):"-"})]})]})]})})}const Ie=(e,a=20)=>{if(!e.file_path||typeof e.file_path!="string"||e.file_path.trim()==="")return e.id;const n=e.file_path.split("/"),t=n[n.length-1];return!t||t.trim()===""?e.id:t.length>a?t.slice(0,a)+"...":t},Si=` +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function Ka(e,a){if(e){if(typeof e=="string")return We(e,a);var n=Object.prototype.toString.call(e).slice(8,-1);if(n==="Object"&&e.constructor&&(n=e.constructor.name),n==="Map"||n==="Set")return Array.from(e);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return We(e,a)}}function We(e,a){(a==null||a>e.length)&&(a=e.length);for(var n=0,t=new Array(a);n=0)&&Object.prototype.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}function wi(e,a){if(e==null)return{};var n={},t=Object.keys(e),o,l;for(l=0;l=0)&&(n[o]=e[o]);return n}var we=p.forwardRef(function(e,a){var n=e.children,t=ye(e,si),o=ji(t),l=o.open,d=ye(o,di);return p.useImperativeHandle(a,function(){return{open:l}},[l]),Za.createElement(p.Fragment,null,n(S(S({},d),{},{open:l})))});we.displayName="Dropzone";var Wa={disabled:!1,getFilesFromEvent:Ft,maxSize:1/0,minSize:0,multiple:!0,maxFiles:0,preventDropOnDocument:!0,noClick:!1,noKeyboard:!1,noDrag:!1,noDragEventsBubbling:!1,validator:null,useFsAccessApi:!1,autoFocus:!1};we.defaultProps=Wa;we.propTypes={children:z.func,accept:z.objectOf(z.arrayOf(z.string)),multiple:z.bool,preventDropOnDocument:z.bool,noClick:z.bool,noKeyboard:z.bool,noDrag:z.bool,noDragEventsBubbling:z.bool,minSize:z.number,maxSize:z.number,maxFiles:z.number,disabled:z.bool,getFilesFromEvent:z.func,onFileDialogCancel:z.func,onFileDialogOpen:z.func,useFsAccessApi:z.bool,autoFocus:z.bool,onDragEnter:z.func,onDragLeave:z.func,onDragOver:z.func,onDrop:z.func,onDropAccepted:z.func,onDropRejected:z.func,onError:z.func,validator:z.func};var Ye={isFocused:!1,isFileDialogActive:!1,isDragActive:!1,isDragAccept:!1,isDragReject:!1,acceptedFiles:[],fileRejections:[]};function ji(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},a=S(S({},Wa),e),n=a.accept,t=a.disabled,o=a.getFilesFromEvent,l=a.maxSize,d=a.minSize,r=a.multiple,h=a.maxFiles,b=a.onDragEnter,v=a.onDragLeave,A=a.onDragOver,f=a.onDrop,C=a.onDropAccepted,P=a.onDropRejected,M=a.onFileDialogCancel,x=a.onFileDialogOpen,N=a.useFsAccessApi,B=a.autoFocus,H=a.preventDropOnDocument,W=a.noClick,m=a.noKeyboard,g=a.noDrag,k=a.noDragEventsBubbling,E=a.onError,U=a.validator,c=p.useMemo(function(){return ri(n)},[n]),F=p.useMemo(function(){return li(n)},[n]),y=p.useMemo(function(){return typeof x=="function"?x:Na},[x]),D=p.useMemo(function(){return typeof M=="function"?M:Na},[M]),w=p.useRef(null),j=p.useRef(null),L=p.useReducer(ki,Ye),G=qe(L,2),Y=G[0],_=G[1],ce=Y.isFocused,aa=Y.isFileDialogActive,se=p.useRef(typeof window<"u"&&window.isSecureContext&&N&&oi()),ta=function(){!se.current&&aa&&setTimeout(function(){if(j.current){var u=j.current.files;u.length||(_({type:"closeDialog"}),D())}},300)};p.useEffect(function(){return window.addEventListener("focus",ta,!1),function(){window.removeEventListener("focus",ta,!1)}},[j,aa,D,se]);var ae=p.useRef([]),ia=function(u){w.current&&w.current.contains(u.target)||(u.preventDefault(),ae.current=[])};p.useEffect(function(){return H&&(document.addEventListener("dragover",za,!1),document.addEventListener("drop",ia,!1)),function(){H&&(document.removeEventListener("dragover",za),document.removeEventListener("drop",ia))}},[w,H]),p.useEffect(function(){return!t&&B&&w.current&&w.current.focus(),function(){}},[w,B,t]);var Q=p.useCallback(function(s){E?E(s):console.error(s)},[E]),na=p.useCallback(function(s){s.preventDefault(),s.persist(),fe(s),ae.current=[].concat(fi(ae.current),[s.target]),ge(s)&&Promise.resolve(o(s)).then(function(u){if(!(be(s)&&!k)){var T=u.length,R=T>0&&ai({files:u,accept:c,minSize:d,maxSize:l,multiple:r,maxFiles:h,validator:U}),$=T>0&&!R;_({isDragAccept:R,isDragReject:$,isDragActive:!0,type:"setDraggedFiles"}),b&&b(s)}}).catch(function(u){return Q(u)})},[o,b,Q,k,c,d,l,r,h,U]),oa=p.useCallback(function(s){s.preventDefault(),s.persist(),fe(s);var u=ge(s);if(u&&s.dataTransfer)try{s.dataTransfer.dropEffect="copy"}catch{}return u&&A&&A(s),!1},[A,k]),la=p.useCallback(function(s){s.preventDefault(),s.persist(),fe(s);var u=ae.current.filter(function(R){return w.current&&w.current.contains(R)}),T=u.indexOf(s.target);T!==-1&&u.splice(T,1),ae.current=u,!(u.length>0)&&(_({type:"setDraggedFiles",isDragActive:!1,isDragAccept:!1,isDragReject:!1}),ge(s)&&v&&v(s))},[w,v,k]),de=p.useCallback(function(s,u){var T=[],R=[];s.forEach(function($){var re=Ba($,c),ne=qe(re,2),ke=ne[0],De=ne[1],ze=Ua($,d,l),xe=qe(ze,2),Pe=xe[0],Ne=xe[1],Ee=U?U($):null;if(ke&&Pe&&!Ee)T.push($);else{var Ce=[De,Ne];Ee&&(Ce=Ce.concat(Ee)),R.push({file:$,errors:Ce.filter(function(Xa){return Xa})})}}),(!r&&T.length>1||r&&h>=1&&T.length>h)&&(T.forEach(function($){R.push({file:$,errors:[ei]})}),T.splice(0)),_({acceptedFiles:T,fileRejections:R,isDragReject:R.length>0,type:"setFiles"}),f&&f(T,R,u),R.length>0&&P&&P(R,u),T.length>0&&C&&C(T,u)},[_,r,c,d,l,h,f,C,P,U]),me=p.useCallback(function(s){s.preventDefault(),s.persist(),fe(s),ae.current=[],ge(s)&&Promise.resolve(o(s)).then(function(u){be(s)&&!k||de(u,s)}).catch(function(u){return Q(u)}),_({type:"reset"})},[o,de,Q,k]),te=p.useCallback(function(){if(se.current){_({type:"openDialog"}),y();var s={multiple:r,types:F};window.showOpenFilePicker(s).then(function(u){return o(u)}).then(function(u){de(u,null),_({type:"closeDialog"})}).catch(function(u){pi(u)?(D(u),_({type:"closeDialog"})):ci(u)?(se.current=!1,j.current?(j.current.value=null,j.current.click()):Q(new Error("Cannot open the file picker because the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API is not supported and no was provided."))):Q(u)});return}j.current&&(_({type:"openDialog"}),y(),j.current.value=null,j.current.click())},[_,y,D,N,de,Q,F,r]),ra=p.useCallback(function(s){!w.current||!w.current.isEqualNode(s.target)||(s.key===" "||s.key==="Enter"||s.keyCode===32||s.keyCode===13)&&(s.preventDefault(),te())},[w,te]),pa=p.useCallback(function(){_({type:"focus"})},[]),ca=p.useCallback(function(){_({type:"blur"})},[]),sa=p.useCallback(function(){W||(ni()?setTimeout(te,0):te())},[W,te]),ie=function(u){return t?null:u},je=function(u){return m?null:ie(u)},ue=function(u){return g?null:ie(u)},fe=function(u){k&&u.stopPropagation()},Ya=p.useMemo(function(){return function(){var s=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},u=s.refKey,T=u===void 0?"ref":u,R=s.role,$=s.onKeyDown,re=s.onFocus,ne=s.onBlur,ke=s.onClick,De=s.onDragEnter,ze=s.onDragOver,xe=s.onDragLeave,Pe=s.onDrop,Ne=ye(s,mi);return S(S(Ge({onKeyDown:je(K($,ra)),onFocus:je(K(re,pa)),onBlur:je(K(ne,ca)),onClick:ie(K(ke,sa)),onDragEnter:ue(K(De,na)),onDragOver:ue(K(ze,oa)),onDragLeave:ue(K(xe,la)),onDrop:ue(K(Pe,me)),role:typeof R=="string"&&R!==""?R:"presentation"},T,w),!t&&!m?{tabIndex:0}:{}),Ne)}},[w,ra,pa,ca,sa,na,oa,la,me,m,g,t]),Ja=p.useCallback(function(s){s.stopPropagation()},[]),Va=p.useMemo(function(){return function(){var s=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},u=s.refKey,T=u===void 0?"ref":u,R=s.onChange,$=s.onClick,re=ye(s,ui),ne=Ge({accept:c,multiple:r,type:"file",style:{border:0,clip:"rect(0, 0, 0, 0)",clipPath:"inset(50%)",height:"1px",margin:"0 -1px -1px 0",overflow:"hidden",padding:0,position:"absolute",width:"1px",whiteSpace:"nowrap"},onChange:ie(K(R,me)),onClick:ie(K($,Ja)),tabIndex:-1},T,j);return S(S({},ne),re)}},[j,n,r,me,t]);return S(S({},Y),{},{isFocused:ce&&!t,getRootProps:Ya,getInputProps:Va,rootRef:w,inputRef:j,open:ie(te)})}function ki(e,a){switch(a.type){case"focus":return S(S({},e),{},{isFocused:!0});case"blur":return S(S({},e),{},{isFocused:!1});case"openDialog":return S(S({},Ye),{},{isFileDialogActive:!0});case"closeDialog":return S(S({},e),{},{isFileDialogActive:!1});case"setDraggedFiles":return S(S({},e),{},{isDragActive:a.isDragActive,isDragAccept:a.isDragAccept,isDragReject:a.isDragReject});case"setFiles":return S(S({},e),{},{acceptedFiles:a.acceptedFiles,fileRejections:a.fileRejections,isDragReject:a.isDragReject});case"reset":return S({},Ye);default:return e}}function Na(){}function Je(e,a={}){const{decimals:n=0,sizeType:t="normal"}=a,o=["Bytes","KB","MB","GB","TB"],l=["Bytes","KiB","MiB","GiB","TiB"];if(e===0)return"0 Byte";const d=Math.floor(Math.log(e)/Math.log(1024));return`${(e/Math.pow(1024,d)).toFixed(n)} ${t==="accurate"?l[d]??"Bytes":o[d]??"Bytes"}`}function Di(e){const{t:a}=le(),{value:n,onValueChange:t,onUpload:o,onReject:l,progresses:d,fileErrors:r,accept:h=at,maxSize:b=1024*1024*200,maxFileCount:v=1,multiple:A=!1,disabled:f=!1,description:C,className:P,...M}=e,[x,N]=Qa({prop:n,onChange:t}),B=p.useCallback((m,g)=>{const k=((x==null?void 0:x.length)??0)+m.length+g.length;if(!A&&v===1&&m.length+g.length>1){q.error(a("documentPanel.uploadDocuments.fileUploader.singleFileLimit"));return}if(k>v){q.error(a("documentPanel.uploadDocuments.fileUploader.maxFilesLimit",{count:v}));return}g.length>0&&(l?l(g):g.forEach(({file:y})=>{q.error(a("documentPanel.uploadDocuments.fileUploader.fileRejected",{name:y.name}))}));const E=m.map(y=>Object.assign(y,{preview:URL.createObjectURL(y)})),U=g.map(({file:y})=>Object.assign(y,{preview:URL.createObjectURL(y),rejected:!0})),c=[...E,...U],F=x?[...x,...c]:c;if(N(F),o&&m.length>0){const y=m.filter(D=>{var G;if(!D.name)return!1;const w=`.${((G=D.name.split(".").pop())==null?void 0:G.toLowerCase())||""}`,j=Object.entries(h||{}).some(([Y,_])=>D.type===Y||Array.isArray(_)&&_.includes(w)),L=D.size<=b;return j&&L});y.length>0&&o(y)}},[x,v,A,o,l,N,a,h,b]);function H(m){if(!x)return;const g=x.filter((k,E)=>E!==m);N(g),t==null||t(g)}p.useEffect(()=>()=>{x&&x.forEach(m=>{Ga(m)&&URL.revokeObjectURL(m.preview)})},[]);const W=f||((x==null?void 0:x.length)??0)>=v;return i.jsxs("div",{className:"relative flex flex-col gap-6 overflow-hidden",children:[i.jsx(we,{onDrop:B,noClick:!1,noKeyboard:!1,maxSize:b,maxFiles:v,multiple:v>1||A,disabled:W,validator:m=>{var E;if(!m.name)return{code:"invalid-file-name",message:a("documentPanel.uploadDocuments.fileUploader.invalidFileName",{fallback:"Invalid file name"})};const g=`.${((E=m.name.split(".").pop())==null?void 0:E.toLowerCase())||""}`;return Object.entries(h||{}).some(([U,c])=>m.type===U||Array.isArray(c)&&c.includes(g))?m.size>b?{code:"file-too-large",message:a("documentPanel.uploadDocuments.fileUploader.fileTooLarge",{maxSize:Je(b)})}:null:{code:"file-invalid-type",message:a("documentPanel.uploadDocuments.fileUploader.unsupportedType")}},children:({getRootProps:m,getInputProps:g,isDragActive:k})=>i.jsxs("div",{...m(),className:O("group border-muted-foreground/25 hover:bg-muted/25 relative grid h-52 w-full cursor-pointer place-items-center rounded-lg border-2 border-dashed px-5 py-2.5 text-center transition","ring-offset-background focus-visible:ring-ring focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none",k&&"border-muted-foreground/50",W&&"pointer-events-none opacity-60",P),...M,children:[i.jsx("input",{...g()}),k?i.jsxs("div",{className:"flex flex-col items-center justify-center gap-4 sm:px-5",children:[i.jsx("div",{className:"rounded-full border border-dashed p-3",children:i.jsx(Ue,{className:"text-muted-foreground size-7","aria-hidden":"true"})}),i.jsx("p",{className:"text-muted-foreground font-medium",children:a("documentPanel.uploadDocuments.fileUploader.dropHere")})]}):i.jsxs("div",{className:"flex flex-col items-center justify-center gap-4 sm:px-5",children:[i.jsx("div",{className:"rounded-full border border-dashed p-3",children:i.jsx(Ue,{className:"text-muted-foreground size-7","aria-hidden":"true"})}),i.jsxs("div",{className:"flex flex-col gap-px",children:[i.jsx("p",{className:"text-muted-foreground font-medium",children:a("documentPanel.uploadDocuments.fileUploader.dragAndDrop")}),C?i.jsx("p",{className:"text-muted-foreground/70 text-sm",children:C}):i.jsxs("p",{className:"text-muted-foreground/70 text-sm",children:[a("documentPanel.uploadDocuments.fileUploader.uploadDescription",{count:v,isMultiple:v===1/0,maxSize:Je(b)}),a("documentPanel.uploadDocuments.fileTypes")]})]})]})]})}),x!=null&&x.length?i.jsx(tt,{className:"h-fit w-full px-3",children:i.jsx("div",{className:"flex max-h-48 flex-col gap-4",children:x==null?void 0:x.map((m,g)=>i.jsx(zi,{file:m,onRemove:()=>H(g),progress:d==null?void 0:d[m.name],error:r==null?void 0:r[m.name]},g))})}):null]})}function Ea({value:e,error:a}){return i.jsx("div",{className:"relative h-2 w-full",children:i.jsx("div",{className:"h-full w-full overflow-hidden rounded-full bg-secondary",children:i.jsx("div",{className:O("h-full transition-all",a?"bg-red-400":"bg-primary"),style:{width:`${e}%`}})})})}function zi({file:e,progress:a,error:n,onRemove:t}){const{t:o}=le();return i.jsxs("div",{className:"relative flex items-center gap-2.5",children:[i.jsxs("div",{className:"flex flex-1 gap-2.5",children:[n?i.jsx(Oa,{className:"text-red-400 size-10","aria-hidden":"true"}):Ga(e)?i.jsx(Pi,{file:e}):null,i.jsxs("div",{className:"flex w-full flex-col gap-2",children:[i.jsxs("div",{className:"flex flex-col gap-px",children:[i.jsx("p",{className:"text-foreground/80 line-clamp-1 text-sm font-medium",children:e.name}),i.jsx("p",{className:"text-muted-foreground text-xs",children:Je(e.size)})]}),n?i.jsxs("div",{className:"text-red-400 text-sm",children:[i.jsx("div",{className:"relative mb-2",children:i.jsx(Ea,{value:100,error:!0})}),i.jsx("p",{children:n})]}):a?i.jsx(Ea,{value:a}):null]})]}),i.jsx("div",{className:"flex items-center gap-2",children:i.jsxs(I,{type:"button",variant:"outline",size:"icon",className:"size-7",onClick:t,children:[i.jsx(it,{className:"size-4","aria-hidden":"true"}),i.jsx("span",{className:"sr-only",children:o("documentPanel.uploadDocuments.fileUploader.removeFile")})]})})]})}function Ga(e){return"preview"in e&&typeof e.preview=="string"}function Pi({file:e}){return e.type.startsWith("image/")?i.jsx("div",{className:"aspect-square shrink-0 rounded-md object-cover"}):i.jsx(Oa,{className:"text-muted-foreground size-10","aria-hidden":"true"})}function Ni({onDocumentsUploaded:e}){const{t:a}=le(),[n,t]=p.useState(!1),[o,l]=p.useState(!1),[d,r]=p.useState({}),[h,b]=p.useState({}),v=p.useCallback(f=>{f.forEach(({file:C,errors:P})=>{var x;let M=((x=P[0])==null?void 0:x.message)||a("documentPanel.uploadDocuments.fileUploader.fileRejected",{name:C.name});M.includes("file-invalid-type")&&(M=a("documentPanel.uploadDocuments.fileUploader.unsupportedType")),r(N=>({...N,[C.name]:100})),b(N=>({...N,[C.name]:M}))})},[r,b,a]),A=p.useCallback(async f=>{var M,x;l(!0);let C=!1;b(N=>{const B={...N};return f.forEach(H=>{delete B[H.name]}),B});const P=q.loading(a("documentPanel.uploadDocuments.batch.uploading"));try{const N={},B=new Intl.Collator(["zh-CN","en"],{sensitivity:"accent",numeric:!0}),H=[...f].sort((m,g)=>B.compare(m.name,g.name));for(const m of H)try{r(k=>({...k,[m.name]:0}));const g=await nt(m,k=>{console.debug(a("documentPanel.uploadDocuments.single.uploading",{name:m.name,percent:k})),r(E=>({...E,[m.name]:k}))});g.status==="duplicated"?(N[m.name]=a("documentPanel.uploadDocuments.fileUploader.duplicateFile"),b(k=>({...k,[m.name]:a("documentPanel.uploadDocuments.fileUploader.duplicateFile")}))):g.status!=="success"?(N[m.name]=g.message,b(k=>({...k,[m.name]:g.message}))):C=!0}catch(g){console.error(`Upload failed for ${m.name}:`,g);let k=X(g);if(g&&typeof g=="object"&&"response"in g){const E=g;((M=E.response)==null?void 0:M.status)===400&&(k=((x=E.response.data)==null?void 0:x.detail)||k),r(U=>({...U,[m.name]:100}))}N[m.name]=k,b(E=>({...E,[m.name]:k}))}Object.keys(N).length>0?q.error(a("documentPanel.uploadDocuments.batch.error"),{id:P}):q.success(a("documentPanel.uploadDocuments.batch.success"),{id:P}),C&&e&&e().catch(m=>{console.error("Error refreshing documents:",m)})}catch(N){console.error("Unexpected error during upload:",N),q.error(a("documentPanel.uploadDocuments.generalError",{error:X(N)}),{id:P})}finally{l(!1)}},[l,r,b,a,e]);return i.jsxs(Ve,{open:n,onOpenChange:f=>{o||(f||(r({}),b({})),t(f))},children:[i.jsx(Aa,{asChild:!0,children:i.jsxs(I,{variant:"default",side:"bottom",tooltip:a("documentPanel.uploadDocuments.tooltip"),size:"sm",children:[i.jsx(Ue,{})," ",a("documentPanel.uploadDocuments.button")]})}),i.jsxs(Xe,{className:"sm:max-w-xl",onCloseAutoFocus:f=>f.preventDefault(),children:[i.jsxs(Qe,{children:[i.jsx(Ze,{children:a("documentPanel.uploadDocuments.title")}),i.jsx(ea,{children:a("documentPanel.uploadDocuments.description")})]}),i.jsx(Di,{maxFileCount:1/0,maxSize:200*1024*1024,description:a("documentPanel.uploadDocuments.fileTypes"),onUpload:A,onReject:v,progresses:d,fileErrors:h,disabled:o})]})]})}const Ca=({htmlFor:e,className:a,children:n,...t})=>i.jsx("label",{htmlFor:e,className:a,...t,children:n});function Ei({onDocumentsCleared:e}){const{t:a}=le(),[n,t]=p.useState(!1),[o,l]=p.useState(""),[d,r]=p.useState(!1),h=o.toLowerCase()==="yes";p.useEffect(()=>{n||(l(""),r(!1))},[n]);const b=p.useCallback(async()=>{if(h)try{const v=await ot();if(v.status!=="success"){q.error(a("documentPanel.clearDocuments.failed",{message:v.message})),l("");return}if(q.success(a("documentPanel.clearDocuments.success")),d)try{await lt(),q.success(a("documentPanel.clearDocuments.cacheCleared"))}catch(A){q.error(a("documentPanel.clearDocuments.cacheClearFailed",{error:X(A)}))}e&&e().catch(console.error),t(!1)}catch(v){q.error(a("documentPanel.clearDocuments.error",{error:X(v)})),l("")}},[h,d,t,a,e]);return i.jsxs(Ve,{open:n,onOpenChange:t,children:[i.jsx(Aa,{asChild:!0,children:i.jsxs(I,{variant:"outline",side:"bottom",tooltip:a("documentPanel.clearDocuments.tooltip"),size:"sm",children:[i.jsx(rt,{})," ",a("documentPanel.clearDocuments.button")]})}),i.jsxs(Xe,{className:"sm:max-w-xl",onCloseAutoFocus:v=>v.preventDefault(),children:[i.jsxs(Qe,{children:[i.jsxs(Ze,{className:"flex items-center gap-2 text-red-500 dark:text-red-400 font-bold",children:[i.jsx(pt,{className:"h-5 w-5"}),a("documentPanel.clearDocuments.title")]}),i.jsx(ea,{className:"pt-2",children:a("documentPanel.clearDocuments.description")})]}),i.jsx("div",{className:"text-red-500 dark:text-red-400 font-semibold mb-4",children:a("documentPanel.clearDocuments.warning")}),i.jsx("div",{className:"mb-4",children:a("documentPanel.clearDocuments.confirm")}),i.jsxs("div",{className:"space-y-4",children:[i.jsxs("div",{className:"space-y-2",children:[i.jsx(Ca,{htmlFor:"confirm-text",className:"text-sm font-medium",children:a("documentPanel.clearDocuments.confirmPrompt")}),i.jsx(ct,{id:"confirm-text",value:o,onChange:v=>l(v.target.value),placeholder:a("documentPanel.clearDocuments.confirmPlaceholder"),className:"w-full"})]}),i.jsxs("div",{className:"flex items-center space-x-2",children:[i.jsx(st,{id:"clear-cache",checked:d,onCheckedChange:v=>r(v===!0)}),i.jsx(Ca,{htmlFor:"clear-cache",className:"text-sm font-medium cursor-pointer",children:a("documentPanel.clearDocuments.clearCache")})]})]}),i.jsxs(dt,{children:[i.jsx(I,{variant:"outline",onClick:()=>t(!1),children:a("common.cancel")}),i.jsx(I,{variant:"destructive",onClick:b,disabled:!h,children:a("documentPanel.clearDocuments.confirmButton")})]})]})]})}function Ci({open:e,onOpenChange:a}){var A;const{t:n}=le(),[t,o]=p.useState(null),[l,d]=p.useState("center"),[r,h]=p.useState(!1),b=p.useRef(null);p.useEffect(()=>{e&&(d("center"),h(!1))},[e]),p.useEffect(()=>{const f=b.current;!f||r||(f.scrollTop=f.scrollHeight)},[t==null?void 0:t.history_messages,r]);const v=()=>{const f=b.current;if(!f)return;const C=Math.abs(f.scrollHeight-f.scrollTop-f.clientHeight)<1;h(!C)};return p.useEffect(()=>{if(!e)return;const f=async()=>{try{const P=await xt();o(P)}catch(P){q.error(n("documentPanel.pipelineStatus.errors.fetchFailed",{error:X(P)}))}};f();const C=setInterval(f,2e3);return()=>clearInterval(C)},[e,n]),i.jsx(Ve,{open:e,onOpenChange:a,children:i.jsxs(Xe,{className:O("sm:max-w-[800px] transition-all duration-200 fixed",l==="left"&&"!left-[25%] !translate-x-[-50%] !mx-4",l==="center"&&"!left-1/2 !-translate-x-1/2",l==="right"&&"!left-[75%] !translate-x-[-50%] !mx-4"),children:[i.jsx(ea,{className:"sr-only",children:t!=null&&t.job_name?`${n("documentPanel.pipelineStatus.jobName")}: ${t.job_name}, ${n("documentPanel.pipelineStatus.progress")}: ${t.cur_batch}/${t.batchs}`:n("documentPanel.pipelineStatus.noActiveJob")}),i.jsxs(Qe,{className:"flex flex-row items-center",children:[i.jsx(Ze,{className:"flex-1",children:n("documentPanel.pipelineStatus.title")}),i.jsxs("div",{className:"flex items-center gap-2 mr-8",children:[i.jsx(I,{variant:"ghost",size:"icon",className:O("h-6 w-6",l==="left"&&"bg-zinc-200 text-zinc-800 hover:bg-zinc-300 dark:bg-zinc-700 dark:text-zinc-200 dark:hover:bg-zinc-600"),onClick:()=>d("left"),children:i.jsx(mt,{className:"h-4 w-4"})}),i.jsx(I,{variant:"ghost",size:"icon",className:O("h-6 w-6",l==="center"&&"bg-zinc-200 text-zinc-800 hover:bg-zinc-300 dark:bg-zinc-700 dark:text-zinc-200 dark:hover:bg-zinc-600"),onClick:()=>d("center"),children:i.jsx(ut,{className:"h-4 w-4"})}),i.jsx(I,{variant:"ghost",size:"icon",className:O("h-6 w-6",l==="right"&&"bg-zinc-200 text-zinc-800 hover:bg-zinc-300 dark:bg-zinc-700 dark:text-zinc-200 dark:hover:bg-zinc-600"),onClick:()=>d("right"),children:i.jsx(ft,{className:"h-4 w-4"})})]})]}),i.jsxs("div",{className:"space-y-4 pt-4",children:[i.jsxs("div",{className:"flex items-center gap-4",children:[i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsxs("div",{className:"text-sm font-medium",children:[n("documentPanel.pipelineStatus.busy"),":"]}),i.jsx("div",{className:`h-2 w-2 rounded-full ${t!=null&&t.busy?"bg-green-500":"bg-gray-300"}`})]}),i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsxs("div",{className:"text-sm font-medium",children:[n("documentPanel.pipelineStatus.requestPending"),":"]}),i.jsx("div",{className:`h-2 w-2 rounded-full ${t!=null&&t.request_pending?"bg-green-500":"bg-gray-300"}`})]})]}),i.jsxs("div",{className:"rounded-md border p-3 space-y-2",children:[i.jsxs("div",{children:[n("documentPanel.pipelineStatus.jobName"),": ",(t==null?void 0:t.job_name)||"-"]}),i.jsxs("div",{className:"flex justify-between",children:[i.jsxs("span",{children:[n("documentPanel.pipelineStatus.startTime"),": ",t!=null&&t.job_start?new Date(t.job_start).toLocaleString():"-"]}),i.jsxs("span",{children:[n("documentPanel.pipelineStatus.progress"),": ",t?`${t.cur_batch}/${t.batchs} ${n("documentPanel.pipelineStatus.unit")}`:"-"]})]})]}),i.jsxs("div",{className:"space-y-2",children:[i.jsxs("div",{className:"text-sm font-medium",children:[n("documentPanel.pipelineStatus.latestMessage"),":"]}),i.jsx("div",{className:"font-mono text-xs rounded-md bg-zinc-800 text-zinc-100 p-3 whitespace-pre-wrap break-words",children:(t==null?void 0:t.latest_message)||"-"})]}),i.jsxs("div",{className:"space-y-2",children:[i.jsxs("div",{className:"text-sm font-medium",children:[n("documentPanel.pipelineStatus.historyMessages"),":"]}),i.jsx("div",{ref:b,onScroll:v,className:"font-mono text-xs rounded-md bg-zinc-800 text-zinc-100 p-3 overflow-y-auto min-h-[7.5em] max-h-[40vh]",children:(A=t==null?void 0:t.history_messages)!=null&&A.length?t.history_messages.map((f,C)=>i.jsx("div",{className:"whitespace-pre-wrap break-words",children:f},C)):"-"})]})]})]})})}const Ie=(e,a=20)=>{if(!e.file_path||typeof e.file_path!="string"||e.file_path.trim()==="")return e.id;const n=e.file_path.split("/"),t=n[n.length-1];return!t||t.trim()===""?e.id:t.length>a?t.slice(0,a)+"...":t},Si=` /* Tooltip styles */ .tooltip-container { position: relative; diff --git a/lightrag/api/webui/assets/index-QYZi8qob.js b/lightrag/api/webui/assets/index-C7DV8sI5.js similarity index 99% rename from lightrag/api/webui/assets/index-QYZi8qob.js rename to lightrag/api/webui/assets/index-C7DV8sI5.js index f6a14dba..b9ca74eb 100644 --- a/lightrag/api/webui/assets/index-QYZi8qob.js +++ b/lightrag/api/webui/assets/index-C7DV8sI5.js @@ -1,4 +1,4 @@ -import{j as o,Y as td,O as fg,k as dg,u as ad,Z as mg,c as hg,l as gg,g as pg,S as yg,T as vg,n as bg,m as nd,o as Sg,p as Tg,$ as ud,a0 as id,a1 as cd,a2 as xg}from"./ui-vendor-CeCm8EER.js";import{d as Ag,h as Dg,r as E,u as sd,H as Ng,i as Eg,j as kf}from"./react-vendor-DEwriMA6.js";import{w as Xe,c as Ve,a2 as od,u as ql,v as Gt,a3 as rd,a4 as fd,I as us,B as Cn,D as Mg,i as zg,j as Cg,k as Og,l as jg,a5 as Rg,a6 as Ug,a7 as _g,a8 as Hg,a9 as Ll,aa as dd,ab as ss,ac as is,ad as Lg,ae as qg,af as Bg,ag as Gg,ah as Yg,ai as wg,aj as md,ak as Xg,al as Vg,am as hd,an as Qg,ao as gd,C as Kg,z as Zg,G as kg,d as En,ap as Jg,aq as Fg,ar as $g}from"./feature-graph-trMp_ED2.js";import{S as Jf,a as Ff,b as $f,c as Wf,d as ot,R as Wg}from"./feature-retrieval-DaoLh-kj.js";import{D as Pg}from"./feature-documents-DCEXq3Fi.js";import{i as cs}from"./utils-vendor-BysuhMZA.js";import"./graph-vendor-B-X5JegA.js";import"./mermaid-vendor-c8YIQY7F.js";import"./markdown-vendor-BBaHfVvE.js";(function(){const b=document.createElement("link").relList;if(b&&b.supports&&b.supports("modulepreload"))return;for(const N of document.querySelectorAll('link[rel="modulepreload"]'))d(N);new MutationObserver(N=>{for(const j of N)if(j.type==="childList")for(const H of j.addedNodes)H.tagName==="LINK"&&H.rel==="modulepreload"&&d(H)}).observe(document,{childList:!0,subtree:!0});function x(N){const j={};return N.integrity&&(j.integrity=N.integrity),N.referrerPolicy&&(j.referrerPolicy=N.referrerPolicy),N.crossOrigin==="use-credentials"?j.credentials="include":N.crossOrigin==="anonymous"?j.credentials="omit":j.credentials="same-origin",j}function d(N){if(N.ep)return;N.ep=!0;const j=x(N);fetch(N.href,j)}})();var ts={exports:{}},Mn={},as={exports:{}},ns={};/** +import{j as o,Y as td,O as fg,k as dg,u as ad,Z as mg,c as hg,l as gg,g as pg,S as yg,T as vg,n as bg,m as nd,o as Sg,p as Tg,$ as ud,a0 as id,a1 as cd,a2 as xg}from"./ui-vendor-CeCm8EER.js";import{d as Ag,h as Dg,r as E,u as sd,H as Ng,i as Eg,j as kf}from"./react-vendor-DEwriMA6.js";import{w as Xe,c as Ve,a2 as od,u as ql,v as Gt,a3 as rd,a4 as fd,I as us,B as Cn,D as Mg,i as zg,j as Cg,k as Og,l as jg,a5 as Rg,a6 as Ug,a7 as _g,a8 as Hg,a9 as Ll,aa as dd,ab as ss,ac as is,ad as Lg,ae as qg,af as Bg,ag as Gg,ah as Yg,ai as wg,aj as md,ak as Xg,al as Vg,am as hd,an as Qg,ao as gd,C as Kg,z as Zg,G as kg,d as En,ap as Jg,aq as Fg,ar as $g}from"./feature-graph-trMp_ED2.js";import{S as Jf,a as Ff,b as $f,c as Wf,d as ot,R as Wg}from"./feature-retrieval-DaoLh-kj.js";import{D as Pg}from"./feature-documents-DMvE8vgg.js";import{i as cs}from"./utils-vendor-BysuhMZA.js";import"./graph-vendor-B-X5JegA.js";import"./mermaid-vendor-c8YIQY7F.js";import"./markdown-vendor-BBaHfVvE.js";(function(){const b=document.createElement("link").relList;if(b&&b.supports&&b.supports("modulepreload"))return;for(const N of document.querySelectorAll('link[rel="modulepreload"]'))d(N);new MutationObserver(N=>{for(const j of N)if(j.type==="childList")for(const H of j.addedNodes)H.tagName==="LINK"&&H.rel==="modulepreload"&&d(H)}).observe(document,{childList:!0,subtree:!0});function x(N){const j={};return N.integrity&&(j.integrity=N.integrity),N.referrerPolicy&&(j.referrerPolicy=N.referrerPolicy),N.crossOrigin==="use-credentials"?j.credentials="include":N.crossOrigin==="anonymous"?j.credentials="omit":j.credentials="same-origin",j}function d(N){if(N.ep)return;N.ep=!0;const j=x(N);fetch(N.href,j)}})();var ts={exports:{}},Mn={},as={exports:{}},ns={};/** * @license React * scheduler.production.js * diff --git a/lightrag/api/webui/assets/index-DsHQCgEh.css b/lightrag/api/webui/assets/index-Dd2S8XA6.css similarity index 99% rename from lightrag/api/webui/assets/index-DsHQCgEh.css rename to lightrag/api/webui/assets/index-Dd2S8XA6.css index a9a161c1..c59a9d83 100644 --- a/lightrag/api/webui/assets/index-DsHQCgEh.css +++ b/lightrag/api/webui/assets/index-Dd2S8XA6.css @@ -1 +1 @@ -/*! tailwindcss v4.0.8 | MIT License | https://tailwindcss.com */@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-100:oklch(.936 .032 17.717);--color-red-400:oklch(.704 .191 22.216);--color-red-500:oklch(.637 .237 25.331);--color-red-600:oklch(.577 .245 27.325);--color-red-900:oklch(.396 .141 25.723);--color-red-950:oklch(.258 .092 26.042);--color-orange-500:oklch(.705 .213 47.604);--color-amber-100:oklch(.962 .059 95.617);--color-amber-200:oklch(.924 .12 95.746);--color-amber-700:oklch(.555 .163 48.998);--color-amber-800:oklch(.473 .137 46.201);--color-amber-900:oklch(.414 .112 45.904);--color-yellow-100:oklch(.973 .071 103.193);--color-yellow-400:oklch(.852 .199 91.936);--color-yellow-600:oklch(.681 .162 75.834);--color-yellow-900:oklch(.421 .095 57.708);--color-green-100:oklch(.962 .044 156.743);--color-green-400:oklch(.792 .209 151.711);--color-green-500:oklch(.723 .219 149.579);--color-green-600:oklch(.627 .194 149.214);--color-green-900:oklch(.393 .095 152.535);--color-emerald-50:oklch(.979 .021 166.113);--color-emerald-400:oklch(.765 .177 163.223);--color-emerald-700:oklch(.508 .118 165.612);--color-teal-100:oklch(.953 .051 180.801);--color-blue-100:oklch(.932 .032 255.585);--color-blue-400:oklch(.707 .165 254.624);--color-blue-600:oklch(.546 .245 262.881);--color-blue-700:oklch(.488 .243 264.376);--color-blue-900:oklch(.379 .146 265.522);--color-violet-700:oklch(.491 .27 292.581);--color-gray-100:oklch(.967 .003 264.542);--color-gray-200:oklch(.928 .006 264.531);--color-gray-300:oklch(.872 .01 258.338);--color-gray-400:oklch(.707 .022 261.325);--color-gray-500:oklch(.551 .027 264.364);--color-gray-600:oklch(.446 .03 256.802);--color-gray-700:oklch(.373 .034 259.733);--color-gray-800:oklch(.278 .033 256.848);--color-gray-900:oklch(.21 .034 264.665);--color-zinc-50:oklch(.985 0 0);--color-zinc-100:oklch(.967 .001 286.375);--color-zinc-200:oklch(.92 .004 286.32);--color-zinc-300:oklch(.871 .006 286.286);--color-zinc-600:oklch(.442 .017 285.786);--color-zinc-700:oklch(.37 .013 285.805);--color-zinc-800:oklch(.274 .006 286.033);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-widest:.1em;--leading-relaxed:1.625;--ease-out:cubic-bezier(0,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-sm:8px;--blur-lg:16px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-font-feature-settings:var(--font-sans--font-feature-settings);--default-font-variation-settings:var(--font-sans--font-variation-settings);--default-mono-font-family:var(--font-mono);--default-mono-font-feature-settings:var(--font-mono--font-feature-settings);--default-mono-font-variation-settings:var(--font-mono--font-variation-settings)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}body{line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1;color:color-mix(in oklab,currentColor 50%,transparent)}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:color-mix(in oklab,var(--ring)50%,transparent)}body{background-color:var(--background);color:var(--foreground)}*{scrollbar-color:initial;scrollbar-width:initial}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing)*0)}.inset-\[-1px\]{top:-1px;right:-1px;bottom:-1px;left:-1px}.top-0{top:calc(var(--spacing)*0)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing)*2)}.top-4{top:calc(var(--spacing)*4)}.top-\[50\%\]{top:50%}.top-full{top:100%}.right-0{right:calc(var(--spacing)*0)}.right-2{right:calc(var(--spacing)*2)}.right-4{right:calc(var(--spacing)*4)}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-2{bottom:calc(var(--spacing)*2)}.bottom-4{bottom:calc(var(--spacing)*4)}.bottom-10{bottom:calc(var(--spacing)*10)}.\!left-1\/2{left:50%!important}.\!left-\[25\%\]{left:25%!important}.\!left-\[75\%\]{left:75%!important}.left-0{left:calc(var(--spacing)*0)}.left-2{left:calc(var(--spacing)*2)}.left-\[50\%\]{left:50%}.left-\[calc\(1rem\+2\.5rem\)\]{left:3.5rem}.z-10{z-index:10}.z-50{z-index:50}.z-60{z-index:60}.\!container{width:100%!important}@media (width>=40rem){.\!container{max-width:40rem!important}}@media (width>=48rem){.\!container{max-width:48rem!important}}@media (width>=64rem){.\!container{max-width:64rem!important}}@media (width>=80rem){.\!container{max-width:80rem!important}}@media (width>=96rem){.\!container{max-width:96rem!important}}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.\!m-0{margin:calc(var(--spacing)*0)!important}.m-0{margin:calc(var(--spacing)*0)}.\!mx-4{margin-inline:calc(var(--spacing)*4)!important}.-mx-1{margin-inline:calc(var(--spacing)*-1)}.mx-1{margin-inline:calc(var(--spacing)*1)}.mx-4{margin-inline:calc(var(--spacing)*4)}.my-1{margin-block:calc(var(--spacing)*1)}.my-2{margin-block:calc(var(--spacing)*2)}.my-4{margin-block:calc(var(--spacing)*4)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-2{margin-right:calc(var(--spacing)*2)}.mr-4{margin-right:calc(var(--spacing)*4)}.mr-8{margin-right:calc(var(--spacing)*8)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\!inline{display:inline!important}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.list-item{display:list-item}.table{display:table}.aspect-square{aspect-ratio:1}.\!size-full{width:100%!important;height:100%!important}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-7{width:calc(var(--spacing)*7);height:calc(var(--spacing)*7)}.size-8{width:calc(var(--spacing)*8);height:calc(var(--spacing)*8)}.size-10{width:calc(var(--spacing)*10);height:calc(var(--spacing)*10)}.size-full{width:100%;height:100%}.h-1\/2{height:50%}.h-2{height:calc(var(--spacing)*2)}.h-2\.5{height:calc(var(--spacing)*2.5)}.h-3{height:calc(var(--spacing)*3)}.h-3\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.h-12{height:calc(var(--spacing)*12)}.h-24{height:calc(var(--spacing)*24)}.h-52{height:calc(var(--spacing)*52)}.h-\[1px\]{height:1px}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-fit{height:fit-content}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-8{max-height:calc(var(--spacing)*8)}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-80{max-height:calc(var(--spacing)*80)}.max-h-96{max-height:calc(var(--spacing)*96)}.max-h-\[40vh\]{max-height:40vh}.max-h-\[50vh\]{max-height:50vh}.max-h-\[60vh\]{max-height:60vh}.max-h-\[300px\]{max-height:300px}.max-h-full{max-height:100%}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-\[7\.5em\]{min-height:7.5em}.min-h-\[10em\]{min-height:10em}.w-2{width:calc(var(--spacing)*2)}.w-2\.5{width:calc(var(--spacing)*2.5)}.w-3{width:calc(var(--spacing)*3)}.w-3\.5{width:calc(var(--spacing)*3.5)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-7{width:calc(var(--spacing)*7)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-12{width:calc(var(--spacing)*12)}.w-16{width:calc(var(--spacing)*16)}.w-24{width:calc(var(--spacing)*24)}.w-56{width:calc(var(--spacing)*56)}.w-\[1px\]{width:1px}.w-\[90\%\]{width:90%}.w-\[200px\]{width:200px}.w-auto{width:auto}.w-full{width:100%}.w-screen{width:100vw}.max-w-80{max-width:calc(var(--spacing)*80)}.max-w-\[80\%\]{max-width:80%}.max-w-\[200px\]{max-width:200px}.max-w-\[250px\]{max-width:250px}.max-w-\[480px\]{max-width:480px}.max-w-lg{max-width:var(--container-lg)}.max-w-none{max-width:none}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-45{min-width:calc(var(--spacing)*45)}.min-w-\[8rem\]{min-width:8rem}.min-w-\[200px\]{min-width:200px}.min-w-\[220px\]{min-width:220px}.min-w-\[300px\]{min-width:300px}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.min-w-auto{min-width:auto}.flex-1{flex:1}.flex-none{flex:none}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.caption-bottom{caption-side:bottom}.\!-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)!important}.\!translate-x-\[-50\%\]{--tw-translate-x:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)!important}.-translate-x-13{--tw-translate-x:calc(var(--spacing)*-13);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-x-15{--tw-translate-x:calc(var(--spacing)*-15);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-\[-50\%\]{--tw-translate-x:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-\[-50\%\]{--tw-translate-y:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)}.scale-125{--tw-scale-x:125%;--tw-scale-y:125%;--tw-scale-z:125%;scale:var(--tw-scale-x)var(--tw-scale-y)}.transform{transform:var(--tw-rotate-x)var(--tw-rotate-y)var(--tw-rotate-z)var(--tw-skew-x)var(--tw-skew-y)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.resize-y{resize:vertical}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.\[appearance\:textfield\]{-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}.grid-cols-\[120px_1fr\]{grid-template-columns:120px 1fr}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.place-items-center{place-items:center}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.gap-px{gap:1px}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}.self-center{align-self:center}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.\!overflow-hidden{overflow:hidden!important}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.\!rounded-none{border-radius:0!important}.rounded{border-radius:.25rem}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.rounded-tr-none{border-top-right-radius:0}.rounded-br-none{border-bottom-right-radius:0}.border,.border-1{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-4{border-style:var(--tw-border-style);border-width:4px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.\!border-input{border-color:var(--input)!important}.border-blue-400{border-color:var(--color-blue-400)}.border-border\/40{border-color:color-mix(in oklab,var(--border)40%,transparent)}.border-destructive\/50{border-color:color-mix(in oklab,var(--destructive)50%,transparent)}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-400{border-color:var(--color-gray-400)}.border-green-400{border-color:var(--color-green-400)}.border-input{border-color:var(--input)}.border-muted-foreground\/25{border-color:color-mix(in oklab,var(--muted-foreground)25%,transparent)}.border-muted-foreground\/50{border-color:color-mix(in oklab,var(--muted-foreground)50%,transparent)}.border-primary{border-color:var(--primary)}.border-red-400{border-color:var(--color-red-400)}.border-transparent{border-color:#0000}.border-yellow-400{border-color:var(--color-yellow-400)}.border-t-transparent{border-top-color:#0000}.border-l-transparent{border-left-color:#0000}.\!bg-background{background-color:var(--background)!important}.\!bg-emerald-400{background-color:var(--color-emerald-400)!important}.bg-amber-100{background-color:var(--color-amber-100)}.bg-background{background-color:var(--background)}.bg-background\/60{background-color:color-mix(in oklab,var(--background)60%,transparent)}.bg-background\/80{background-color:color-mix(in oklab,var(--background)80%,transparent)}.bg-background\/95{background-color:color-mix(in oklab,var(--background)95%,transparent)}.bg-black\/30{background-color:color-mix(in oklab,var(--color-black)30%,transparent)}.bg-black\/50{background-color:color-mix(in oklab,var(--color-black)50%,transparent)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-border{background-color:var(--border)}.bg-card{background-color:var(--card)}.bg-card\/95{background-color:color-mix(in oklab,var(--card)95%,transparent)}.bg-destructive{background-color:var(--destructive)}.bg-foreground\/10{background-color:color-mix(in oklab,var(--foreground)10%,transparent)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-300{background-color:var(--color-gray-300)}.bg-green-100{background-color:var(--color-green-100)}.bg-green-500{background-color:var(--color-green-500)}.bg-muted{background-color:var(--muted)}.bg-muted\/50{background-color:color-mix(in oklab,var(--muted)50%,transparent)}.bg-popover{background-color:var(--popover)}.bg-primary{background-color:var(--primary)}.bg-primary-foreground\/60{background-color:color-mix(in oklab,var(--primary-foreground)60%,transparent)}.bg-primary\/5{background-color:color-mix(in oklab,var(--primary)5%,transparent)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-400{background-color:var(--color-red-400)}.bg-red-500{background-color:var(--color-red-500)}.bg-secondary{background-color:var(--secondary)}.bg-transparent{background-color:#0000}.bg-white\/30{background-color:color-mix(in oklab,var(--color-white)30%,transparent)}.bg-yellow-100{background-color:var(--color-yellow-100)}.bg-zinc-200{background-color:var(--color-zinc-200)}.bg-zinc-800{background-color:var(--color-zinc-800)}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-emerald-50{--tw-gradient-from:var(--color-emerald-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-teal-100{--tw-gradient-to:var(--color-teal-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.object-cover{object-fit:cover}.\!p-0{padding:calc(var(--spacing)*0)!important}.p-0{padding:calc(var(--spacing)*0)}.p-1{padding:calc(var(--spacing)*1)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.p-16{padding:calc(var(--spacing)*16)}.p-\[1px\]{padding:1px}.px-1{padding-inline:calc(var(--spacing)*1)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.px-6{padding-inline:calc(var(--spacing)*6)}.px-8{padding-inline:calc(var(--spacing)*8)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-6{padding-block:calc(var(--spacing)*6)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-6{padding-top:calc(var(--spacing)*6)}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-2{padding-right:calc(var(--spacing)*2)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-8{padding-bottom:calc(var(--spacing)*8)}.pb-12{padding-bottom:calc(var(--spacing)*12)}.pl-1{padding-left:calc(var(--spacing)*1)}.pl-5{padding-left:calc(var(--spacing)*5)}.pl-8{padding-left:calc(var(--spacing)*8)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.text-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.\!text-zinc-50{color:var(--color-zinc-50)!important}.text-amber-700{color:var(--color-amber-700)}.text-amber-800{color:var(--color-amber-800)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-card-foreground{color:var(--card-foreground)}.text-current{color:currentColor}.text-destructive{color:var(--destructive)}.text-destructive-foreground{color:var(--destructive-foreground)}.text-emerald-400{color:var(--color-emerald-400)}.text-emerald-700{color:var(--color-emerald-700)}.text-foreground{color:var(--foreground)}.text-foreground\/80{color:color-mix(in oklab,var(--foreground)80%,transparent)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-700{color:var(--color-gray-700)}.text-gray-900{color:var(--color-gray-900)}.text-green-600{color:var(--color-green-600)}.text-muted-foreground{color:var(--muted-foreground)}.text-muted-foreground\/70{color:color-mix(in oklab,var(--muted-foreground)70%,transparent)}.text-orange-500{color:var(--color-orange-500)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-primary\/60{color:color-mix(in oklab,var(--primary)60%,transparent)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-violet-700{color:var(--color-violet-700)}.text-yellow-600{color:var(--color-yellow-600)}.text-zinc-100{color:var(--color-zinc-100)}.text-zinc-800{color:var(--color-zinc-800)}.lowercase{text-transform:lowercase}.italic{font-style:italic}.underline{text-decoration-line:underline}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-20{opacity:.2}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_8px_rgba\(0\,0\,0\,0\.2\)\]{--tw-shadow:0 0 8px var(--tw-shadow-color,#0003);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_12px_rgba\(34\,197\,94\,0\.4\)\]{--tw-shadow:0 0 12px var(--tw-shadow-color,#22c55e66);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_12px_rgba\(239\,68\,68\,0\.4\)\]{--tw-shadow:0 0 12px var(--tw-shadow-color,#ef444466);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[inset_0_-1px_0_rgba\(0\,0\,0\,0\.1\)\]{--tw-shadow:inset 0 -1px 0 var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-offset-background{--tw-ring-offset-color:var(--background)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.backdrop-blur-lg{--tw-backdrop-blur:blur(var(--blur-lg));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-2000{--tw-duration:2s;transition-duration:2s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.animate-in{--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial;animation-name:enter;animation-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.duration-200{animation-duration:.2s}.duration-300{animation-duration:.3s}.duration-2000{animation-duration:2s}.ease-out{animation-timing-function:cubic-bezier(0,0,.2,1)}.fade-in-0{--tw-enter-opacity:0}.running{animation-play-state:running}.zoom-in-95{--tw-enter-scale:.95}@media (hover:hover){.group-hover\:visible:is(:where(.group):hover *){visibility:visible}}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.peer-disabled\:opacity-70:is(:where(.peer):disabled~*){opacity:.7}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--foreground)}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}@media (hover:hover){.hover\:w-fit:hover{width:fit-content}.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:bg-background\/60:hover{background-color:color-mix(in oklab,var(--background)60%,transparent)}.hover\:bg-destructive\/80:hover{background-color:color-mix(in oklab,var(--destructive)80%,transparent)}.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab,var(--destructive)90%,transparent)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-200:hover{background-color:var(--color-gray-200)}.hover\:bg-muted:hover{background-color:var(--muted)}.hover\:bg-muted\/25:hover{background-color:color-mix(in oklab,var(--muted)25%,transparent)}.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab,var(--muted)50%,transparent)}.hover\:bg-primary\/5:hover{background-color:color-mix(in oklab,var(--primary)5%,transparent)}.hover\:bg-primary\/20:hover{background-color:color-mix(in oklab,var(--primary)20%,transparent)}.hover\:bg-primary\/80:hover{background-color:color-mix(in oklab,var(--primary)80%,transparent)}.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--primary)90%,transparent)}.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab,var(--secondary)80%,transparent)}.hover\:bg-zinc-300:hover{background-color:var(--color-zinc-300)}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:text-gray-700:hover{color:var(--color-gray-700)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}}.focus\:bg-accent:focus{background-color:var(--accent)}.focus\:text-accent-foreground:focus{color:var(--accent-foreground)}.focus\:ring-0:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-ring:focus{--tw-ring-color:var(--ring)}.focus\:ring-offset-0:focus{--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:outline-0:focus{outline-style:var(--tw-outline-style);outline-width:0}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:relative:focus-visible{position:relative}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--ring)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.active\:right-0:active{right:calc(var(--spacing)*0)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[disabled\=true\]\:pointer-events-none[data-disabled=true]{pointer-events:none}.data-\[disabled\=true\]\:opacity-50[data-disabled=true]{opacity:.5}.data-\[selected\=\'true\'\]\:bg-accent[data-selected=true]{background-color:var(--accent)}.data-\[selected\=true\]\:text-accent-foreground[data-selected=true]{color:var(--accent-foreground)}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y:calc(var(--spacing)*1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=bottom\]\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y:-.5rem}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=left\]\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x:.5rem}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x:calc(var(--spacing)*1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=right\]\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x:-.5rem}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=top\]\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y:.5rem}.data-\[state\=active\]\:visible[data-state=active]{visibility:visible}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:var(--background)}.data-\[state\=active\]\:text-foreground[data-state=active]{color:var(--foreground)}.data-\[state\=active\]\:shadow-sm[data-state=active]{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.data-\[state\=checked\]\:bg-muted[data-state=checked]{background-color:var(--muted)}.data-\[state\=checked\]\:text-muted-foreground[data-state=checked]{color:var(--muted-foreground)}.data-\[state\=closed\]\:animate-out[data-state=closed]{--tw-exit-opacity:initial;--tw-exit-scale:initial;--tw-exit-rotate:initial;--tw-exit-translate-x:initial;--tw-exit-translate-y:initial;animation-name:exit;animation-duration:.15s}.data-\[state\=closed\]\:fade-out-0[data-state=closed]{--tw-exit-opacity:0}.data-\[state\=closed\]\:slide-out-to-top-\[48\%\][data-state=closed]{--tw-exit-translate-y:-48%}.data-\[state\=closed\]\:zoom-out-95[data-state=closed]{--tw-exit-scale:.95}.data-\[state\=inactive\]\:invisible[data-state=inactive]{visibility:hidden}.data-\[state\=open\]\:bg-accent[data-state=open]{background-color:var(--accent)}.data-\[state\=open\]\:text-muted-foreground[data-state=open]{color:var(--muted-foreground)}.data-\[state\=open\]\:animate-in[data-state=open]{--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial;animation-name:enter;animation-duration:.15s}.data-\[state\=open\]\:fade-in-0[data-state=open]{--tw-enter-opacity:0}.data-\[state\=open\]\:slide-in-from-top-\[48\%\][data-state=open]{--tw-enter-translate-y:-48%}.data-\[state\=open\]\:zoom-in-95[data-state=open]{--tw-enter-scale:.95}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:var(--muted)}@supports ((-webkit-backdrop-filter:var(--tw)) or (backdrop-filter:var(--tw))){.supports-\[backdrop-filter\]\:bg-background\/60{background-color:color-mix(in oklab,var(--background)60%,transparent)}.supports-\[backdrop-filter\]\:bg-card\/75{background-color:color-mix(in oklab,var(--card)75%,transparent)}}@media (width>=40rem){.sm\:mt-0{margin-top:calc(var(--spacing)*0)}.sm\:max-w-\[500px\]{max-width:500px}.sm\:max-w-\[600px\]{max-width:600px}.sm\:max-w-md{max-width:var(--container-md)}.sm\:max-w-xl{max-width:var(--container-xl)}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}:where(.sm\:space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:var(--radius)}.sm\:px-5{padding-inline:calc(var(--spacing)*5)}.sm\:text-left{text-align:left}}@media (width>=48rem){.md\:inline-block{display:inline-block}.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.dark\:border-blue-600:is(.dark *){border-color:var(--color-blue-600)}.dark\:border-destructive:is(.dark *){border-color:var(--destructive)}.dark\:border-gray-500:is(.dark *){border-color:var(--color-gray-500)}.dark\:border-gray-600:is(.dark *){border-color:var(--color-gray-600)}.dark\:border-gray-700:is(.dark *){border-color:var(--color-gray-700)}.dark\:border-green-600:is(.dark *){border-color:var(--color-green-600)}.dark\:border-red-600:is(.dark *){border-color:var(--color-red-600)}.dark\:border-yellow-600:is(.dark *){border-color:var(--color-yellow-600)}.dark\:bg-amber-900:is(.dark *){background-color:var(--color-amber-900)}.dark\:bg-blue-900\/30:is(.dark *){background-color:color-mix(in oklab,var(--color-blue-900)30%,transparent)}.dark\:bg-gray-800\/30:is(.dark *){background-color:color-mix(in oklab,var(--color-gray-800)30%,transparent)}.dark\:bg-gray-900:is(.dark *){background-color:var(--color-gray-900)}.dark\:bg-green-900\/30:is(.dark *){background-color:color-mix(in oklab,var(--color-green-900)30%,transparent)}.dark\:bg-red-900\/30:is(.dark *){background-color:color-mix(in oklab,var(--color-red-900)30%,transparent)}.dark\:bg-red-950:is(.dark *){background-color:var(--color-red-950)}.dark\:bg-yellow-900\/30:is(.dark *){background-color:color-mix(in oklab,var(--color-yellow-900)30%,transparent)}.dark\:bg-zinc-700:is(.dark *){background-color:var(--color-zinc-700)}.dark\:from-gray-900:is(.dark *){--tw-gradient-from:var(--color-gray-900);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.dark\:to-gray-800:is(.dark *){--tw-gradient-to:var(--color-gray-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.dark\:text-amber-200:is(.dark *){color:var(--color-amber-200)}.dark\:text-gray-300:is(.dark *){color:var(--color-gray-300)}.dark\:text-gray-400:is(.dark *){color:var(--color-gray-400)}.dark\:text-red-400:is(.dark *){color:var(--color-red-400)}.dark\:text-zinc-200:is(.dark *){color:var(--color-zinc-200)}@media (hover:hover){.dark\:hover\:bg-gray-700:is(.dark *):hover{background-color:var(--color-gray-700)}.dark\:hover\:bg-gray-800:is(.dark *):hover{background-color:var(--color-gray-800)}.dark\:hover\:bg-zinc-600:is(.dark *):hover{background-color:var(--color-zinc-600)}}.\[\&_\[cmdk-group-heading\]\]\:px-2 [cmdk-group-heading]{padding-inline:calc(var(--spacing)*2)}.\[\&_\[cmdk-group-heading\]\]\:py-1\.5 [cmdk-group-heading]{padding-block:calc(var(--spacing)*1.5)}.\[\&_\[cmdk-group-heading\]\]\:text-xs [cmdk-group-heading]{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\[\&_\[cmdk-group-heading\]\]\:font-medium [cmdk-group-heading]{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.\[\&_\[cmdk-group-heading\]\]\:text-muted-foreground [cmdk-group-heading]{color:var(--muted-foreground)}.\[\&_\[cmdk-group\]\]\:px-2 [cmdk-group]{padding-inline:calc(var(--spacing)*2)}.\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0 [cmdk-group]:not([hidden])~[cmdk-group]{padding-top:calc(var(--spacing)*0)}.\[\&_\[cmdk-input-wrapper\]_svg\]\:h-5 [cmdk-input-wrapper] svg{height:calc(var(--spacing)*5)}.\[\&_\[cmdk-input-wrapper\]_svg\]\:w-5 [cmdk-input-wrapper] svg{width:calc(var(--spacing)*5)}.\[\&_\[cmdk-input\]\]\:h-12 [cmdk-input]{height:calc(var(--spacing)*12)}.\[\&_\[cmdk-item\]\]\:px-2 [cmdk-item]{padding-inline:calc(var(--spacing)*2)}.\[\&_\[cmdk-item\]\]\:py-3 [cmdk-item]{padding-block:calc(var(--spacing)*3)}.\[\&_\[cmdk-item\]_svg\]\:h-5 [cmdk-item] svg{height:calc(var(--spacing)*5)}.\[\&_\[cmdk-item\]_svg\]\:w-5 [cmdk-item] svg{width:calc(var(--spacing)*5)}.\[\&_p\]\:leading-relaxed p{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&\:\:-webkit-inner-spin-button\]\:appearance-none::-webkit-inner-spin-button{-webkit-appearance:none;-moz-appearance:none;appearance:none}.\[\&\:\:-webkit-inner-spin-button\]\:opacity-50::-webkit-inner-spin-button{opacity:.5}.\[\&\:\:-webkit-outer-spin-button\]\:appearance-none::-webkit-outer-spin-button{-webkit-appearance:none;-moz-appearance:none;appearance:none}.\[\&\:\:-webkit-outer-spin-button\]\:opacity-50::-webkit-outer-spin-button{opacity:.5}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:calc(var(--spacing)*0)}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y:2px;translate:var(--tw-translate-x)var(--tw-translate-y)}.\[\&\>span\]\:line-clamp-1>span{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\[\&\>svg\]\:absolute>svg{position:absolute}.\[\&\>svg\]\:top-4>svg{top:calc(var(--spacing)*4)}.\[\&\>svg\]\:left-4>svg{left:calc(var(--spacing)*4)}.\[\&\>svg\]\:text-destructive>svg{color:var(--destructive)}.\[\&\>svg\]\:text-foreground>svg{color:var(--foreground)}.\[\&\>svg\+div\]\:translate-y-\[-3px\]>svg+div{--tw-translate-y:-3px;translate:var(--tw-translate-x)var(--tw-translate-y)}.\[\&\>svg\~\*\]\:pl-7>svg~*{padding-left:calc(var(--spacing)*7)}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}}:root{--background:#fff;--foreground:#09090b;--card:#fff;--card-foreground:#09090b;--popover:#fff;--popover-foreground:#09090b;--primary:#18181b;--primary-foreground:#fafafa;--secondary:#f4f4f5;--secondary-foreground:#18181b;--muted:#f4f4f5;--muted-foreground:#71717a;--accent:#f4f4f5;--accent-foreground:#18181b;--destructive:#ef4444;--destructive-foreground:#fafafa;--border:#e4e4e7;--input:#e4e4e7;--ring:#09090b;--chart-1:#e76e50;--chart-2:#2a9d90;--chart-3:#274754;--chart-4:#e8c468;--chart-5:#f4a462;--radius:.6rem;--sidebar-background:#fafafa;--sidebar-foreground:#3f3f46;--sidebar-primary:#18181b;--sidebar-primary-foreground:#fafafa;--sidebar-accent:#f4f4f5;--sidebar-accent-foreground:#18181b;--sidebar-border:#e5e7eb;--sidebar-ring:#3b82f6}.dark{--background:#09090b;--foreground:#fafafa;--card:#09090b;--card-foreground:#fafafa;--popover:#09090b;--popover-foreground:#fafafa;--primary:#fafafa;--primary-foreground:#18181b;--secondary:#27272a;--secondary-foreground:#fafafa;--muted:#27272a;--muted-foreground:#a1a1aa;--accent:#27272a;--accent-foreground:#fafafa;--destructive:#7f1d1d;--destructive-foreground:#fafafa;--border:#27272a;--input:#27272a;--ring:#d4d4d8;--chart-1:#2662d9;--chart-2:#2eb88a;--chart-3:#e88c30;--chart-4:#af57db;--chart-5:#e23670;--sidebar-background:#18181b;--sidebar-foreground:#f4f4f5;--sidebar-primary:#1d4ed8;--sidebar-primary-foreground:#fff;--sidebar-accent:#27272a;--sidebar-accent-foreground:#f4f4f5;--sidebar-border:#27272a;--sidebar-ring:#3b82f6}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-thumb{background-color:#ccc;border-radius:5px}::-webkit-scrollbar-track{background-color:#f2f2f2}.dark ::-webkit-scrollbar-thumb{background-color:#e6e6e6}.dark ::-webkit-scrollbar-track{background-color:#000}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0))}}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false;initial-value:rotateX(0)}@property --tw-rotate-y{syntax:"*";inherits:false;initial-value:rotateY(0)}@property --tw-rotate-z{syntax:"*";inherits:false;initial-value:rotateZ(0)}@property --tw-skew-x{syntax:"*";inherits:false;initial-value:skewX(0)}@property --tw-skew-y{syntax:"*";inherits:false;initial-value:skewY(0)}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false} +/*! tailwindcss v4.0.8 | MIT License | https://tailwindcss.com */@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-100:oklch(.936 .032 17.717);--color-red-400:oklch(.704 .191 22.216);--color-red-500:oklch(.637 .237 25.331);--color-red-600:oklch(.577 .245 27.325);--color-red-900:oklch(.396 .141 25.723);--color-red-950:oklch(.258 .092 26.042);--color-orange-500:oklch(.705 .213 47.604);--color-amber-100:oklch(.962 .059 95.617);--color-amber-200:oklch(.924 .12 95.746);--color-amber-700:oklch(.555 .163 48.998);--color-amber-800:oklch(.473 .137 46.201);--color-amber-900:oklch(.414 .112 45.904);--color-yellow-100:oklch(.973 .071 103.193);--color-yellow-400:oklch(.852 .199 91.936);--color-yellow-600:oklch(.681 .162 75.834);--color-yellow-900:oklch(.421 .095 57.708);--color-green-100:oklch(.962 .044 156.743);--color-green-400:oklch(.792 .209 151.711);--color-green-500:oklch(.723 .219 149.579);--color-green-600:oklch(.627 .194 149.214);--color-green-900:oklch(.393 .095 152.535);--color-emerald-50:oklch(.979 .021 166.113);--color-emerald-400:oklch(.765 .177 163.223);--color-emerald-700:oklch(.508 .118 165.612);--color-teal-100:oklch(.953 .051 180.801);--color-blue-100:oklch(.932 .032 255.585);--color-blue-400:oklch(.707 .165 254.624);--color-blue-600:oklch(.546 .245 262.881);--color-blue-700:oklch(.488 .243 264.376);--color-blue-900:oklch(.379 .146 265.522);--color-violet-700:oklch(.491 .27 292.581);--color-gray-100:oklch(.967 .003 264.542);--color-gray-200:oklch(.928 .006 264.531);--color-gray-300:oklch(.872 .01 258.338);--color-gray-400:oklch(.707 .022 261.325);--color-gray-500:oklch(.551 .027 264.364);--color-gray-600:oklch(.446 .03 256.802);--color-gray-700:oklch(.373 .034 259.733);--color-gray-800:oklch(.278 .033 256.848);--color-gray-900:oklch(.21 .034 264.665);--color-zinc-50:oklch(.985 0 0);--color-zinc-100:oklch(.967 .001 286.375);--color-zinc-200:oklch(.92 .004 286.32);--color-zinc-300:oklch(.871 .006 286.286);--color-zinc-600:oklch(.442 .017 285.786);--color-zinc-700:oklch(.37 .013 285.805);--color-zinc-800:oklch(.274 .006 286.033);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-widest:.1em;--leading-relaxed:1.625;--ease-out:cubic-bezier(0,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-sm:8px;--blur-lg:16px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-font-feature-settings:var(--font-sans--font-feature-settings);--default-font-variation-settings:var(--font-sans--font-variation-settings);--default-mono-font-family:var(--font-mono);--default-mono-font-feature-settings:var(--font-mono--font-feature-settings);--default-mono-font-variation-settings:var(--font-mono--font-variation-settings)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}body{line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1;color:color-mix(in oklab,currentColor 50%,transparent)}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:color-mix(in oklab,var(--ring)50%,transparent)}body{background-color:var(--background);color:var(--foreground)}*{scrollbar-color:initial;scrollbar-width:initial}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing)*0)}.inset-\[-1px\]{top:-1px;right:-1px;bottom:-1px;left:-1px}.top-0{top:calc(var(--spacing)*0)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing)*2)}.top-4{top:calc(var(--spacing)*4)}.top-\[50\%\]{top:50%}.top-full{top:100%}.right-0{right:calc(var(--spacing)*0)}.right-2{right:calc(var(--spacing)*2)}.right-4{right:calc(var(--spacing)*4)}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-2{bottom:calc(var(--spacing)*2)}.bottom-4{bottom:calc(var(--spacing)*4)}.bottom-10{bottom:calc(var(--spacing)*10)}.\!left-1\/2{left:50%!important}.\!left-\[25\%\]{left:25%!important}.\!left-\[75\%\]{left:75%!important}.left-0{left:calc(var(--spacing)*0)}.left-2{left:calc(var(--spacing)*2)}.left-\[50\%\]{left:50%}.left-\[calc\(1rem\+2\.5rem\)\]{left:3.5rem}.z-10{z-index:10}.z-50{z-index:50}.z-60{z-index:60}.\!container{width:100%!important}@media (width>=40rem){.\!container{max-width:40rem!important}}@media (width>=48rem){.\!container{max-width:48rem!important}}@media (width>=64rem){.\!container{max-width:64rem!important}}@media (width>=80rem){.\!container{max-width:80rem!important}}@media (width>=96rem){.\!container{max-width:96rem!important}}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.\!m-0{margin:calc(var(--spacing)*0)!important}.m-0{margin:calc(var(--spacing)*0)}.\!mx-4{margin-inline:calc(var(--spacing)*4)!important}.-mx-1{margin-inline:calc(var(--spacing)*-1)}.mx-1{margin-inline:calc(var(--spacing)*1)}.mx-4{margin-inline:calc(var(--spacing)*4)}.my-1{margin-block:calc(var(--spacing)*1)}.my-2{margin-block:calc(var(--spacing)*2)}.my-4{margin-block:calc(var(--spacing)*4)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-2{margin-right:calc(var(--spacing)*2)}.mr-4{margin-right:calc(var(--spacing)*4)}.mr-8{margin-right:calc(var(--spacing)*8)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\!inline{display:inline!important}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.list-item{display:list-item}.table{display:table}.aspect-square{aspect-ratio:1}.\!size-full{width:100%!important;height:100%!important}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-7{width:calc(var(--spacing)*7);height:calc(var(--spacing)*7)}.size-8{width:calc(var(--spacing)*8);height:calc(var(--spacing)*8)}.size-10{width:calc(var(--spacing)*10);height:calc(var(--spacing)*10)}.size-full{width:100%;height:100%}.h-1\/2{height:50%}.h-2{height:calc(var(--spacing)*2)}.h-2\.5{height:calc(var(--spacing)*2.5)}.h-3{height:calc(var(--spacing)*3)}.h-3\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.h-12{height:calc(var(--spacing)*12)}.h-24{height:calc(var(--spacing)*24)}.h-52{height:calc(var(--spacing)*52)}.h-\[1px\]{height:1px}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-fit{height:fit-content}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-8{max-height:calc(var(--spacing)*8)}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-80{max-height:calc(var(--spacing)*80)}.max-h-96{max-height:calc(var(--spacing)*96)}.max-h-\[40vh\]{max-height:40vh}.max-h-\[50vh\]{max-height:50vh}.max-h-\[60vh\]{max-height:60vh}.max-h-\[300px\]{max-height:300px}.max-h-full{max-height:100%}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-\[7\.5em\]{min-height:7.5em}.min-h-\[10em\]{min-height:10em}.w-2{width:calc(var(--spacing)*2)}.w-2\.5{width:calc(var(--spacing)*2.5)}.w-3{width:calc(var(--spacing)*3)}.w-3\.5{width:calc(var(--spacing)*3.5)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-7{width:calc(var(--spacing)*7)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-12{width:calc(var(--spacing)*12)}.w-16{width:calc(var(--spacing)*16)}.w-24{width:calc(var(--spacing)*24)}.w-56{width:calc(var(--spacing)*56)}.w-\[1px\]{width:1px}.w-\[90\%\]{width:90%}.w-\[200px\]{width:200px}.w-auto{width:auto}.w-full{width:100%}.w-screen{width:100vw}.max-w-80{max-width:calc(var(--spacing)*80)}.max-w-\[80\%\]{max-width:80%}.max-w-\[200px\]{max-width:200px}.max-w-\[250px\]{max-width:250px}.max-w-\[480px\]{max-width:480px}.max-w-lg{max-width:var(--container-lg)}.max-w-none{max-width:none}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-45{min-width:calc(var(--spacing)*45)}.min-w-\[8rem\]{min-width:8rem}.min-w-\[200px\]{min-width:200px}.min-w-\[220px\]{min-width:220px}.min-w-\[300px\]{min-width:300px}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.min-w-auto{min-width:auto}.flex-1{flex:1}.flex-none{flex:none}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.caption-bottom{caption-side:bottom}.\!-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)!important}.\!translate-x-\[-50\%\]{--tw-translate-x:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)!important}.-translate-x-13{--tw-translate-x:calc(var(--spacing)*-13);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-x-15{--tw-translate-x:calc(var(--spacing)*-15);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-\[-50\%\]{--tw-translate-x:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-\[-50\%\]{--tw-translate-y:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)}.scale-125{--tw-scale-x:125%;--tw-scale-y:125%;--tw-scale-z:125%;scale:var(--tw-scale-x)var(--tw-scale-y)}.transform{transform:var(--tw-rotate-x)var(--tw-rotate-y)var(--tw-rotate-z)var(--tw-skew-x)var(--tw-skew-y)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.resize-y{resize:vertical}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.\[appearance\:textfield\]{-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}.grid-cols-\[120px_1fr\]{grid-template-columns:120px 1fr}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.place-items-center{place-items:center}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.gap-px{gap:1px}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}.self-center{align-self:center}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.\!overflow-hidden{overflow:hidden!important}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.\!rounded-none{border-radius:0!important}.rounded{border-radius:.25rem}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.rounded-tr-none{border-top-right-radius:0}.rounded-br-none{border-bottom-right-radius:0}.border,.border-1{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-4{border-style:var(--tw-border-style);border-width:4px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.\!border-input{border-color:var(--input)!important}.border-blue-400{border-color:var(--color-blue-400)}.border-border\/40{border-color:color-mix(in oklab,var(--border)40%,transparent)}.border-destructive\/50{border-color:color-mix(in oklab,var(--destructive)50%,transparent)}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-400{border-color:var(--color-gray-400)}.border-green-400{border-color:var(--color-green-400)}.border-input{border-color:var(--input)}.border-muted-foreground\/25{border-color:color-mix(in oklab,var(--muted-foreground)25%,transparent)}.border-muted-foreground\/50{border-color:color-mix(in oklab,var(--muted-foreground)50%,transparent)}.border-primary{border-color:var(--primary)}.border-red-400{border-color:var(--color-red-400)}.border-transparent{border-color:#0000}.border-yellow-400{border-color:var(--color-yellow-400)}.border-t-transparent{border-top-color:#0000}.border-l-transparent{border-left-color:#0000}.\!bg-background{background-color:var(--background)!important}.\!bg-emerald-400{background-color:var(--color-emerald-400)!important}.bg-amber-100{background-color:var(--color-amber-100)}.bg-background{background-color:var(--background)}.bg-background\/60{background-color:color-mix(in oklab,var(--background)60%,transparent)}.bg-background\/80{background-color:color-mix(in oklab,var(--background)80%,transparent)}.bg-background\/95{background-color:color-mix(in oklab,var(--background)95%,transparent)}.bg-black\/30{background-color:color-mix(in oklab,var(--color-black)30%,transparent)}.bg-black\/50{background-color:color-mix(in oklab,var(--color-black)50%,transparent)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-border{background-color:var(--border)}.bg-card{background-color:var(--card)}.bg-card\/95{background-color:color-mix(in oklab,var(--card)95%,transparent)}.bg-destructive{background-color:var(--destructive)}.bg-foreground\/10{background-color:color-mix(in oklab,var(--foreground)10%,transparent)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-300{background-color:var(--color-gray-300)}.bg-green-100{background-color:var(--color-green-100)}.bg-green-500{background-color:var(--color-green-500)}.bg-muted{background-color:var(--muted)}.bg-muted\/50{background-color:color-mix(in oklab,var(--muted)50%,transparent)}.bg-popover{background-color:var(--popover)}.bg-primary{background-color:var(--primary)}.bg-primary-foreground\/60{background-color:color-mix(in oklab,var(--primary-foreground)60%,transparent)}.bg-primary\/5{background-color:color-mix(in oklab,var(--primary)5%,transparent)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-400{background-color:var(--color-red-400)}.bg-red-500{background-color:var(--color-red-500)}.bg-secondary{background-color:var(--secondary)}.bg-transparent{background-color:#0000}.bg-white\/30{background-color:color-mix(in oklab,var(--color-white)30%,transparent)}.bg-yellow-100{background-color:var(--color-yellow-100)}.bg-zinc-200{background-color:var(--color-zinc-200)}.bg-zinc-800{background-color:var(--color-zinc-800)}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-emerald-50{--tw-gradient-from:var(--color-emerald-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-teal-100{--tw-gradient-to:var(--color-teal-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.object-cover{object-fit:cover}.\!p-0{padding:calc(var(--spacing)*0)!important}.p-0{padding:calc(var(--spacing)*0)}.p-1{padding:calc(var(--spacing)*1)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.p-16{padding:calc(var(--spacing)*16)}.p-\[1px\]{padding:1px}.px-1{padding-inline:calc(var(--spacing)*1)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.px-6{padding-inline:calc(var(--spacing)*6)}.px-8{padding-inline:calc(var(--spacing)*8)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-6{padding-block:calc(var(--spacing)*6)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-6{padding-top:calc(var(--spacing)*6)}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-2{padding-right:calc(var(--spacing)*2)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-8{padding-bottom:calc(var(--spacing)*8)}.pb-12{padding-bottom:calc(var(--spacing)*12)}.pl-1{padding-left:calc(var(--spacing)*1)}.pl-5{padding-left:calc(var(--spacing)*5)}.pl-8{padding-left:calc(var(--spacing)*8)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.text-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.\!text-zinc-50{color:var(--color-zinc-50)!important}.text-amber-700{color:var(--color-amber-700)}.text-amber-800{color:var(--color-amber-800)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-card-foreground{color:var(--card-foreground)}.text-current{color:currentColor}.text-destructive{color:var(--destructive)}.text-destructive-foreground{color:var(--destructive-foreground)}.text-emerald-400{color:var(--color-emerald-400)}.text-emerald-700{color:var(--color-emerald-700)}.text-foreground{color:var(--foreground)}.text-foreground\/80{color:color-mix(in oklab,var(--foreground)80%,transparent)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-700{color:var(--color-gray-700)}.text-gray-900{color:var(--color-gray-900)}.text-green-600{color:var(--color-green-600)}.text-muted-foreground{color:var(--muted-foreground)}.text-muted-foreground\/70{color:color-mix(in oklab,var(--muted-foreground)70%,transparent)}.text-orange-500{color:var(--color-orange-500)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-primary\/60{color:color-mix(in oklab,var(--primary)60%,transparent)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-violet-700{color:var(--color-violet-700)}.text-yellow-600{color:var(--color-yellow-600)}.text-zinc-100{color:var(--color-zinc-100)}.text-zinc-800{color:var(--color-zinc-800)}.lowercase{text-transform:lowercase}.italic{font-style:italic}.underline{text-decoration-line:underline}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-20{opacity:.2}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_8px_rgba\(0\,0\,0\,0\.2\)\]{--tw-shadow:0 0 8px var(--tw-shadow-color,#0003);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_12px_rgba\(34\,197\,94\,0\.4\)\]{--tw-shadow:0 0 12px var(--tw-shadow-color,#22c55e66);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_12px_rgba\(239\,68\,68\,0\.4\)\]{--tw-shadow:0 0 12px var(--tw-shadow-color,#ef444466);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[inset_0_-1px_0_rgba\(0\,0\,0\,0\.1\)\]{--tw-shadow:inset 0 -1px 0 var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-offset-background{--tw-ring-offset-color:var(--background)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.backdrop-blur-lg{--tw-backdrop-blur:blur(var(--blur-lg));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-2000{--tw-duration:2s;transition-duration:2s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.animate-in{--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial;animation-name:enter;animation-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.duration-200{animation-duration:.2s}.duration-300{animation-duration:.3s}.duration-2000{animation-duration:2s}.ease-out{animation-timing-function:cubic-bezier(0,0,.2,1)}.fade-in-0{--tw-enter-opacity:0}.running{animation-play-state:running}.zoom-in-95{--tw-enter-scale:.95}@media (hover:hover){.group-hover\:visible:is(:where(.group):hover *){visibility:visible}}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.peer-disabled\:opacity-70:is(:where(.peer):disabled~*){opacity:.7}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--foreground)}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}@media (hover:hover){.hover\:w-fit:hover{width:fit-content}.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:bg-background\/60:hover{background-color:color-mix(in oklab,var(--background)60%,transparent)}.hover\:bg-destructive\/80:hover{background-color:color-mix(in oklab,var(--destructive)80%,transparent)}.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab,var(--destructive)90%,transparent)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-200:hover{background-color:var(--color-gray-200)}.hover\:bg-muted:hover{background-color:var(--muted)}.hover\:bg-muted\/25:hover{background-color:color-mix(in oklab,var(--muted)25%,transparent)}.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab,var(--muted)50%,transparent)}.hover\:bg-primary\/5:hover{background-color:color-mix(in oklab,var(--primary)5%,transparent)}.hover\:bg-primary\/20:hover{background-color:color-mix(in oklab,var(--primary)20%,transparent)}.hover\:bg-primary\/80:hover{background-color:color-mix(in oklab,var(--primary)80%,transparent)}.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--primary)90%,transparent)}.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab,var(--secondary)80%,transparent)}.hover\:bg-zinc-300:hover{background-color:var(--color-zinc-300)}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:text-gray-700:hover{color:var(--color-gray-700)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}}.focus\:bg-accent:focus{background-color:var(--accent)}.focus\:text-accent-foreground:focus{color:var(--accent-foreground)}.focus\:ring-0:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-ring:focus{--tw-ring-color:var(--ring)}.focus\:ring-offset-0:focus{--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:outline-0:focus{outline-style:var(--tw-outline-style);outline-width:0}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:relative:focus-visible{position:relative}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--ring)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.active\:right-0:active{right:calc(var(--spacing)*0)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[disabled\=true\]\:pointer-events-none[data-disabled=true]{pointer-events:none}.data-\[disabled\=true\]\:opacity-50[data-disabled=true]{opacity:.5}.data-\[selected\=\'true\'\]\:bg-accent[data-selected=true]{background-color:var(--accent)}.data-\[selected\=true\]\:text-accent-foreground[data-selected=true]{color:var(--accent-foreground)}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y:calc(var(--spacing)*1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=bottom\]\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y:-.5rem}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=left\]\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x:.5rem}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x:calc(var(--spacing)*1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=right\]\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x:-.5rem}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=top\]\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y:.5rem}.data-\[state\=active\]\:visible[data-state=active]{visibility:visible}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:var(--background)}.data-\[state\=active\]\:text-foreground[data-state=active]{color:var(--foreground)}.data-\[state\=active\]\:shadow-sm[data-state=active]{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.data-\[state\=checked\]\:bg-muted[data-state=checked]{background-color:var(--muted)}.data-\[state\=checked\]\:text-muted-foreground[data-state=checked]{color:var(--muted-foreground)}.data-\[state\=closed\]\:animate-out[data-state=closed]{--tw-exit-opacity:initial;--tw-exit-scale:initial;--tw-exit-rotate:initial;--tw-exit-translate-x:initial;--tw-exit-translate-y:initial;animation-name:exit;animation-duration:.15s}.data-\[state\=closed\]\:fade-out-0[data-state=closed]{--tw-exit-opacity:0}.data-\[state\=closed\]\:slide-out-to-top-\[48\%\][data-state=closed]{--tw-exit-translate-y:-48%}.data-\[state\=closed\]\:zoom-out-95[data-state=closed]{--tw-exit-scale:.95}.data-\[state\=inactive\]\:invisible[data-state=inactive]{visibility:hidden}.data-\[state\=open\]\:bg-accent[data-state=open]{background-color:var(--accent)}.data-\[state\=open\]\:text-muted-foreground[data-state=open]{color:var(--muted-foreground)}.data-\[state\=open\]\:animate-in[data-state=open]{--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial;animation-name:enter;animation-duration:.15s}.data-\[state\=open\]\:fade-in-0[data-state=open]{--tw-enter-opacity:0}.data-\[state\=open\]\:slide-in-from-top-\[48\%\][data-state=open]{--tw-enter-translate-y:-48%}.data-\[state\=open\]\:zoom-in-95[data-state=open]{--tw-enter-scale:.95}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:var(--muted)}@supports ((-webkit-backdrop-filter:var(--tw)) or (backdrop-filter:var(--tw))){.supports-\[backdrop-filter\]\:bg-background\/60{background-color:color-mix(in oklab,var(--background)60%,transparent)}.supports-\[backdrop-filter\]\:bg-card\/75{background-color:color-mix(in oklab,var(--card)75%,transparent)}}@media (width>=40rem){.sm\:mt-0{margin-top:calc(var(--spacing)*0)}.sm\:max-w-\[500px\]{max-width:500px}.sm\:max-w-\[800px\]{max-width:800px}.sm\:max-w-md{max-width:var(--container-md)}.sm\:max-w-xl{max-width:var(--container-xl)}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}:where(.sm\:space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:var(--radius)}.sm\:px-5{padding-inline:calc(var(--spacing)*5)}.sm\:text-left{text-align:left}}@media (width>=48rem){.md\:inline-block{display:inline-block}.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.dark\:border-blue-600:is(.dark *){border-color:var(--color-blue-600)}.dark\:border-destructive:is(.dark *){border-color:var(--destructive)}.dark\:border-gray-500:is(.dark *){border-color:var(--color-gray-500)}.dark\:border-gray-600:is(.dark *){border-color:var(--color-gray-600)}.dark\:border-gray-700:is(.dark *){border-color:var(--color-gray-700)}.dark\:border-green-600:is(.dark *){border-color:var(--color-green-600)}.dark\:border-red-600:is(.dark *){border-color:var(--color-red-600)}.dark\:border-yellow-600:is(.dark *){border-color:var(--color-yellow-600)}.dark\:bg-amber-900:is(.dark *){background-color:var(--color-amber-900)}.dark\:bg-blue-900\/30:is(.dark *){background-color:color-mix(in oklab,var(--color-blue-900)30%,transparent)}.dark\:bg-gray-800\/30:is(.dark *){background-color:color-mix(in oklab,var(--color-gray-800)30%,transparent)}.dark\:bg-gray-900:is(.dark *){background-color:var(--color-gray-900)}.dark\:bg-green-900\/30:is(.dark *){background-color:color-mix(in oklab,var(--color-green-900)30%,transparent)}.dark\:bg-red-900\/30:is(.dark *){background-color:color-mix(in oklab,var(--color-red-900)30%,transparent)}.dark\:bg-red-950:is(.dark *){background-color:var(--color-red-950)}.dark\:bg-yellow-900\/30:is(.dark *){background-color:color-mix(in oklab,var(--color-yellow-900)30%,transparent)}.dark\:bg-zinc-700:is(.dark *){background-color:var(--color-zinc-700)}.dark\:from-gray-900:is(.dark *){--tw-gradient-from:var(--color-gray-900);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.dark\:to-gray-800:is(.dark *){--tw-gradient-to:var(--color-gray-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.dark\:text-amber-200:is(.dark *){color:var(--color-amber-200)}.dark\:text-gray-300:is(.dark *){color:var(--color-gray-300)}.dark\:text-gray-400:is(.dark *){color:var(--color-gray-400)}.dark\:text-red-400:is(.dark *){color:var(--color-red-400)}.dark\:text-zinc-200:is(.dark *){color:var(--color-zinc-200)}@media (hover:hover){.dark\:hover\:bg-gray-700:is(.dark *):hover{background-color:var(--color-gray-700)}.dark\:hover\:bg-gray-800:is(.dark *):hover{background-color:var(--color-gray-800)}.dark\:hover\:bg-zinc-600:is(.dark *):hover{background-color:var(--color-zinc-600)}}.\[\&_\[cmdk-group-heading\]\]\:px-2 [cmdk-group-heading]{padding-inline:calc(var(--spacing)*2)}.\[\&_\[cmdk-group-heading\]\]\:py-1\.5 [cmdk-group-heading]{padding-block:calc(var(--spacing)*1.5)}.\[\&_\[cmdk-group-heading\]\]\:text-xs [cmdk-group-heading]{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\[\&_\[cmdk-group-heading\]\]\:font-medium [cmdk-group-heading]{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.\[\&_\[cmdk-group-heading\]\]\:text-muted-foreground [cmdk-group-heading]{color:var(--muted-foreground)}.\[\&_\[cmdk-group\]\]\:px-2 [cmdk-group]{padding-inline:calc(var(--spacing)*2)}.\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0 [cmdk-group]:not([hidden])~[cmdk-group]{padding-top:calc(var(--spacing)*0)}.\[\&_\[cmdk-input-wrapper\]_svg\]\:h-5 [cmdk-input-wrapper] svg{height:calc(var(--spacing)*5)}.\[\&_\[cmdk-input-wrapper\]_svg\]\:w-5 [cmdk-input-wrapper] svg{width:calc(var(--spacing)*5)}.\[\&_\[cmdk-input\]\]\:h-12 [cmdk-input]{height:calc(var(--spacing)*12)}.\[\&_\[cmdk-item\]\]\:px-2 [cmdk-item]{padding-inline:calc(var(--spacing)*2)}.\[\&_\[cmdk-item\]\]\:py-3 [cmdk-item]{padding-block:calc(var(--spacing)*3)}.\[\&_\[cmdk-item\]_svg\]\:h-5 [cmdk-item] svg{height:calc(var(--spacing)*5)}.\[\&_\[cmdk-item\]_svg\]\:w-5 [cmdk-item] svg{width:calc(var(--spacing)*5)}.\[\&_p\]\:leading-relaxed p{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&\:\:-webkit-inner-spin-button\]\:appearance-none::-webkit-inner-spin-button{-webkit-appearance:none;-moz-appearance:none;appearance:none}.\[\&\:\:-webkit-inner-spin-button\]\:opacity-50::-webkit-inner-spin-button{opacity:.5}.\[\&\:\:-webkit-outer-spin-button\]\:appearance-none::-webkit-outer-spin-button{-webkit-appearance:none;-moz-appearance:none;appearance:none}.\[\&\:\:-webkit-outer-spin-button\]\:opacity-50::-webkit-outer-spin-button{opacity:.5}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:calc(var(--spacing)*0)}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y:2px;translate:var(--tw-translate-x)var(--tw-translate-y)}.\[\&\>span\]\:line-clamp-1>span{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\[\&\>svg\]\:absolute>svg{position:absolute}.\[\&\>svg\]\:top-4>svg{top:calc(var(--spacing)*4)}.\[\&\>svg\]\:left-4>svg{left:calc(var(--spacing)*4)}.\[\&\>svg\]\:text-destructive>svg{color:var(--destructive)}.\[\&\>svg\]\:text-foreground>svg{color:var(--foreground)}.\[\&\>svg\+div\]\:translate-y-\[-3px\]>svg+div{--tw-translate-y:-3px;translate:var(--tw-translate-x)var(--tw-translate-y)}.\[\&\>svg\~\*\]\:pl-7>svg~*{padding-left:calc(var(--spacing)*7)}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}}:root{--background:#fff;--foreground:#09090b;--card:#fff;--card-foreground:#09090b;--popover:#fff;--popover-foreground:#09090b;--primary:#18181b;--primary-foreground:#fafafa;--secondary:#f4f4f5;--secondary-foreground:#18181b;--muted:#f4f4f5;--muted-foreground:#71717a;--accent:#f4f4f5;--accent-foreground:#18181b;--destructive:#ef4444;--destructive-foreground:#fafafa;--border:#e4e4e7;--input:#e4e4e7;--ring:#09090b;--chart-1:#e76e50;--chart-2:#2a9d90;--chart-3:#274754;--chart-4:#e8c468;--chart-5:#f4a462;--radius:.6rem;--sidebar-background:#fafafa;--sidebar-foreground:#3f3f46;--sidebar-primary:#18181b;--sidebar-primary-foreground:#fafafa;--sidebar-accent:#f4f4f5;--sidebar-accent-foreground:#18181b;--sidebar-border:#e5e7eb;--sidebar-ring:#3b82f6}.dark{--background:#09090b;--foreground:#fafafa;--card:#09090b;--card-foreground:#fafafa;--popover:#09090b;--popover-foreground:#fafafa;--primary:#fafafa;--primary-foreground:#18181b;--secondary:#27272a;--secondary-foreground:#fafafa;--muted:#27272a;--muted-foreground:#a1a1aa;--accent:#27272a;--accent-foreground:#fafafa;--destructive:#7f1d1d;--destructive-foreground:#fafafa;--border:#27272a;--input:#27272a;--ring:#d4d4d8;--chart-1:#2662d9;--chart-2:#2eb88a;--chart-3:#e88c30;--chart-4:#af57db;--chart-5:#e23670;--sidebar-background:#18181b;--sidebar-foreground:#f4f4f5;--sidebar-primary:#1d4ed8;--sidebar-primary-foreground:#fff;--sidebar-accent:#27272a;--sidebar-accent-foreground:#f4f4f5;--sidebar-border:#27272a;--sidebar-ring:#3b82f6}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-thumb{background-color:#ccc;border-radius:5px}::-webkit-scrollbar-track{background-color:#f2f2f2}.dark ::-webkit-scrollbar-thumb{background-color:#e6e6e6}.dark ::-webkit-scrollbar-track{background-color:#000}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0))}}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false;initial-value:rotateX(0)}@property --tw-rotate-y{syntax:"*";inherits:false;initial-value:rotateY(0)}@property --tw-rotate-z{syntax:"*";inherits:false;initial-value:rotateZ(0)}@property --tw-skew-x{syntax:"*";inherits:false;initial-value:skewX(0)}@property --tw-skew-y{syntax:"*";inherits:false;initial-value:skewY(0)}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false} diff --git a/lightrag/api/webui/index.html b/lightrag/api/webui/index.html index ece06710..ffd4177e 100644 --- a/lightrag/api/webui/index.html +++ b/lightrag/api/webui/index.html @@ -8,7 +8,7 @@ Lightrag - + @@ -17,9 +17,9 @@ - + - +
diff --git a/lightrag/kg/chroma_impl.py b/lightrag/kg/chroma_impl.py index 020e358f..627cf480 100644 --- a/lightrag/kg/chroma_impl.py +++ b/lightrag/kg/chroma_impl.py @@ -161,7 +161,9 @@ class ChromaVectorDBStorage(BaseVectorStorage): self, query: str, top_k: int, ids: list[str] | None = None ) -> list[dict[str, Any]]: try: - embedding = await self.embedding_func([query]) + embedding = await self.embedding_func( + [query], _priority=5 + ) # higher priority for query results = self._collection.query( query_embeddings=embedding.tolist() diff --git a/lightrag/kg/faiss_impl.py b/lightrag/kg/faiss_impl.py index 3022e6f6..d4e6ad01 100644 --- a/lightrag/kg/faiss_impl.py +++ b/lightrag/kg/faiss_impl.py @@ -175,7 +175,9 @@ class FaissVectorDBStorage(BaseVectorStorage): """ Search by a textual query; returns top_k results with their metadata + similarity distance. """ - embedding = await self.embedding_func([query]) + embedding = await self.embedding_func( + [query], _priority=5 + ) # higher priority for query # embedding is shape (1, dim) embedding = np.array(embedding, dtype=np.float32) faiss.normalize_L2(embedding) # we do in-place normalization diff --git a/lightrag/kg/json_kv_impl.py b/lightrag/kg/json_kv_impl.py index 62f7289d..2d44ce00 100644 --- a/lightrag/kg/json_kv_impl.py +++ b/lightrag/kg/json_kv_impl.py @@ -197,3 +197,10 @@ class JsonKVStorage(BaseKVStorage): except Exception as e: logger.error(f"Error dropping {self.namespace}: {e}") return {"status": "error", "message": str(e)} + + async def finalize(self): + """Finalize storage resources + Persistence cache data to disk before exiting + """ + if self.namespace.endswith("cache"): + await self.index_done_callback() diff --git a/lightrag/kg/milvus_impl.py b/lightrag/kg/milvus_impl.py index 2cff0079..74e0f039 100644 --- a/lightrag/kg/milvus_impl.py +++ b/lightrag/kg/milvus_impl.py @@ -104,7 +104,9 @@ class MilvusVectorDBStorage(BaseVectorStorage): async def query( self, query: str, top_k: int, ids: list[str] | None = None ) -> list[dict[str, Any]]: - embedding = await self.embedding_func([query]) + embedding = await self.embedding_func( + [query], _priority=5 + ) # higher priority for query results = self._client.search( collection_name=self.namespace, data=embedding, diff --git a/lightrag/kg/mongo_impl.py b/lightrag/kg/mongo_impl.py index bc4bb240..f4b15d60 100644 --- a/lightrag/kg/mongo_impl.py +++ b/lightrag/kg/mongo_impl.py @@ -1032,7 +1032,9 @@ class MongoVectorDBStorage(BaseVectorStorage): ) -> list[dict[str, Any]]: """Queries the vector database using Atlas Vector Search.""" # Generate the embedding - embedding = await self.embedding_func([query]) + embedding = await self.embedding_func( + [query], _priority=5 + ) # higher priority for query # Convert numpy array to a list to ensure compatibility with MongoDB query_vector = embedding[0].tolist() diff --git a/lightrag/kg/nano_vector_db_impl.py b/lightrag/kg/nano_vector_db_impl.py index 3003eea0..589dd9ee 100644 --- a/lightrag/kg/nano_vector_db_impl.py +++ b/lightrag/kg/nano_vector_db_impl.py @@ -124,8 +124,10 @@ class NanoVectorDBStorage(BaseVectorStorage): async def query( self, query: str, top_k: int, ids: list[str] | None = None ) -> list[dict[str, Any]]: - # Execute embedding outside of lock to avoid long lock times - embedding = await self.embedding_func([query]) + # Execute embedding outside of lock to avoid improve cocurrent + embedding = await self.embedding_func( + [query], _priority=5 + ) # higher priority for query embedding = embedding[0] client = await self._get_client() diff --git a/lightrag/kg/postgres_impl.py b/lightrag/kg/postgres_impl.py index 07b30d08..cb302e8c 100644 --- a/lightrag/kg/postgres_impl.py +++ b/lightrag/kg/postgres_impl.py @@ -644,7 +644,9 @@ class PGVectorStorage(BaseVectorStorage): async def query( self, query: str, top_k: int, ids: list[str] | None = None ) -> list[dict[str, Any]]: - embeddings = await self.embedding_func([query]) + embeddings = await self.embedding_func( + [query], _priority=5 + ) # higher priority for query embedding = embeddings[0] embedding_string = ",".join(map(str, embedding)) # Use parameterized document IDs (None means search across all documents) diff --git a/lightrag/kg/qdrant_impl.py b/lightrag/kg/qdrant_impl.py index d758ca5c..e0d0c9c3 100644 --- a/lightrag/kg/qdrant_impl.py +++ b/lightrag/kg/qdrant_impl.py @@ -124,7 +124,9 @@ class QdrantVectorDBStorage(BaseVectorStorage): async def query( self, query: str, top_k: int, ids: list[str] | None = None ) -> list[dict[str, Any]]: - embedding = await self.embedding_func([query]) + embedding = await self.embedding_func( + [query], _priority=5 + ) # higher priority for query results = self._client.search( collection_name=self.namespace, query_vector=embedding[0], diff --git a/lightrag/kg/shared_storage.py b/lightrag/kg/shared_storage.py index 1ba73812..10e83e56 100644 --- a/lightrag/kg/shared_storage.py +++ b/lightrag/kg/shared_storage.py @@ -65,17 +65,17 @@ class UnifiedLock(Generic[T]): async def __aenter__(self) -> "UnifiedLock[T]": try: - direct_log( - f"== Lock == Process {self._pid}: Acquiring lock '{self._name}' (async={self._is_async})", - enable_output=self._enable_logging, - ) + # direct_log( + # f"== Lock == Process {self._pid}: Acquiring lock '{self._name}' (async={self._is_async})", + # enable_output=self._enable_logging, + # ) # If in multiprocess mode and async lock exists, acquire it first if not self._is_async and self._async_lock is not None: - direct_log( - f"== Lock == Process {self._pid}: Acquiring async lock for '{self._name}'", - enable_output=self._enable_logging, - ) + # direct_log( + # f"== Lock == Process {self._pid}: Acquiring async lock for '{self._name}'", + # enable_output=self._enable_logging, + # ) await self._async_lock.acquire() direct_log( f"== Lock == Process {self._pid}: Async lock for '{self._name}' acquired", @@ -112,10 +112,10 @@ class UnifiedLock(Generic[T]): async def __aexit__(self, exc_type, exc_val, exc_tb): main_lock_released = False try: - direct_log( - f"== Lock == Process {self._pid}: Releasing lock '{self._name}' (async={self._is_async})", - enable_output=self._enable_logging, - ) + # direct_log( + # f"== Lock == Process {self._pid}: Releasing lock '{self._name}' (async={self._is_async})", + # enable_output=self._enable_logging, + # ) # Release main lock first if self._is_async: @@ -127,10 +127,10 @@ class UnifiedLock(Generic[T]): # Then release async lock if in multiprocess mode if not self._is_async and self._async_lock is not None: - direct_log( - f"== Lock == Process {self._pid}: Releasing async lock for '{self._name}'", - enable_output=self._enable_logging, - ) + # direct_log( + # f"== Lock == Process {self._pid}: Releasing async lock for '{self._name}'", + # enable_output=self._enable_logging, + # ) self._async_lock.release() direct_log( diff --git a/lightrag/kg/tidb_impl.py b/lightrag/kg/tidb_impl.py index 33ad1567..fb52b744 100644 --- a/lightrag/kg/tidb_impl.py +++ b/lightrag/kg/tidb_impl.py @@ -390,7 +390,9 @@ class TiDBVectorDBStorage(BaseVectorStorage): self, query: str, top_k: int, ids: list[str] | None = None ) -> list[dict[str, Any]]: """Search from tidb vector""" - embeddings = await self.embedding_func([query]) + embeddings = await self.embedding_func( + [query], _priority=5 + ) # higher priority for query embedding = embeddings[0] embedding_string = "[" + ", ".join(map(str, embedding.tolist())) + "]" diff --git a/lightrag/lightrag.py b/lightrag/lightrag.py index d89e9052..7a79da31 100644 --- a/lightrag/lightrag.py +++ b/lightrag/lightrag.py @@ -61,7 +61,7 @@ from .utils import ( compute_mdhash_id, convert_response_to_json, lazy_external_import, - limit_async_func_call, + priority_limit_async_func_call, get_content_summary, clean_text, check_storage_env_vars, @@ -338,9 +338,9 @@ class LightRAG: logger.debug(f"LightRAG init with param:\n {_print_config}\n") # Init Embedding - self.embedding_func = limit_async_func_call(self.embedding_func_max_async)( # type: ignore - self.embedding_func - ) + self.embedding_func = priority_limit_async_func_call( + self.embedding_func_max_async + )(self.embedding_func) # Initialize all storages self.key_string_value_json_storage_cls: type[BaseKVStorage] = ( @@ -426,7 +426,7 @@ class LightRAG: # Directly use llm_response_cache, don't create a new object hashing_kv = self.llm_response_cache - self.llm_model_func = limit_async_func_call(self.llm_model_max_async)( + self.llm_model_func = priority_limit_async_func_call(self.llm_model_max_async)( partial( self.llm_model_func, # type: ignore hashing_kv=hashing_kv, @@ -1024,7 +1024,8 @@ class LightRAG: } ) - # Release semphore before entering to merge stage + # Semphore was released here + if file_extraction_stage_ok: try: # Get chunk_results from entity_relation_task @@ -1152,9 +1153,6 @@ class LightRAG: try: chunk_results = await extract_entities( chunk, - knowledge_graph_inst=self.chunk_entity_relation_graph, - entity_vdb=self.entities_vdb, - relationships_vdb=self.relationships_vdb, global_config=asdict(self), pipeline_status=pipeline_status, pipeline_status_lock=pipeline_status_lock, @@ -1445,6 +1443,9 @@ class LightRAG: elif param.mode == "bypass": # Bypass mode: directly use LLM without knowledge retrieval use_llm_func = param.model_func or global_config["llm_model_func"] + # Apply higher priority (8) to entity/relation summary tasks + use_llm_func = partial(use_llm_func, _priority=8) + param.stream = True if param.stream is None else param.stream response = await use_llm_func( query.strip(), diff --git a/lightrag/operate.py b/lightrag/operate.py index 14bcdae2..7543e6ba 100644 --- a/lightrag/operate.py +++ b/lightrag/operate.py @@ -1,4 +1,5 @@ from __future__ import annotations +from functools import partial import asyncio import traceback @@ -112,6 +113,9 @@ async def _handle_entity_relation_summary( If too long, use LLM to summarize. """ use_llm_func: callable = global_config["llm_model_func"] + # Apply higher priority (8) to entity/relation summary tasks + use_llm_func = partial(use_llm_func, _priority=8) + tokenizer: Tokenizer = global_config["tokenizer"] llm_max_tokens = global_config["llm_model_max_token_size"] summary_max_tokens = global_config["summary_to_max_tokens"] @@ -136,7 +140,7 @@ async def _handle_entity_relation_summary( use_prompt = prompt_template.format(**context_base) logger.debug(f"Trigger summary: {entity_or_relation_name}") - # Use LLM function with cache + # Use LLM function with cache (higher priority for summary generation) summary = await use_llm_func_with_cache( use_prompt, use_llm_func, @@ -504,8 +508,6 @@ async def merge_nodes_and_edges( # Get lock manager from shared storage from .kg.shared_storage import get_graph_db_lock - graph_db_lock = get_graph_db_lock(enable_logging=False) - # Collect all nodes and edges from all chunks all_nodes = defaultdict(list) all_edges = defaultdict(list) @@ -526,6 +528,7 @@ async def merge_nodes_and_edges( # Merge nodes and edges # Use graph database lock to ensure atomic merges and updates + graph_db_lock = get_graph_db_lock(enable_logging=True) async with graph_db_lock: async with pipeline_status_lock: log_message = ( @@ -612,9 +615,6 @@ async def merge_nodes_and_edges( async def extract_entities( chunks: dict[str, TextChunkSchema], - knowledge_graph_inst: BaseGraphStorage, - entity_vdb: BaseVectorStorage, - relationships_vdb: BaseVectorStorage, global_config: dict[str, str], pipeline_status: dict = None, pipeline_status_lock=None, @@ -849,12 +849,14 @@ async def kg_query( hashing_kv: BaseKVStorage | None = None, system_prompt: str | None = None, ) -> str | AsyncIterator[str]: + if query_param.model_func: + use_model_func = query_param.model_func + else: + use_model_func = global_config["llm_model_func"] + # Apply higher priority (5) to query relation LLM function + use_model_func = partial(use_model_func, _priority=5) + # Handle cache - use_model_func = ( - query_param.model_func - if query_param.model_func - else global_config["llm_model_func"] - ) args_hash = compute_args_hash(query_param.mode, query, cache_type="query") cached_response, quantized, min_val, max_val = await handle_cache( hashing_kv, args_hash, query, query_param.mode, cache_type="query" @@ -1050,9 +1052,13 @@ async def extract_keywords_only( logger.debug(f"[kg_query]Prompt Tokens: {len_of_prompts}") # 5. Call the LLM for keyword extraction - use_model_func = ( - param.model_func if param.model_func else global_config["llm_model_func"] - ) + if param.model_func: + use_model_func = param.model_func + else: + use_model_func = global_config["llm_model_func"] + # Apply higher priority (5) to query relation LLM function + use_model_func = partial(use_model_func, _priority=5) + result = await use_model_func(kw_prompt, keyword_extraction=True) # 6. Parse out JSON from the LLM response @@ -1115,12 +1121,15 @@ async def mix_kg_vector_query( """ # get tokenizer tokenizer: Tokenizer = global_config["tokenizer"] + + if query_param.model_func: + use_model_func = query_param.model_func + else: + use_model_func = global_config["llm_model_func"] + # Apply higher priority (5) to query relation LLM function + use_model_func = partial(use_model_func, _priority=5) + # 1. Cache handling - use_model_func = ( - query_param.model_func - if query_param.model_func - else global_config["llm_model_func"] - ) args_hash = compute_args_hash("mix", query, cache_type="query") cached_response, quantized, min_val, max_val = await handle_cache( hashing_kv, args_hash, query, "mix", cache_type="query" @@ -2006,12 +2015,14 @@ async def naive_query( hashing_kv: BaseKVStorage | None = None, system_prompt: str | None = None, ) -> str | AsyncIterator[str]: + if query_param.model_func: + use_model_func = query_param.model_func + else: + use_model_func = global_config["llm_model_func"] + # Apply higher priority (5) to query relation LLM function + use_model_func = partial(use_model_func, _priority=5) + # Handle cache - use_model_func = ( - query_param.model_func - if query_param.model_func - else global_config["llm_model_func"] - ) args_hash = compute_args_hash(query_param.mode, query, cache_type="query") cached_response, quantized, min_val, max_val = await handle_cache( hashing_kv, args_hash, query, query_param.mode, cache_type="query" @@ -2138,15 +2149,16 @@ async def kg_query_with_keywords( It expects hl_keywords and ll_keywords to be set in query_param, or defaults to empty. Then it uses those to build context and produce a final LLM response. """ + if query_param.model_func: + use_model_func = query_param.model_func + else: + use_model_func = global_config["llm_model_func"] + # Apply higher priority (5) to query relation LLM function + use_model_func = partial(use_model_func, _priority=5) # --------------------------- # 1) Handle potential cache for query results # --------------------------- - use_model_func = ( - query_param.model_func - if query_param.model_func - else global_config["llm_model_func"] - ) args_hash = compute_args_hash(query_param.mode, query, cache_type="query") cached_response, quantized, min_val, max_val = await handle_cache( hashing_kv, args_hash, query, query_param.mode, cache_type="query" diff --git a/lightrag/utils.py b/lightrag/utils.py index b57acc37..574e3ecd 100644 --- a/lightrag/utils.py +++ b/lightrag/utils.py @@ -1,4 +1,5 @@ from __future__ import annotations +import weakref import asyncio import html @@ -267,17 +268,261 @@ def compute_mdhash_id(content: str, prefix: str = "") -> str: return prefix + md5(content.encode()).hexdigest() -def limit_async_func_call(max_size: int): - """Add restriction of maximum concurrent async calls using asyncio.Semaphore""" +# Custom exception class +class QueueFullError(Exception): + """Raised when the queue is full and the wait times out""" + + pass + + +def priority_limit_async_func_call(max_size: int, max_queue_size: int = 1000): + """ + Enhanced priority-limited asynchronous function call decorator + + Args: + max_size: Maximum number of concurrent calls + max_queue_size: Maximum queue capacity to prevent memory overflow + Returns: + Decorator function + """ def final_decro(func): - sem = asyncio.Semaphore(max_size) + queue = asyncio.PriorityQueue(maxsize=max_queue_size) + tasks = set() + initialization_lock = asyncio.Lock() + counter = 0 + shutdown_event = asyncio.Event() + initialized = False # Global initialization flag + worker_health_check_task = None + + # Track active future objects for cleanup + active_futures = weakref.WeakSet() + + # Worker function to process tasks in the queue + async def worker(): + """Worker that processes tasks in the priority queue""" + try: + while not shutdown_event.is_set(): + try: + # Use timeout to get tasks, allowing periodic checking of shutdown signal + try: + ( + priority, + count, + future, + args, + kwargs, + ) = await asyncio.wait_for(queue.get(), timeout=1.0) + except asyncio.TimeoutError: + # Timeout is just to check shutdown signal, continue to next iteration + continue + + # If future is cancelled, skip execution + if future.cancelled(): + queue.task_done() + continue + + try: + # Execute function + result = await func(*args, **kwargs) + # If future is not done, set the result + if not future.done(): + future.set_result(result) + except asyncio.CancelledError: + if not future.done(): + future.cancel() + logger.debug("limit_async: Task cancelled during execution") + except Exception as e: + logger.error( + f"limit_async: Error in decorated function: {str(e)}" + ) + if not future.done(): + future.set_exception(e) + finally: + queue.task_done() + except Exception as e: + # Catch all exceptions in worker loop to prevent worker termination + logger.error(f"limit_async: Critical error in worker: {str(e)}") + await asyncio.sleep(0.1) # Prevent high CPU usage + finally: + logger.warning("limit_async: Worker exiting") + + async def health_check(): + """Periodically check worker health status and recover""" + try: + while not shutdown_event.is_set(): + await asyncio.sleep(5) # Check every 5 seconds + + # No longer acquire lock, directly operate on task set + # Use a copy of the task set to avoid concurrent modification + current_tasks = set(tasks) + done_tasks = {t for t in current_tasks if t.done()} + tasks.difference_update(done_tasks) + + # Calculate active tasks count + active_tasks_count = len(tasks) + workers_needed = max_size - active_tasks_count + + if workers_needed > 0: + logger.info( + f"limit_async: Creating {workers_needed} new workers" + ) + new_tasks = set() + for _ in range(workers_needed): + task = asyncio.create_task(worker()) + new_tasks.add(task) + task.add_done_callback(tasks.discard) + # Update task set in one operation + tasks.update(new_tasks) + except Exception as e: + logger.error(f"limit_async: Error in health check: {str(e)}") + finally: + logger.warning("limit_async: Health check task exiting") + + async def ensure_workers(): + """Ensure worker threads and health check system are available + + This function checks if the worker system is already initialized. + If not, it performs a one-time initialization of all worker threads + and starts the health check system. + """ + nonlocal initialized, worker_health_check_task, tasks + + if initialized: + return + + async with initialization_lock: + if initialized: + return + + logger.info("limit_async: Initializing worker system") + + # Create initial worker tasks + for _ in range(max_size): + task = asyncio.create_task(worker()) + tasks.add(task) + task.add_done_callback(tasks.discard) + + # Start health check + worker_health_check_task = asyncio.create_task(health_check()) + + initialized = True + logger.info("limit_async: Worker system initialized") + + async def shutdown(): + """Gracefully shut down all workers and the queue""" + logger.info("limit_async: Shutting down priority queue workers") + + # Set the shutdown event + shutdown_event.set() + + # Cancel all active futures + for future in list(active_futures): + if not future.done(): + future.cancel() + + # Wait for the queue to empty + try: + await asyncio.wait_for(queue.join(), timeout=5.0) + except asyncio.TimeoutError: + logger.warning( + "limit_async: Timeout waiting for queue to empty during shutdown" + ) + + # Cancel all worker tasks + for task in list(tasks): + if not task.done(): + task.cancel() + + # Wait for all tasks to complete + if tasks: + await asyncio.gather(*tasks, return_exceptions=True) + + # Cancel the health check task + if worker_health_check_task and not worker_health_check_task.done(): + worker_health_check_task.cancel() + try: + await worker_health_check_task + except asyncio.CancelledError: + pass + + logger.info("limit_async: Priority queue workers shutdown complete") @wraps(func) - async def wait_func(*args, **kwargs): - async with sem: - result = await func(*args, **kwargs) - return result + async def wait_func( + *args, _priority=10, _timeout=None, _queue_timeout=None, **kwargs + ): + """ + Execute the function with priority-based concurrency control + Args: + *args: Positional arguments passed to the function + _priority: Call priority (lower values have higher priority) + _timeout: Maximum time to wait for function completion (in seconds) + _queue_timeout: Maximum time to wait for entering the queue (in seconds) + **kwargs: Keyword arguments passed to the function + Returns: + The result of the function call + Raises: + TimeoutError: If the function call times out + QueueFullError: If the queue is full and waiting times out + Any exception raised by the decorated function + """ + # Ensure worker system is initialized + await ensure_workers() + + # Create a future for the result + future = asyncio.Future() + active_futures.add(future) + + nonlocal counter + async with initialization_lock: + current_count = counter + counter += 1 + + # Try to put the task into the queue, supporting timeout + try: + if _queue_timeout is not None: + # Use timeout to wait for queue space + try: + await asyncio.wait_for( + queue.put((_priority, current_count, future, args, kwargs)), + timeout=_queue_timeout, + ) + except asyncio.TimeoutError: + raise QueueFullError( + f"Queue full, timeout after {_queue_timeout} seconds" + ) + else: + # No timeout, may wait indefinitely + await queue.put((_priority, current_count, future, args, kwargs)) + except Exception as e: + # Clean up the future + if not future.done(): + future.set_exception(e) + active_futures.discard(future) + raise + + try: + # Wait for the result, optional timeout + if _timeout is not None: + try: + return await asyncio.wait_for(future, _timeout) + except asyncio.TimeoutError: + # Cancel the future + if not future.done(): + future.cancel() + raise TimeoutError( + f"limit_async: Task timed out after {_timeout} seconds" + ) + else: + # Wait for the result without timeout + return await future + finally: + # Clean up the future reference + active_futures.discard(future) + + # Add the shutdown method to the decorated function + wait_func.shutdown = shutdown return wait_func @@ -726,46 +971,10 @@ async def handle_cache( if mode != "default": # handle cache for all type of query if not hashing_kv.global_config.get("enable_llm_cache"): return None, None, None, None - - # TODO: deprecated (PostgreSQL cache not implemented yet) - # Get embedding cache configuration - embedding_cache_config = hashing_kv.global_config.get( - "embedding_cache_config", - {"enabled": False, "similarity_threshold": 0.95, "use_llm_check": False}, - ) - is_embedding_cache_enabled = embedding_cache_config["enabled"] - use_llm_check = embedding_cache_config.get("use_llm_check", False) - - quantized = min_val = max_val = None - if is_embedding_cache_enabled: # Use embedding simularity to match cache - current_embedding = await hashing_kv.embedding_func([prompt]) - llm_model_func = hashing_kv.global_config.get("llm_model_func") - quantized, min_val, max_val = quantize_embedding(current_embedding[0]) - best_cached_response = await get_best_cached_response( - hashing_kv, - current_embedding[0], - similarity_threshold=embedding_cache_config["similarity_threshold"], - mode=mode, - use_llm_check=use_llm_check, - llm_func=llm_model_func if use_llm_check else None, - original_prompt=prompt, - cache_type=cache_type, - ) - if best_cached_response is not None: - logger.debug(f"Embedding cached hit(mode:{mode} type:{cache_type})") - return best_cached_response, None, None, None - else: - # if caching keyword embedding is enabled, return the quantized embedding for saving it latter - logger.debug(f"Embedding cached missed(mode:{mode} type:{cache_type})") - return None, quantized, min_val, max_val - else: # handle cache for entity extraction if not hashing_kv.global_config.get("enable_llm_cache_for_entity_extract"): return None, None, None, None - # Here is the conditions of code reaching this point: - # 1. All query mode: enable_llm_cache is True and embedding simularity is not enabled - # 2. Entity extract: enable_llm_cache_for_entity_extract is True if exists_func(hashing_kv, "get_by_mode_and_id"): mode_cache = await hashing_kv.get_by_mode_and_id(mode, args_hash) or {} else: @@ -1340,7 +1549,7 @@ async def use_llm_func_with_cache( Args: input_text: Input text to send to LLM - use_llm_func: LLM function to call + use_llm_func: LLM function with higher priority llm_response_cache: Cache storage instance max_tokens: Maximum tokens for generation history_messages: History messages list diff --git a/lightrag_webui/src/components/documents/PipelineStatusDialog.tsx b/lightrag_webui/src/components/documents/PipelineStatusDialog.tsx index 58d18434..5e902ecf 100644 --- a/lightrag_webui/src/components/documents/PipelineStatusDialog.tsx +++ b/lightrag_webui/src/components/documents/PipelineStatusDialog.tsx @@ -85,7 +85,7 @@ export default function PipelineStatusDialog({
{t('documentPanel.pipelineStatus.latestMessage')}:
-
+
{status?.latest_message || '-'}
@@ -181,7 +181,7 @@ export default function PipelineStatusDialog({ > {status?.history_messages?.length ? ( status.history_messages.map((msg, idx) => ( -
{msg}
+
{msg}
)) ) : '-'}