diff --git a/env.example b/env.example index 514f8425..4738c8b0 100644 --- a/env.example +++ b/env.example @@ -111,25 +111,37 @@ EMBEDDING_BINDING_HOST=http://localhost:11434 ########################### ### Data storage selection ########################### +### In-memory database with data persistence to local files +# LIGHTRAG_KV_STORAGE=JsonKVStorage +# LIGHTRAG_DOC_STATUS_STORAGE=JsonDocStatusStorage +# LIGHTRAG_GRAPH_STORAGE=NetworkXStorage +# LIGHTRAG_VECTOR_STORAGE=NanoVectorDBStorage +# LIGHTRAG_VECTOR_STORAGE=FaissVectorDBStorage ### PostgreSQL # LIGHTRAG_KV_STORAGE=PGKVStorage # LIGHTRAG_DOC_STATUS_STORAGE=PGDocStatusStorage -# LIGHTRAG_VECTOR_STORAGE=PGVectorStorage # LIGHTRAG_GRAPH_STORAGE=PGGraphStorage -### MongoDB +# LIGHTRAG_VECTOR_STORAGE=PGVectorStorage +### MongoDB (recommended for production deploy) # LIGHTRAG_KV_STORAGE=MongoKVStorage # LIGHTRAG_DOC_STATUS_STORAGE=MongoDocStatusStorage -# LIGHTRAG_VECTOR_STORAGE=MongoVectorDBStorage # LIGHTRAG_GRAPH_STORAGE=MongoGraphStorage -### KV Storage +# LIGHTRAG_VECTOR_STORAGE=MongoVectorDBStorage +### Redis Storage (recommended for production deploy) # LIGHTRAG_KV_STORAGE=RedisKVStorage # LIGHTRAG_DOC_STATUS_STORAGE=RedisDocStatusStorage -### Vector Storage -# LIGHTRAG_VECTOR_STORAGE=FaissVectorDBStorage +### Vector Storage (recommended for production deploy) # LIGHTRAG_VECTOR_STORAGE=MilvusVectorDBStorage -### Graph Storage +# LIGHTRAG_VECTOR_STORAGE=QdrantVectorDBStorage +### Graph Storage (recommended for production deploy) # LIGHTRAG_GRAPH_STORAGE=Neo4JStorage -# LIGHTRAG_GRAPH_STORAGE=MemgraphStorage + +#################################################################### +### Default workspace for all storage types +### For the purpose of isolation of data for each LightRAG instance +### Valid characters: a-z, A-Z, 0-9, and _ +#################################################################### +# WORKSPACE=doc— ### PostgreSQL Configuration POSTGRES_HOST=localhost @@ -138,31 +150,19 @@ POSTGRES_USER=your_username POSTGRES_PASSWORD='your_password' POSTGRES_DATABASE=your_database POSTGRES_MAX_CONNECTIONS=12 -### separating all data from difference Lightrag instances -# POSTGRES_WORKSPACE=default +# POSTGRES_WORKSPACE=forced_workspace_name ### Neo4j Configuration NEO4J_URI=neo4j+s://xxxxxxxx.databases.neo4j.io NEO4J_USERNAME=neo4j NEO4J_PASSWORD='your_password' - -### Independent AGM Configuration(not for AMG embedded in PostreSQL) -# AGE_POSTGRES_DB= -# AGE_POSTGRES_USER= -# AGE_POSTGRES_PASSWORD= -# AGE_POSTGRES_HOST= -# AGE_POSTGRES_PORT=8529 - -# AGE Graph Name(apply to PostgreSQL and independent AGM) -### AGE_GRAPH_NAME is deprecated -# AGE_GRAPH_NAME=lightrag +# NEO4J_WORKSPACE=forced_workspace_name ### MongoDB Configuration MONGO_URI=mongodb://root:root@localhost:27017/ +#MONGO_URI=mongodb+srv://root:rooot@cluster0.xxxx.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0 MONGO_DATABASE=LightRAG -### separating all data from difference Lightrag instances(deprecating) -### separating all data from difference Lightrag instances -# MONGODB_WORKSPACE=default +# MONGODB_WORKSPACE=forced_workspace_name ### Milvus Configuration MILVUS_URI=http://localhost:19530 @@ -170,10 +170,13 @@ MILVUS_DB_NAME=lightrag # MILVUS_USER=root # MILVUS_PASSWORD=your_password # MILVUS_TOKEN=your_token +# MILVUS_WORKSPACE=forced_workspace_name ### Qdrant -QDRANT_URL=http://localhost:16333 +QDRANT_URL=http://localhost:6333 # QDRANT_API_KEY=your-api-key +# QDRANT_WORKSPACE=forced_workspace_name ### Redis REDIS_URI=redis://localhost:6379 +# REDIS_WORKSPACE=forced_workspace_name diff --git a/lightrag/api/__init__.py b/lightrag/api/__init__.py index 952266f6..5904b8a9 100644 --- a/lightrag/api/__init__.py +++ b/lightrag/api/__init__.py @@ -1 +1 @@ -__api_version__ = "0178" +__api_version__ = "0179" diff --git a/lightrag/api/config.py b/lightrag/api/config.py index 006ab452..2e15fd3a 100644 --- a/lightrag/api/config.py +++ b/lightrag/api/config.py @@ -184,10 +184,10 @@ def parse_args() -> argparse.Namespace: # Namespace parser.add_argument( - "--namespace-prefix", + "--workspace", type=str, - default=get_env_value("NAMESPACE_PREFIX", ""), - help="Prefix of the namespace", + default=get_env_value("WORKSPACE", ""), + help="Default workspace for all storage", ) parser.add_argument( diff --git a/lightrag/api/lightrag_server.py b/lightrag/api/lightrag_server.py index 0930c1cd..7a34ab5c 100644 --- a/lightrag/api/lightrag_server.py +++ b/lightrag/api/lightrag_server.py @@ -112,8 +112,8 @@ def create_app(args): # Check if API key is provided either through env var or args api_key = os.getenv("LIGHTRAG_API_KEY") or args.key - # Initialize document manager - doc_manager = DocumentManager(args.input_dir) + # Initialize document manager with workspace support for data isolation + doc_manager = DocumentManager(args.input_dir, workspace=args.workspace) @asynccontextmanager async def lifespan(app: FastAPI): @@ -295,6 +295,7 @@ def create_app(args): if args.llm_binding in ["lollms", "ollama", "openai"]: rag = LightRAG( working_dir=args.working_dir, + workspace=args.workspace, llm_model_func=lollms_model_complete if args.llm_binding == "lollms" else ollama_model_complete @@ -330,6 +331,7 @@ def create_app(args): else: # azure_openai rag = LightRAG( working_dir=args.working_dir, + workspace=args.workspace, llm_model_func=azure_openai_model_complete, chunk_token_size=int(args.chunk_size), chunk_overlap_token_size=int(args.chunk_overlap_size), @@ -472,6 +474,8 @@ def create_app(args): "vector_storage": args.vector_storage, "enable_llm_cache_for_extract": args.enable_llm_cache_for_extract, "enable_llm_cache": args.enable_llm_cache, + "workspace": args.workspace, + "max_graph_nodes": os.getenv("MAX_GRAPH_NODES"), }, "auth_mode": auth_mode, "pipeline_busy": pipeline_status.get("busy", False), diff --git a/lightrag/api/routers/document_routes.py b/lightrag/api/routers/document_routes.py index c25f7241..288a66e1 100644 --- a/lightrag/api/routers/document_routes.py +++ b/lightrag/api/routers/document_routes.py @@ -475,6 +475,7 @@ class DocumentManager: def __init__( self, input_dir: str, + workspace: str = "", # New parameter for workspace isolation supported_extensions: tuple = ( ".txt", ".md", @@ -515,10 +516,19 @@ class DocumentManager: ".less", # LESS CSS ), ): - self.input_dir = Path(input_dir) + # Store the base input directory and workspace + self.base_input_dir = Path(input_dir) + self.workspace = workspace self.supported_extensions = supported_extensions self.indexed_files = set() + # Create workspace-specific input directory + # If workspace is provided, create a subdirectory for data isolation + if workspace: + self.input_dir = self.base_input_dir / workspace + else: + self.input_dir = self.base_input_dir + # Create input directory if it doesn't exist self.input_dir.mkdir(parents=True, exist_ok=True) @@ -714,6 +724,12 @@ async def pipeline_enqueue_file(rag: LightRAG, file_path: Path) -> bool: # Insert into the RAG queue if content: + # Check if content contains only whitespace characters + if not content.strip(): + logger.warning( + f"File contains only whitespace characters. file_paths={file_path.name}" + ) + await rag.apipeline_enqueue_documents(content, file_paths=file_path.name) logger.info(f"Successfully fetched and enqueued file: {file_path.name}") return True diff --git a/lightrag/api/utils_api.py b/lightrag/api/utils_api.py index 13ec4ddd..e55e2a11 100644 --- a/lightrag/api/utils_api.py +++ b/lightrag/api/utils_api.py @@ -284,8 +284,10 @@ def display_splash_screen(args: argparse.Namespace) -> None: ASCIIColors.yellow(f"{args.vector_storage}") ASCIIColors.white(" ├─ Graph Storage: ", end="") ASCIIColors.yellow(f"{args.graph_storage}") - ASCIIColors.white(" └─ Document Status Storage: ", end="") + ASCIIColors.white(" ├─ Document Status Storage: ", end="") ASCIIColors.yellow(f"{args.doc_status_storage}") + ASCIIColors.white(" └─ Workspace: ", end="") + ASCIIColors.yellow(f"{args.workspace if args.workspace else '-'}") # Server Status ASCIIColors.green("\n✨ Server starting up...\n") diff --git a/lightrag/api/webui/assets/index-CRWiopRc.js b/lightrag/api/webui/assets/index-BlAjHenV.js similarity index 77% rename from lightrag/api/webui/assets/index-CRWiopRc.js rename to lightrag/api/webui/assets/index-BlAjHenV.js index f5e6b027..cee1a59c 100644 --- a/lightrag/api/webui/assets/index-CRWiopRc.js +++ b/lightrag/api/webui/assets/index-BlAjHenV.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 Jf}from"./react-vendor-DEwriMA6.js";import{z as Ve,c as Qe,a8 as od,u as Bl,y as Gt,a9 as rd,aa as fd,I as us,B as Cn,D as Mg,i as zg,j as Cg,k as Og,l as jg,ab as Rg,ac as Ug,ad as _g,ae as Hg,af as Ll,ag as dd,ah as ss,ai as is,W as Lg,Y as Bg,Z as qg,_ as Gg,aj as Yg,ak as Xg,al as md,am as Vg,an as Qg,ao as hd,ap as wg,aq as gd,C as Zg,J as Kg,K as Jg,d as En,ar as kg,as as Fg,at as $g}from"./feature-graph-yCDRht5b.js";import{S as kf,a as Ff,b as $f,c as Wf,d as ot,R as Wg}from"./feature-retrieval-DRE_iZah.js";import{D as Pg}from"./feature-documents-DYAipKCP.js";import{i as cs}from"./utils-vendor-BysuhMZA.js";import"./graph-vendor-B-X5JegA.js";import"./mermaid-vendor-DnUYjsdS.js";import"./markdown-vendor-DmIvJdn7.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{z as we,c as Ve,a8 as od,u as Bl,y as Gt,a9 as rd,aa as fd,I as us,B as Cn,D as Mg,i as zg,j as Cg,k as Og,l as jg,ab as Rg,ac as Ug,ad as _g,ae as Hg,af as Ll,ag as dd,ah as ss,ai as is,W as Lg,Y as Bg,Z as qg,_ as Gg,aj as Yg,ak as Xg,al as md,am as wg,an as Vg,ao as hd,ap as Qg,aq as gd,C as Zg,J as Kg,K as kg,d as En,ar as Jg,as as Fg,at as $g}from"./feature-graph-yCDRht5b.js";import{S as Jf,a as Ff,b as $f,c as Wf,d as ot,R as Wg}from"./feature-retrieval-DRE_iZah.js";import{D as Pg}from"./feature-documents-DYAipKCP.js";import{i as cs}from"./utils-vendor-BysuhMZA.js";import"./graph-vendor-B-X5JegA.js";import"./mermaid-vendor-DnUYjsdS.js";import"./markdown-vendor-DmIvJdn7.js";(function(){const v=document.createElement("link").relList;if(v&&v.supports&&v.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 * @@ -6,7 +6,7 @@ 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 * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var Pf;function Ig(){return Pf||(Pf=1,function(g){function b(A,L){var U=A.length;A.push(L);e:for(;0>>1,oe=A[te];if(0>>1;teN(vl,U))wN(we,vl)?(A[te]=we,A[w]=U,te=w):(A[te]=vl,A[pt]=U,te=pt);else if(wN(we,U))A[te]=we,A[w]=U,te=w;else break e}}return L}function N(A,L){var U=A.sortIndex-L.sortIndex;return U!==0?U:A.id-L.id}if(g.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var j=performance;g.unstable_now=function(){return j.now()}}else{var H=Date,$=H.now();g.unstable_now=function(){return H.now()-$}}var Y=[],W=[],he=1,ge=null,V=3,pe=!1,le=!1,C=!1,pl=typeof setTimeout=="function"?setTimeout:null,rt=typeof clearTimeout=="function"?clearTimeout:null,je=typeof setImmediate<"u"?setImmediate:null;function ft(A){for(var L=x(W);L!==null;){if(L.callback===null)d(W);else if(L.startTime<=A)d(W),L.sortIndex=L.expirationTime,b(Y,L);else break;L=x(W)}}function Ea(A){if(C=!1,ft(A),!le)if(x(Y)!==null)le=!0,ht();else{var L=x(W);L!==null&>(Ea,L.startTime-A)}}var dt=!1,al=-1,On=5,Yt=-1;function R(){return!(g.unstable_now()-YtA&&R());){var te=ge.callback;if(typeof te=="function"){ge.callback=null,V=ge.priorityLevel;var oe=te(ge.expirationTime<=A);if(A=g.unstable_now(),typeof oe=="function"){ge.callback=oe,ft(A),L=!0;break l}ge===x(Y)&&d(Y),ft(A)}else d(Y);ge=x(Y)}if(ge!==null)L=!0;else{var Xt=x(W);Xt!==null&>(Ea,Xt.startTime-A),L=!1}}break e}finally{ge=null,V=U,pe=!1}L=void 0}}finally{L?yl():dt=!1}}}var yl;if(typeof je=="function")yl=function(){je(J)};else if(typeof MessageChannel<"u"){var Ma=new MessageChannel,mt=Ma.port2;Ma.port1.onmessage=J,yl=function(){mt.postMessage(null)}}else yl=function(){pl(J,0)};function ht(){dt||(dt=!0,yl())}function gt(A,L){al=pl(function(){A(g.unstable_now())},L)}g.unstable_IdlePriority=5,g.unstable_ImmediatePriority=1,g.unstable_LowPriority=4,g.unstable_NormalPriority=3,g.unstable_Profiling=null,g.unstable_UserBlockingPriority=2,g.unstable_cancelCallback=function(A){A.callback=null},g.unstable_continueExecution=function(){le||pe||(le=!0,ht())},g.unstable_forceFrameRate=function(A){0>A||125te?(A.sortIndex=U,b(W,A),x(Y)===null&&A===x(W)&&(C?(rt(al),al=-1):C=!0,gt(Ea,U-te))):(A.sortIndex=oe,b(Y,A),le||pe||(le=!0,ht())),A},g.unstable_shouldYield=R,g.unstable_wrapCallback=function(A){var L=V;return function(){var U=V;V=L;try{return A.apply(this,arguments)}finally{V=U}}}}(ns)),ns}var If;function ep(){return If||(If=1,as.exports=Ig()),as.exports}/** + */var Pf;function Ig(){return Pf||(Pf=1,function(g){function v(A,L){var U=A.length;A.push(L);e:for(;0>>1,oe=A[te];if(0>>1;teN(vl,U))QN(Qe,vl)?(A[te]=Qe,A[Q]=U,te=Q):(A[te]=vl,A[pt]=U,te=pt);else if(QN(Qe,U))A[te]=Qe,A[Q]=U,te=Q;else break e}}return L}function N(A,L){var U=A.sortIndex-L.sortIndex;return U!==0?U:A.id-L.id}if(g.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var j=performance;g.unstable_now=function(){return j.now()}}else{var H=Date,$=H.now();g.unstable_now=function(){return H.now()-$}}var Y=[],W=[],he=1,ge=null,w=3,pe=!1,le=!1,C=!1,pl=typeof setTimeout=="function"?setTimeout:null,rt=typeof clearTimeout=="function"?clearTimeout:null,je=typeof setImmediate<"u"?setImmediate:null;function ft(A){for(var L=x(W);L!==null;){if(L.callback===null)d(W);else if(L.startTime<=A)d(W),L.sortIndex=L.expirationTime,v(Y,L);else break;L=x(W)}}function Ea(A){if(C=!1,ft(A),!le)if(x(Y)!==null)le=!0,ht();else{var L=x(W);L!==null&>(Ea,L.startTime-A)}}var dt=!1,al=-1,On=5,Yt=-1;function R(){return!(g.unstable_now()-YtA&&R());){var te=ge.callback;if(typeof te=="function"){ge.callback=null,w=ge.priorityLevel;var oe=te(ge.expirationTime<=A);if(A=g.unstable_now(),typeof oe=="function"){ge.callback=oe,ft(A),L=!0;break l}ge===x(Y)&&d(Y),ft(A)}else d(Y);ge=x(Y)}if(ge!==null)L=!0;else{var Xt=x(W);Xt!==null&>(Ea,Xt.startTime-A),L=!1}}break e}finally{ge=null,w=U,pe=!1}L=void 0}}finally{L?yl():dt=!1}}}var yl;if(typeof je=="function")yl=function(){je(k)};else if(typeof MessageChannel<"u"){var Ma=new MessageChannel,mt=Ma.port2;Ma.port1.onmessage=k,yl=function(){mt.postMessage(null)}}else yl=function(){pl(k,0)};function ht(){dt||(dt=!0,yl())}function gt(A,L){al=pl(function(){A(g.unstable_now())},L)}g.unstable_IdlePriority=5,g.unstable_ImmediatePriority=1,g.unstable_LowPriority=4,g.unstable_NormalPriority=3,g.unstable_Profiling=null,g.unstable_UserBlockingPriority=2,g.unstable_cancelCallback=function(A){A.callback=null},g.unstable_continueExecution=function(){le||pe||(le=!0,ht())},g.unstable_forceFrameRate=function(A){0>A||125te?(A.sortIndex=U,v(W,A),x(Y)===null&&A===x(W)&&(C?(rt(al),al=-1):C=!0,gt(Ea,U-te))):(A.sortIndex=oe,v(Y,A),le||pe||(le=!0,ht())),A},g.unstable_shouldYield=R,g.unstable_wrapCallback=function(A){var L=w;return function(){var U=w;w=L;try{return A.apply(this,arguments)}finally{w=U}}}}(ns)),ns}var If;function ep(){return If||(If=1,as.exports=Ig()),as.exports}/** * @license React * react-dom-client.production.js * @@ -14,21 +14,21 @@ 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 * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var ed;function lp(){if(ed)return Mn;ed=1;var g=ep(),b=Ag(),x=Dg();function d(e){var l="https://react.dev/errors/"+e;if(1)":-1n||s[a]!==f[n]){var v=` -`+s[a].replace(" at new "," at ");return e.displayName&&v.includes("")&&(v=v.replace("",e.displayName)),v}while(1<=a&&0<=n);break}}}finally{ht=!1,Error.prepareStackTrace=t}return(t=e?e.displayName||e.name:"")?mt(t):""}function A(e){switch(e.tag){case 26:case 27:case 5:return mt(e.type);case 16:return mt("Lazy");case 13:return mt("Suspense");case 19:return mt("SuspenseList");case 0:case 15:return e=gt(e.type,!1),e;case 11:return e=gt(e.type.render,!1),e;case 1:return e=gt(e.type,!0),e;default:return""}}function L(e){try{var l="";do l+=A(e),e=e.return;while(e);return l}catch(t){return` +`);for(n=a=0;an||s[a]!==f[n]){var b=` +`+s[a].replace(" at new "," at ");return e.displayName&&b.includes("")&&(b=b.replace("",e.displayName)),b}while(1<=a&&0<=n);break}}}finally{ht=!1,Error.prepareStackTrace=t}return(t=e?e.displayName||e.name:"")?mt(t):""}function A(e){switch(e.tag){case 26:case 27:case 5:return mt(e.type);case 16:return mt("Lazy");case 13:return mt("Suspense");case 19:return mt("SuspenseList");case 0:case 15:return e=gt(e.type,!1),e;case 11:return e=gt(e.type.render,!1),e;case 1:return e=gt(e.type,!0),e;default:return""}}function L(e){try{var l="";do l+=A(e),e=e.return;while(e);return l}catch(t){return` Error generating stack: `+t.message+` -`+t.stack}}function U(e){var l=e,t=e;if(e.alternate)for(;l.return;)l=l.return;else{e=l;do l=e,l.flags&4098&&(t=l.return),e=l.return;while(e)}return l.tag===3?t:null}function te(e){if(e.tag===13){var l=e.memoizedState;if(l===null&&(e=e.alternate,e!==null&&(l=e.memoizedState)),l!==null)return l.dehydrated}return null}function oe(e){if(U(e)!==e)throw Error(d(188))}function Xt(e){var l=e.alternate;if(!l){if(l=U(e),l===null)throw Error(d(188));return l!==e?null:e}for(var t=e,a=l;;){var n=t.return;if(n===null)break;var u=n.alternate;if(u===null){if(a=n.return,a!==null){t=a;continue}break}if(n.child===u.child){for(u=n.child;u;){if(u===t)return oe(n),e;if(u===a)return oe(n),l;u=u.sibling}throw Error(d(188))}if(t.return!==a.return)t=n,a=u;else{for(var i=!1,c=n.child;c;){if(c===t){i=!0,t=n,a=u;break}if(c===a){i=!0,a=n,t=u;break}c=c.sibling}if(!i){for(c=u.child;c;){if(c===t){i=!0,t=u,a=n;break}if(c===a){i=!0,a=u,t=n;break}c=c.sibling}if(!i)throw Error(d(189))}}if(t.alternate!==a)throw Error(d(190))}if(t.tag!==3)throw Error(d(188));return t.stateNode.current===t?e:l}function pt(e){var l=e.tag;if(l===5||l===26||l===27||l===6)return e;for(e=e.child;e!==null;){if(l=pt(e),l!==null)return l;e=e.sibling}return null}var vl=Array.isArray,w=x.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,we={pending:!1,data:null,method:null,action:null},Ku=[],Vt=-1;function sl(e){return{current:e}}function be(e){0>Vt||(e.current=Ku[Vt],Ku[Vt]=null,Vt--)}function ae(e,l){Vt++,Ku[Vt]=e.current,e.current=l}var ol=sl(null),za=sl(null),Gl=sl(null),jn=sl(null);function Rn(e,l){switch(ae(Gl,l),ae(za,e),ae(ol,null),e=l.nodeType,e){case 9:case 11:l=(l=l.documentElement)&&(l=l.namespaceURI)?xf(l):0;break;default:if(e=e===8?l.parentNode:l,l=e.tagName,e=e.namespaceURI)e=xf(e),l=Af(e,l);else switch(l){case"svg":l=1;break;case"math":l=2;break;default:l=0}}be(ol),ae(ol,l)}function Qt(){be(ol),be(za),be(Gl)}function Ju(e){e.memoizedState!==null&&ae(jn,e);var l=ol.current,t=Af(l,e.type);l!==t&&(ae(za,e),ae(ol,t))}function Un(e){za.current===e&&(be(ol),be(za)),jn.current===e&&(be(jn),Tn._currentValue=we)}var ku=Object.prototype.hasOwnProperty,Fu=g.unstable_scheduleCallback,$u=g.unstable_cancelCallback,Qd=g.unstable_shouldYield,wd=g.unstable_requestPaint,rl=g.unstable_now,Zd=g.unstable_getCurrentPriorityLevel,os=g.unstable_ImmediatePriority,rs=g.unstable_UserBlockingPriority,_n=g.unstable_NormalPriority,Kd=g.unstable_LowPriority,fs=g.unstable_IdlePriority,Jd=g.log,kd=g.unstable_setDisableYieldValue,Ca=null,He=null;function Fd(e){if(He&&typeof He.onCommitFiberRoot=="function")try{He.onCommitFiberRoot(Ca,e,void 0,(e.current.flags&128)===128)}catch{}}function Yl(e){if(typeof Jd=="function"&&kd(e),He&&typeof He.setStrictMode=="function")try{He.setStrictMode(Ca,e)}catch{}}var Le=Math.clz32?Math.clz32:Pd,$d=Math.log,Wd=Math.LN2;function Pd(e){return e>>>=0,e===0?32:31-($d(e)/Wd|0)|0}var Hn=128,Ln=4194304;function yt(e){var l=e&42;if(l!==0)return l;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194176;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function Bn(e,l){var t=e.pendingLanes;if(t===0)return 0;var a=0,n=e.suspendedLanes,u=e.pingedLanes,i=e.warmLanes;e=e.finishedLanes!==0;var c=t&134217727;return c!==0?(t=c&~n,t!==0?a=yt(t):(u&=c,u!==0?a=yt(u):e||(i=c&~i,i!==0&&(a=yt(i))))):(c=t&~n,c!==0?a=yt(c):u!==0?a=yt(u):e||(i=t&~i,i!==0&&(a=yt(i)))),a===0?0:l!==0&&l!==a&&!(l&n)&&(n=a&-a,i=l&-l,n>=i||n===32&&(i&4194176)!==0)?l:a}function Oa(e,l){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&l)===0}function Id(e,l){switch(e){case 1:case 2:case 4:case 8:return l+250;case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return l+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function ds(){var e=Hn;return Hn<<=1,!(Hn&4194176)&&(Hn=128),e}function ms(){var e=Ln;return Ln<<=1,!(Ln&62914560)&&(Ln=4194304),e}function Wu(e){for(var l=[],t=0;31>t;t++)l.push(e);return l}function ja(e,l){e.pendingLanes|=l,l!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function em(e,l,t,a,n,u){var i=e.pendingLanes;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=t,e.entangledLanes&=t,e.errorRecoveryDisabledLanes&=t,e.shellSuspendCounter=0;var c=e.entanglements,s=e.expirationTimes,f=e.hiddenUpdates;for(t=i&~t;0"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),nm=RegExp("^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$"),Ts={},xs={};function um(e){return ku.call(xs,e)?!0:ku.call(Ts,e)?!1:nm.test(e)?xs[e]=!0:(Ts[e]=!0,!1)}function qn(e,l,t){if(um(l))if(t===null)e.removeAttribute(l);else{switch(typeof t){case"undefined":case"function":case"symbol":e.removeAttribute(l);return;case"boolean":var a=l.toLowerCase().slice(0,5);if(a!=="data-"&&a!=="aria-"){e.removeAttribute(l);return}}e.setAttribute(l,""+t)}}function Gn(e,l,t){if(t===null)e.removeAttribute(l);else{switch(typeof t){case"undefined":case"function":case"symbol":case"boolean":e.removeAttribute(l);return}e.setAttribute(l,""+t)}}function Sl(e,l,t,a){if(a===null)e.removeAttribute(t);else{switch(typeof a){case"undefined":case"function":case"symbol":case"boolean":e.removeAttribute(t);return}e.setAttributeNS(l,t,""+a)}}function Ze(e){switch(typeof e){case"bigint":case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function As(e){var l=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(l==="checkbox"||l==="radio")}function im(e){var l=As(e)?"checked":"value",t=Object.getOwnPropertyDescriptor(e.constructor.prototype,l),a=""+e[l];if(!e.hasOwnProperty(l)&&typeof t<"u"&&typeof t.get=="function"&&typeof t.set=="function"){var n=t.get,u=t.set;return Object.defineProperty(e,l,{configurable:!0,get:function(){return n.call(this)},set:function(i){a=""+i,u.call(this,i)}}),Object.defineProperty(e,l,{enumerable:t.enumerable}),{getValue:function(){return a},setValue:function(i){a=""+i},stopTracking:function(){e._valueTracker=null,delete e[l]}}}}function Yn(e){e._valueTracker||(e._valueTracker=im(e))}function Ds(e){if(!e)return!1;var l=e._valueTracker;if(!l)return!0;var t=l.getValue(),a="";return e&&(a=As(e)?e.checked?"true":"false":e.value),e=a,e!==t?(l.setValue(e),!0):!1}function Xn(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}var cm=/[\n"\\]/g;function Ke(e){return e.replace(cm,function(l){return"\\"+l.charCodeAt(0).toString(16)+" "})}function ei(e,l,t,a,n,u,i,c){e.name="",i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"?e.type=i:e.removeAttribute("type"),l!=null?i==="number"?(l===0&&e.value===""||e.value!=l)&&(e.value=""+Ze(l)):e.value!==""+Ze(l)&&(e.value=""+Ze(l)):i!=="submit"&&i!=="reset"||e.removeAttribute("value"),l!=null?li(e,i,Ze(l)):t!=null?li(e,i,Ze(t)):a!=null&&e.removeAttribute("value"),n==null&&u!=null&&(e.defaultChecked=!!u),n!=null&&(e.checked=n&&typeof n!="function"&&typeof n!="symbol"),c!=null&&typeof c!="function"&&typeof c!="symbol"&&typeof c!="boolean"?e.name=""+Ze(c):e.removeAttribute("name")}function Ns(e,l,t,a,n,u,i,c){if(u!=null&&typeof u!="function"&&typeof u!="symbol"&&typeof u!="boolean"&&(e.type=u),l!=null||t!=null){if(!(u!=="submit"&&u!=="reset"||l!=null))return;t=t!=null?""+Ze(t):"",l=l!=null?""+Ze(l):t,c||l===e.value||(e.value=l),e.defaultValue=l}a=a??n,a=typeof a!="function"&&typeof a!="symbol"&&!!a,e.checked=c?e.checked:!!a,e.defaultChecked=!!a,i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"&&(e.name=i)}function li(e,l,t){l==="number"&&Xn(e.ownerDocument)===e||e.defaultValue===""+t||(e.defaultValue=""+t)}function kt(e,l,t,a){if(e=e.options,l){l={};for(var n=0;n=qa),qs=" ",Gs=!1;function Ys(e,l){switch(e){case"keyup":return Hm.indexOf(l.keyCode)!==-1;case"keydown":return l.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Xs(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Pt=!1;function Bm(e,l){switch(e){case"compositionend":return Xs(l);case"keypress":return l.which!==32?null:(Gs=!0,qs);case"textInput":return e=l.data,e===qs&&Gs?null:e;default:return null}}function qm(e,l){if(Pt)return e==="compositionend"||!di&&Ys(e,l)?(e=Rs(),Qn=ci=Vl=null,Pt=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(l.ctrlKey||l.altKey||l.metaKey)||l.ctrlKey&&l.altKey){if(l.char&&1=l)return{node:t,offset:l-e};e=a}e:{for(;t;){if(t.nextSibling){t=t.nextSibling;break e}t=t.parentNode}t=void 0}t=Fs(t)}}function Ws(e,l){return e&&l?e===l?!0:e&&e.nodeType===3?!1:l&&l.nodeType===3?Ws(e,l.parentNode):"contains"in e?e.contains(l):e.compareDocumentPosition?!!(e.compareDocumentPosition(l)&16):!1:!1}function Ps(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var l=Xn(e.document);l instanceof e.HTMLIFrameElement;){try{var t=typeof l.contentWindow.location.href=="string"}catch{t=!1}if(t)e=l.contentWindow;else break;l=Xn(e.document)}return l}function gi(e){var l=e&&e.nodeName&&e.nodeName.toLowerCase();return l&&(l==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||l==="textarea"||e.contentEditable==="true")}function Km(e,l){var t=Ps(l);l=e.focusedElem;var a=e.selectionRange;if(t!==l&&l&&l.ownerDocument&&Ws(l.ownerDocument.documentElement,l)){if(a!==null&&gi(l)){if(e=a.start,t=a.end,t===void 0&&(t=e),"selectionStart"in l)l.selectionStart=e,l.selectionEnd=Math.min(t,l.value.length);else if(t=(e=l.ownerDocument||document)&&e.defaultView||window,t.getSelection){t=t.getSelection();var n=l.textContent.length,u=Math.min(a.start,n);a=a.end===void 0?u:Math.min(a.end,n),!t.extend&&u>a&&(n=a,a=u,u=n),n=$s(l,u);var i=$s(l,a);n&&i&&(t.rangeCount!==1||t.anchorNode!==n.node||t.anchorOffset!==n.offset||t.focusNode!==i.node||t.focusOffset!==i.offset)&&(e=e.createRange(),e.setStart(n.node,n.offset),t.removeAllRanges(),u>a?(t.addRange(e),t.extend(i.node,i.offset)):(e.setEnd(i.node,i.offset),t.addRange(e)))}}for(e=[],t=l;t=t.parentNode;)t.nodeType===1&&e.push({element:t,left:t.scrollLeft,top:t.scrollTop});for(typeof l.focus=="function"&&l.focus(),l=0;l=document.documentMode,It=null,pi=null,Va=null,yi=!1;function Is(e,l,t){var a=t.window===t?t.document:t.nodeType===9?t:t.ownerDocument;yi||It==null||It!==Xn(a)||(a=It,"selectionStart"in a&&gi(a)?a={start:a.selectionStart,end:a.selectionEnd}:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection(),a={anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset}),Va&&Xa(Va,a)||(Va=a,a=Ou(pi,"onSelect"),0>=i,n-=i,Tl=1<<32-Le(l)+n|t<O?(Ae=z,z=null):Ae=z.sibling;var K=p(m,z,h[O],S);if(K===null){z===null&&(z=Ae);break}e&&z&&K.alternate===null&&l(m,z),r=u(K,r,O),q===null?D=K:q.sibling=K,q=K,z=Ae}if(O===h.length)return t(m,z),Z&&Dt(m,O),D;if(z===null){for(;OO?(Ae=z,z=null):Ae=z.sibling;var st=p(m,z,K.value,S);if(st===null){z===null&&(z=Ae);break}e&&z&&st.alternate===null&&l(m,z),r=u(st,r,O),q===null?D=st:q.sibling=st,q=st,z=Ae}if(K.done)return t(m,z),Z&&Dt(m,O),D;if(z===null){for(;!K.done;O++,K=h.next())K=T(m,K.value,S),K!==null&&(r=u(K,r,O),q===null?D=K:q.sibling=K,q=K);return Z&&Dt(m,O),D}for(z=a(z);!K.done;O++,K=h.next())K=y(z,m,O,K.value,S),K!==null&&(e&&K.alternate!==null&&z.delete(K.key===null?O:K.key),r=u(K,r,O),q===null?D=K:q.sibling=K,q=K);return e&&z.forEach(function(rg){return l(m,rg)}),Z&&Dt(m,O),D}function se(m,r,h,S){if(typeof h=="object"&&h!==null&&h.type===Y&&h.key===null&&(h=h.props.children),typeof h=="object"&&h!==null){switch(h.$$typeof){case H:e:{for(var D=h.key;r!==null;){if(r.key===D){if(D=h.type,D===Y){if(r.tag===7){t(m,r.sibling),S=n(r,h.props.children),S.return=m,m=S;break e}}else if(r.elementType===D||typeof D=="object"&&D!==null&&D.$$typeof===je&&yo(D)===r.type){t(m,r.sibling),S=n(r,h.props),Fa(S,h),S.return=m,m=S;break e}t(m,r);break}else l(m,r);r=r.sibling}h.type===Y?(S=Ht(h.props.children,m.mode,S,h.key),S.return=m,m=S):(S=Su(h.type,h.key,h.props,null,m.mode,S),Fa(S,h),S.return=m,m=S)}return i(m);case $:e:{for(D=h.key;r!==null;){if(r.key===D)if(r.tag===4&&r.stateNode.containerInfo===h.containerInfo&&r.stateNode.implementation===h.implementation){t(m,r.sibling),S=n(r,h.children||[]),S.return=m,m=S;break e}else{t(m,r);break}else l(m,r);r=r.sibling}S=bc(h,m.mode,S),S.return=m,m=S}return i(m);case je:return D=h._init,h=D(h._payload),se(m,r,h,S)}if(vl(h))return M(m,r,h,S);if(al(h)){if(D=al(h),typeof D!="function")throw Error(d(150));return h=D.call(h),_(m,r,h,S)}if(typeof h.then=="function")return se(m,r,lu(h),S);if(h.$$typeof===pe)return se(m,r,yu(m,h),S);tu(m,h)}return typeof h=="string"&&h!==""||typeof h=="number"||typeof h=="bigint"?(h=""+h,r!==null&&r.tag===6?(t(m,r.sibling),S=n(r,h),S.return=m,m=S):(t(m,r),S=vc(h,m.mode,S),S.return=m,m=S),i(m)):t(m,r)}return function(m,r,h,S){try{ka=0;var D=se(m,r,h,S);return ua=null,D}catch(z){if(z===Ka)throw z;var q=el(29,z,null,m.mode);return q.lanes=S,q.return=m,q}finally{}}}var Et=vo(!0),bo=vo(!1),ia=sl(null),au=sl(0);function So(e,l){e=Ul,ae(au,e),ae(ia,l),Ul=e|l.baseLanes}function Ni(){ae(au,Ul),ae(ia,ia.current)}function Ei(){Ul=au.current,be(ia),be(au)}var We=sl(null),dl=null;function wl(e){var l=e.alternate;ae(ye,ye.current&1),ae(We,e),dl===null&&(l===null||ia.current!==null||l.memoizedState!==null)&&(dl=e)}function To(e){if(e.tag===22){if(ae(ye,ye.current),ae(We,e),dl===null){var l=e.alternate;l!==null&&l.memoizedState!==null&&(dl=e)}}else Zl()}function Zl(){ae(ye,ye.current),ae(We,We.current)}function Al(e){be(We),dl===e&&(dl=null),be(ye)}var ye=sl(0);function nu(e){for(var l=e;l!==null;){if(l.tag===13){var t=l.memoizedState;if(t!==null&&(t=t.dehydrated,t===null||t.data==="$?"||t.data==="$!"))return l}else if(l.tag===19&&l.memoizedProps.revealOrder!==void 0){if(l.flags&128)return l}else if(l.child!==null){l.child.return=l,l=l.child;continue}if(l===e)break;for(;l.sibling===null;){if(l.return===null||l.return===e)return null;l=l.return}l.sibling.return=l.return,l=l.sibling}return null}var Wm=typeof AbortController<"u"?AbortController:function(){var e=[],l=this.signal={aborted:!1,addEventListener:function(t,a){e.push(a)}};this.abort=function(){l.aborted=!0,e.forEach(function(t){return t()})}},Pm=g.unstable_scheduleCallback,Im=g.unstable_NormalPriority,ve={$$typeof:pe,Consumer:null,Provider:null,_currentValue:null,_currentValue2:null,_threadCount:0};function Mi(){return{controller:new Wm,data:new Map,refCount:0}}function $a(e){e.refCount--,e.refCount===0&&Pm(Im,function(){e.controller.abort()})}var Wa=null,zi=0,ca=0,sa=null;function eh(e,l){if(Wa===null){var t=Wa=[];zi=0,ca=_c(),sa={status:"pending",value:void 0,then:function(a){t.push(a)}}}return zi++,l.then(xo,xo),l}function xo(){if(--zi===0&&Wa!==null){sa!==null&&(sa.status="fulfilled");var e=Wa;Wa=null,ca=0,sa=null;for(var l=0;lu?u:8;var i=R.T,c={};R.T=c,Zi(e,!1,l,t);try{var s=n(),f=R.S;if(f!==null&&f(c,s),s!==null&&typeof s=="object"&&typeof s.then=="function"){var v=lh(s,a);en(e,l,v,Xe(e))}else en(e,l,a,Xe(e))}catch(T){en(e,l,{then:function(){},status:"rejected",reason:T},Xe())}finally{w.p=u,R.T=i}}function ih(){}function Qi(e,l,t,a){if(e.tag!==5)throw Error(d(476));var n=Io(e).queue;Po(e,n,l,we,t===null?ih:function(){return er(e),t(a)})}function Io(e){var l=e.memoizedState;if(l!==null)return l;l={memoizedState:we,baseState:we,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Dl,lastRenderedState:we},next:null};var t={};return l.next={memoizedState:t,baseState:t,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Dl,lastRenderedState:t},next:null},e.memoizedState=l,e=e.alternate,e!==null&&(e.memoizedState=l),l}function er(e){var l=Io(e).next.queue;en(e,l,{},Xe())}function wi(){return ze(Tn)}function lr(){return de().memoizedState}function tr(){return de().memoizedState}function ch(e){for(var l=e.return;l!==null;){switch(l.tag){case 24:case 3:var t=Xe();e=$l(t);var a=Wl(l,e,t);a!==null&&(Oe(a,l,t),an(a,l,t)),l={cache:Mi()},e.payload=l;return}l=l.return}}function sh(e,l,t){var a=Xe();t={lane:a,revertLane:0,action:t,hasEagerState:!1,eagerState:null,next:null},mu(e)?nr(l,t):(t=Si(e,l,t,a),t!==null&&(Oe(t,e,a),ur(t,l,a)))}function ar(e,l,t){var a=Xe();en(e,l,t,a)}function en(e,l,t,a){var n={lane:a,revertLane:0,action:t,hasEagerState:!1,eagerState:null,next:null};if(mu(e))nr(l,n);else{var u=e.alternate;if(e.lanes===0&&(u===null||u.lanes===0)&&(u=l.lastRenderedReducer,u!==null))try{var i=l.lastRenderedState,c=u(i,t);if(n.hasEagerState=!0,n.eagerState=c,Be(c,i))return $n(e,l,n,0),I===null&&Fn(),!1}catch{}finally{}if(t=Si(e,l,n,a),t!==null)return Oe(t,e,a),ur(t,l,a),!0}return!1}function Zi(e,l,t,a){if(a={lane:2,revertLane:_c(),action:a,hasEagerState:!1,eagerState:null,next:null},mu(e)){if(l)throw Error(d(479))}else l=Si(e,t,a,2),l!==null&&Oe(l,e,2)}function mu(e){var l=e.alternate;return e===B||l!==null&&l===B}function nr(e,l){oa=iu=!0;var t=e.pending;t===null?l.next=l:(l.next=t.next,t.next=l),e.pending=l}function ur(e,l,t){if(t&4194176){var a=l.lanes;a&=e.pendingLanes,t|=a,l.lanes=t,gs(e,t)}}var ml={readContext:ze,use:ou,useCallback:re,useContext:re,useEffect:re,useImperativeHandle:re,useLayoutEffect:re,useInsertionEffect:re,useMemo:re,useReducer:re,useRef:re,useState:re,useDebugValue:re,useDeferredValue:re,useTransition:re,useSyncExternalStore:re,useId:re};ml.useCacheRefresh=re,ml.useMemoCache=re,ml.useHostTransitionStatus=re,ml.useFormState=re,ml.useActionState=re,ml.useOptimistic=re;var Ct={readContext:ze,use:ou,useCallback:function(e,l){return _e().memoizedState=[e,l===void 0?null:l],e},useContext:ze,useEffect:wo,useImperativeHandle:function(e,l,t){t=t!=null?t.concat([e]):null,fu(4194308,4,Jo.bind(null,l,e),t)},useLayoutEffect:function(e,l){return fu(4194308,4,e,l)},useInsertionEffect:function(e,l){fu(4,2,e,l)},useMemo:function(e,l){var t=_e();l=l===void 0?null:l;var a=e();if(zt){Yl(!0);try{e()}finally{Yl(!1)}}return t.memoizedState=[a,l],a},useReducer:function(e,l,t){var a=_e();if(t!==void 0){var n=t(l);if(zt){Yl(!0);try{t(l)}finally{Yl(!1)}}}else n=l;return a.memoizedState=a.baseState=n,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:n},a.queue=e,e=e.dispatch=sh.bind(null,B,e),[a.memoizedState,e]},useRef:function(e){var l=_e();return e={current:e},l.memoizedState=e},useState:function(e){e=qi(e);var l=e.queue,t=ar.bind(null,B,l);return l.dispatch=t,[e.memoizedState,t]},useDebugValue:Xi,useDeferredValue:function(e,l){var t=_e();return Vi(t,e,l)},useTransition:function(){var e=qi(!1);return e=Po.bind(null,B,e.queue,!0,!1),_e().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,l,t){var a=B,n=_e();if(Z){if(t===void 0)throw Error(d(407));t=t()}else{if(t=l(),I===null)throw Error(d(349));Q&60||zo(a,l,t)}n.memoizedState=t;var u={value:t,getSnapshot:l};return n.queue=u,wo(Oo.bind(null,a,u,e),[e]),a.flags|=2048,fa(9,Co.bind(null,a,u,t,l),{destroy:void 0},null),t},useId:function(){var e=_e(),l=I.identifierPrefix;if(Z){var t=xl,a=Tl;t=(a&~(1<<32-Le(a)-1)).toString(32)+t,l=":"+l+"R"+t,t=cu++,0 title"))),Ee(u,a,t),u[Me]=e,Se(u),a=u;break e;case"link":var i=Uf("link","href",n).get(a+(t.href||""));if(i){for(var c=0;c<\/script>",e=e.removeChild(e.firstChild);break;case"select":e=typeof a.is=="string"?n.createElement("select",{is:a.is}):n.createElement("select"),a.multiple?e.multiple=!0:a.size&&(e.size=a.size);break;default:e=typeof a.is=="string"?n.createElement(t,{is:a.is}):n.createElement(t)}}e[Me]=l,e[Re]=a;e:for(n=l.child;n!==null;){if(n.tag===5||n.tag===6)e.appendChild(n.stateNode);else if(n.tag!==4&&n.tag!==27&&n.child!==null){n.child.return=n,n=n.child;continue}if(n===l)break e;for(;n.sibling===null;){if(n.return===null||n.return===l)break e;n=n.return}n.sibling.return=n.return,n=n.sibling}l.stateNode=e;e:switch(Ee(e,t,a),t){case"button":case"input":case"select":case"textarea":e=!!a.autoFocus;break e;case"img":e=!0;break e;default:e=!1}e&&jl(l)}}return ne(l),l.flags&=-16777217,null;case 6:if(e&&l.stateNode!=null)e.memoizedProps!==a&&jl(l);else{if(typeof a!="string"&&l.stateNode===null)throw Error(d(166));if(e=Gl.current,Qa(l)){if(e=l.stateNode,t=l.memoizedProps,a=null,n=Ce,n!==null)switch(n.tag){case 27:case 5:a=n.memoizedProps}e[Me]=l,e=!!(e.nodeValue===t||a!==null&&a.suppressHydrationWarning===!0||Tf(e.nodeValue,t)),e||Nt(l)}else e=Ru(e).createTextNode(a),e[Me]=l,l.stateNode=e}return ne(l),null;case 13:if(a=l.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(n=Qa(l),a!==null&&a.dehydrated!==null){if(e===null){if(!n)throw Error(d(318));if(n=l.memoizedState,n=n!==null?n.dehydrated:null,!n)throw Error(d(317));n[Me]=l}else wa(),!(l.flags&128)&&(l.memoizedState=null),l.flags|=4;ne(l),n=!1}else ul!==null&&(Mc(ul),ul=null),n=!0;if(!n)return l.flags&256?(Al(l),l):(Al(l),null)}if(Al(l),l.flags&128)return l.lanes=t,l;if(t=a!==null,e=e!==null&&e.memoizedState!==null,t){a=l.child,n=null,a.alternate!==null&&a.alternate.memoizedState!==null&&a.alternate.memoizedState.cachePool!==null&&(n=a.alternate.memoizedState.cachePool.pool);var u=null;a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(u=a.memoizedState.cachePool.pool),u!==n&&(a.flags|=2048)}return t!==e&&t&&(l.child.flags|=8192),Tu(l,l.updateQueue),ne(l),null;case 4:return Qt(),e===null&&qc(l.stateNode.containerInfo),ne(l),null;case 10:return Ml(l.type),ne(l),null;case 19:if(be(ye),n=l.memoizedState,n===null)return ne(l),null;if(a=(l.flags&128)!==0,u=n.rendering,u===null)if(a)fn(n,!1);else{if(ce!==0||e!==null&&e.flags&128)for(e=l.child;e!==null;){if(u=nu(e),u!==null){for(l.flags|=128,fn(n,!1),e=u.updateQueue,l.updateQueue=e,Tu(l,e),l.subtreeFlags=0,e=t,t=l.child;t!==null;)kr(t,e),t=t.sibling;return ae(ye,ye.current&1|2),l.child}e=e.sibling}n.tail!==null&&rl()>xu&&(l.flags|=128,a=!0,fn(n,!1),l.lanes=4194304)}else{if(!a)if(e=nu(u),e!==null){if(l.flags|=128,a=!0,e=e.updateQueue,l.updateQueue=e,Tu(l,e),fn(n,!0),n.tail===null&&n.tailMode==="hidden"&&!u.alternate&&!Z)return ne(l),null}else 2*rl()-n.renderingStartTime>xu&&t!==536870912&&(l.flags|=128,a=!0,fn(n,!1),l.lanes=4194304);n.isBackwards?(u.sibling=l.child,l.child=u):(e=n.last,e!==null?e.sibling=u:l.child=u,n.last=u)}return n.tail!==null?(l=n.tail,n.rendering=l,n.tail=l.sibling,n.renderingStartTime=rl(),l.sibling=null,e=ye.current,ae(ye,a?e&1|2:e&1),l):(ne(l),null);case 22:case 23:return Al(l),Ei(),a=l.memoizedState!==null,e!==null?e.memoizedState!==null!==a&&(l.flags|=8192):a&&(l.flags|=8192),a?t&536870912&&!(l.flags&128)&&(ne(l),l.subtreeFlags&6&&(l.flags|=8192)):ne(l),t=l.updateQueue,t!==null&&Tu(l,t.retryQueue),t=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(t=e.memoizedState.cachePool.pool),a=null,l.memoizedState!==null&&l.memoizedState.cachePool!==null&&(a=l.memoizedState.cachePool.pool),a!==t&&(l.flags|=2048),e!==null&&be(Mt),null;case 24:return t=null,e!==null&&(t=e.memoizedState.cache),l.memoizedState.cache!==t&&(l.flags|=2048),Ml(ve),ne(l),null;case 25:return null}throw Error(d(156,l.tag))}function gh(e,l){switch(xi(l),l.tag){case 1:return e=l.flags,e&65536?(l.flags=e&-65537|128,l):null;case 3:return Ml(ve),Qt(),e=l.flags,e&65536&&!(e&128)?(l.flags=e&-65537|128,l):null;case 26:case 27:case 5:return Un(l),null;case 13:if(Al(l),e=l.memoizedState,e!==null&&e.dehydrated!==null){if(l.alternate===null)throw Error(d(340));wa()}return e=l.flags,e&65536?(l.flags=e&-65537|128,l):null;case 19:return be(ye),null;case 4:return Qt(),null;case 10:return Ml(l.type),null;case 22:case 23:return Al(l),Ei(),e!==null&&be(Mt),e=l.flags,e&65536?(l.flags=e&-65537|128,l):null;case 24:return Ml(ve),null;case 25:return null;default:return null}}function Wr(e,l){switch(xi(l),l.tag){case 3:Ml(ve),Qt();break;case 26:case 27:case 5:Un(l);break;case 4:Qt();break;case 13:Al(l);break;case 19:be(ye);break;case 10:Ml(l.type);break;case 22:case 23:Al(l),Ei(),e!==null&&be(Mt);break;case 24:Ml(ve)}}var ph={getCacheForType:function(e){var l=ze(ve),t=l.data.get(e);return t===void 0&&(t=e(),l.data.set(e,t)),t}},yh=typeof WeakMap=="function"?WeakMap:Map,ue=0,I=null,G=null,Q=0,ee=0,Ye=null,Rl=!1,ga=!1,Sc=!1,Ul=0,ce=0,tt=0,Lt=0,Tc=0,ll=0,pa=0,dn=null,hl=null,xc=!1,Ac=0,xu=1/0,Au=null,at=null,Du=!1,Bt=null,mn=0,Dc=0,Nc=null,hn=0,Ec=null;function Xe(){if(ue&2&&Q!==0)return Q&-Q;if(R.T!==null){var e=ca;return e!==0?e:_c()}return ys()}function Pr(){ll===0&&(ll=!(Q&536870912)||Z?ds():536870912);var e=We.current;return e!==null&&(e.flags|=32),ll}function Oe(e,l,t){(e===I&&ee===2||e.cancelPendingCommit!==null)&&(ya(e,0),_l(e,Q,ll,!1)),ja(e,t),(!(ue&2)||e!==I)&&(e===I&&(!(ue&2)&&(Lt|=t),ce===4&&_l(e,Q,ll,!1)),gl(e))}function Ir(e,l,t){if(ue&6)throw Error(d(327));var a=!t&&(l&60)===0&&(l&e.expiredLanes)===0||Oa(e,l),n=a?Sh(e,l):Oc(e,l,!0),u=a;do{if(n===0){ga&&!a&&_l(e,l,0,!1);break}else if(n===6)_l(e,l,0,!Rl);else{if(t=e.current.alternate,u&&!vh(t)){n=Oc(e,l,!1),u=!1;continue}if(n===2){if(u=l,e.errorRecoveryDisabledLanes&u)var i=0;else i=e.pendingLanes&-536870913,i=i!==0?i:i&536870912?536870912:0;if(i!==0){l=i;e:{var c=e;n=dn;var s=c.current.memoizedState.isDehydrated;if(s&&(ya(c,i).flags|=256),i=Oc(c,i,!1),i!==2){if(Sc&&!s){c.errorRecoveryDisabledLanes|=u,Lt|=u,n=4;break e}u=hl,hl=n,u!==null&&Mc(u)}n=i}if(u=!1,n!==2)continue}}if(n===1){ya(e,0),_l(e,l,0,!0);break}e:{switch(a=e,n){case 0:case 1:throw Error(d(345));case 4:if((l&4194176)===l){_l(a,l,ll,!Rl);break e}break;case 2:hl=null;break;case 3:case 5:break;default:throw Error(d(329))}if(a.finishedWork=t,a.finishedLanes=l,(l&62914560)===l&&(u=Ac+300-rl(),10t?32:t,R.T=null,Bt===null)var u=!1;else{t=Nc,Nc=null;var i=Bt,c=mn;if(Bt=null,mn=0,ue&6)throw Error(d(331));var s=ue;if(ue|=4,Kr(i.current),Qr(i,i.current,c,t),ue=s,gn(0,!1),He&&typeof He.onPostCommitFiberRoot=="function")try{He.onPostCommitFiberRoot(Ca,i)}catch{}u=!0}return u}finally{w.p=n,R.T=a,of(e,l)}}return!1}function rf(e,l,t){l=ke(t,l),l=ki(e.stateNode,l,2),e=Wl(e,l,2),e!==null&&(ja(e,2),gl(e))}function P(e,l,t){if(e.tag===3)rf(e,e,t);else for(;l!==null;){if(l.tag===3){rf(l,e,t);break}else if(l.tag===1){var a=l.stateNode;if(typeof l.type.getDerivedStateFromError=="function"||typeof a.componentDidCatch=="function"&&(at===null||!at.has(a))){e=ke(t,e),t=dr(2),a=Wl(l,t,2),a!==null&&(mr(t,a,l,e),ja(a,2),gl(a));break}}l=l.return}}function jc(e,l,t){var a=e.pingCache;if(a===null){a=e.pingCache=new yh;var n=new Set;a.set(l,n)}else n=a.get(l),n===void 0&&(n=new Set,a.set(l,n));n.has(t)||(Sc=!0,n.add(t),e=Ah.bind(null,e,l,t),l.then(e,e))}function Ah(e,l,t){var a=e.pingCache;a!==null&&a.delete(l),e.pingedLanes|=e.suspendedLanes&t,e.warmLanes&=~t,I===e&&(Q&t)===t&&(ce===4||ce===3&&(Q&62914560)===Q&&300>rl()-Ac?!(ue&2)&&ya(e,0):Tc|=t,pa===Q&&(pa=0)),gl(e)}function ff(e,l){l===0&&(l=ms()),e=Ql(e,l),e!==null&&(ja(e,l),gl(e))}function Dh(e){var l=e.memoizedState,t=0;l!==null&&(t=l.retryLane),ff(e,t)}function Nh(e,l){var t=0;switch(e.tag){case 13:var a=e.stateNode,n=e.memoizedState;n!==null&&(t=n.retryLane);break;case 19:a=e.stateNode;break;case 22:a=e.stateNode._retryCache;break;default:throw Error(d(314))}a!==null&&a.delete(l),ff(e,t)}function Eh(e,l){return Fu(e,l)}var Mu=null,Sa=null,Rc=!1,zu=!1,Uc=!1,qt=0;function gl(e){e!==Sa&&e.next===null&&(Sa===null?Mu=Sa=e:Sa=Sa.next=e),zu=!0,Rc||(Rc=!0,zh(Mh))}function gn(e,l){if(!Uc&&zu){Uc=!0;do for(var t=!1,a=Mu;a!==null;){if(e!==0){var n=a.pendingLanes;if(n===0)var u=0;else{var i=a.suspendedLanes,c=a.pingedLanes;u=(1<<31-Le(42|e)+1)-1,u&=n&~(i&~c),u=u&201326677?u&201326677|1:u?u|2:0}u!==0&&(t=!0,hf(a,u))}else u=Q,u=Bn(a,a===I?u:0),!(u&3)||Oa(a,u)||(t=!0,hf(a,u));a=a.next}while(t);Uc=!1}}function Mh(){zu=Rc=!1;var e=0;qt!==0&&(Lh()&&(e=qt),qt=0);for(var l=rl(),t=null,a=Mu;a!==null;){var n=a.next,u=df(a,l);u===0?(a.next=null,t===null?Mu=n:t.next=n,n===null&&(Sa=t)):(t=a,(e!==0||u&3)&&(zu=!0)),a=n}gn(e)}function df(e,l){for(var t=e.suspendedLanes,a=e.pingedLanes,n=e.expirationTimes,u=e.pendingLanes&-62914561;0"u"?null:document;function Cf(e,l,t){var a=xa;if(a&&typeof l=="string"&&l){var n=Ke(l);n='link[rel="'+e+'"][href="'+n+'"]',typeof t=="string"&&(n+='[crossorigin="'+t+'"]'),zf.has(n)||(zf.add(n),e={rel:e,crossOrigin:t,href:l},a.querySelector(n)===null&&(l=a.createElement("link"),Ee(l,"link",e),Se(l),a.head.appendChild(l)))}}function wh(e){Hl.D(e),Cf("dns-prefetch",e,null)}function Zh(e,l){Hl.C(e,l),Cf("preconnect",e,l)}function Kh(e,l,t){Hl.L(e,l,t);var a=xa;if(a&&e&&l){var n='link[rel="preload"][as="'+Ke(l)+'"]';l==="image"&&t&&t.imageSrcSet?(n+='[imagesrcset="'+Ke(t.imageSrcSet)+'"]',typeof t.imageSizes=="string"&&(n+='[imagesizes="'+Ke(t.imageSizes)+'"]')):n+='[href="'+Ke(e)+'"]';var u=n;switch(l){case"style":u=Aa(e);break;case"script":u=Da(e)}tl.has(u)||(e=J({rel:"preload",href:l==="image"&&t&&t.imageSrcSet?void 0:e,as:l},t),tl.set(u,e),a.querySelector(n)!==null||l==="style"&&a.querySelector(vn(u))||l==="script"&&a.querySelector(bn(u))||(l=a.createElement("link"),Ee(l,"link",e),Se(l),a.head.appendChild(l)))}}function Jh(e,l){Hl.m(e,l);var t=xa;if(t&&e){var a=l&&typeof l.as=="string"?l.as:"script",n='link[rel="modulepreload"][as="'+Ke(a)+'"][href="'+Ke(e)+'"]',u=n;switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":u=Da(e)}if(!tl.has(u)&&(e=J({rel:"modulepreload",href:e},l),tl.set(u,e),t.querySelector(n)===null)){switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(t.querySelector(bn(u)))return}a=t.createElement("link"),Ee(a,"link",e),Se(a),t.head.appendChild(a)}}}function kh(e,l,t){Hl.S(e,l,t);var a=xa;if(a&&e){var n=Kt(a).hoistableStyles,u=Aa(e);l=l||"default";var i=n.get(u);if(!i){var c={loading:0,preload:null};if(i=a.querySelector(vn(u)))c.loading=5;else{e=J({rel:"stylesheet",href:e,"data-precedence":l},t),(t=tl.get(u))&&Jc(e,t);var s=i=a.createElement("link");Se(s),Ee(s,"link",e),s._p=new Promise(function(f,v){s.onload=f,s.onerror=v}),s.addEventListener("load",function(){c.loading|=1}),s.addEventListener("error",function(){c.loading|=2}),c.loading|=4,_u(i,l,a)}i={type:"stylesheet",instance:i,count:1,state:c},n.set(u,i)}}}function Fh(e,l){Hl.X(e,l);var t=xa;if(t&&e){var a=Kt(t).hoistableScripts,n=Da(e),u=a.get(n);u||(u=t.querySelector(bn(n)),u||(e=J({src:e,async:!0},l),(l=tl.get(n))&&kc(e,l),u=t.createElement("script"),Se(u),Ee(u,"link",e),t.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function $h(e,l){Hl.M(e,l);var t=xa;if(t&&e){var a=Kt(t).hoistableScripts,n=Da(e),u=a.get(n);u||(u=t.querySelector(bn(n)),u||(e=J({src:e,async:!0,type:"module"},l),(l=tl.get(n))&&kc(e,l),u=t.createElement("script"),Se(u),Ee(u,"link",e),t.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function Of(e,l,t,a){var n=(n=Gl.current)?Uu(n):null;if(!n)throw Error(d(446));switch(e){case"meta":case"title":return null;case"style":return typeof t.precedence=="string"&&typeof t.href=="string"?(l=Aa(t.href),t=Kt(n).hoistableStyles,a=t.get(l),a||(a={type:"style",instance:null,count:0,state:null},t.set(l,a)),a):{type:"void",instance:null,count:0,state:null};case"link":if(t.rel==="stylesheet"&&typeof t.href=="string"&&typeof t.precedence=="string"){e=Aa(t.href);var u=Kt(n).hoistableStyles,i=u.get(e);if(i||(n=n.ownerDocument||n,i={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},u.set(e,i),(u=n.querySelector(vn(e)))&&!u._p&&(i.instance=u,i.state.loading=5),tl.has(e)||(t={rel:"preload",as:"style",href:t.href,crossOrigin:t.crossOrigin,integrity:t.integrity,media:t.media,hrefLang:t.hrefLang,referrerPolicy:t.referrerPolicy},tl.set(e,t),u||Wh(n,e,t,i.state))),l&&a===null)throw Error(d(528,""));return i}if(l&&a!==null)throw Error(d(529,""));return null;case"script":return l=t.async,t=t.src,typeof t=="string"&&l&&typeof l!="function"&&typeof l!="symbol"?(l=Da(t),t=Kt(n).hoistableScripts,a=t.get(l),a||(a={type:"script",instance:null,count:0,state:null},t.set(l,a)),a):{type:"void",instance:null,count:0,state:null};default:throw Error(d(444,e))}}function Aa(e){return'href="'+Ke(e)+'"'}function vn(e){return'link[rel="stylesheet"]['+e+"]"}function jf(e){return J({},e,{"data-precedence":e.precedence,precedence:null})}function Wh(e,l,t,a){e.querySelector('link[rel="preload"][as="style"]['+l+"]")?a.loading=1:(l=e.createElement("link"),a.preload=l,l.addEventListener("load",function(){return a.loading|=1}),l.addEventListener("error",function(){return a.loading|=2}),Ee(l,"link",t),Se(l),e.head.appendChild(l))}function Da(e){return'[src="'+Ke(e)+'"]'}function bn(e){return"script[async]"+e}function Rf(e,l,t){if(l.count++,l.instance===null)switch(l.type){case"style":var a=e.querySelector('style[data-href~="'+Ke(t.href)+'"]');if(a)return l.instance=a,Se(a),a;var n=J({},t,{"data-href":t.href,"data-precedence":t.precedence,href:null,precedence:null});return a=(e.ownerDocument||e).createElement("style"),Se(a),Ee(a,"style",n),_u(a,t.precedence,e),l.instance=a;case"stylesheet":n=Aa(t.href);var u=e.querySelector(vn(n));if(u)return l.state.loading|=4,l.instance=u,Se(u),u;a=jf(t),(n=tl.get(n))&&Jc(a,n),u=(e.ownerDocument||e).createElement("link"),Se(u);var i=u;return i._p=new Promise(function(c,s){i.onload=c,i.onerror=s}),Ee(u,"link",a),l.state.loading|=4,_u(u,t.precedence,e),l.instance=u;case"script":return u=Da(t.src),(n=e.querySelector(bn(u)))?(l.instance=n,Se(n),n):(a=t,(n=tl.get(u))&&(a=J({},t),kc(a,n)),e=e.ownerDocument||e,n=e.createElement("script"),Se(n),Ee(n,"link",a),e.head.appendChild(n),l.instance=n);case"void":return null;default:throw Error(d(443,l.type))}else l.type==="stylesheet"&&!(l.state.loading&4)&&(a=l.instance,l.state.loading|=4,_u(a,t.precedence,e));return l.instance}function _u(e,l,t){for(var a=t.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),n=a.length?a[a.length-1]:null,u=n,i=0;i title"):null)}function Ph(e,l,t){if(t===1||l.itemProp!=null)return!1;switch(e){case"meta":case"title":return!0;case"style":if(typeof l.precedence!="string"||typeof l.href!="string"||l.href==="")break;return!0;case"link":if(typeof l.rel!="string"||typeof l.href!="string"||l.href===""||l.onLoad||l.onError)break;switch(l.rel){case"stylesheet":return e=l.disabled,typeof l.precedence=="string"&&e==null;default:return!0}case"script":if(l.async&&typeof l.async!="function"&&typeof l.async!="symbol"&&!l.onLoad&&!l.onError&&l.src&&typeof l.src=="string")return!0}return!1}function Hf(e){return!(e.type==="stylesheet"&&!(e.state.loading&3))}var Sn=null;function Ih(){}function eg(e,l,t){if(Sn===null)throw Error(d(475));var a=Sn;if(l.type==="stylesheet"&&(typeof t.media!="string"||matchMedia(t.media).matches!==!1)&&!(l.state.loading&4)){if(l.instance===null){var n=Aa(t.href),u=e.querySelector(vn(n));if(u){e=u._p,e!==null&&typeof e=="object"&&typeof e.then=="function"&&(a.count++,a=Lu.bind(a),e.then(a,a)),l.state.loading|=4,l.instance=u,Se(u);return}u=e.ownerDocument||e,t=jf(t),(n=tl.get(n))&&Jc(t,n),u=u.createElement("link"),Se(u);var i=u;i._p=new Promise(function(c,s){i.onload=c,i.onerror=s}),Ee(u,"link",t),l.instance=u}a.stylesheets===null&&(a.stylesheets=new Map),a.stylesheets.set(l,e),(e=l.state.preload)&&!(l.state.loading&3)&&(a.count++,l=Lu.bind(a),e.addEventListener("load",l),e.addEventListener("error",l))}}function lg(){if(Sn===null)throw Error(d(475));var e=Sn;return e.stylesheets&&e.count===0&&Fc(e,e.stylesheets),0"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(g)}catch(b){console.error(b)}}return g(),ts.exports=lp(),ts.exports}var ap=tp();const np={visibleTabs:{},setTabVisibility:()=>{},isTabVisible:()=>!1},pd=E.createContext(np),up=({children:g})=>{const b=Ve.use.currentTab(),[x,d]=E.useState(()=>({documents:!0,"knowledge-graph":!0,retrieval:!0,api:!0}));E.useEffect(()=>{d(j=>({...j,documents:!0,"knowledge-graph":!0,retrieval:!0,api:!0}))},[b]);const N=E.useMemo(()=>({visibleTabs:x,setTabVisibility:(j,H)=>{d($=>({...$,[j]:H}))},isTabVisible:j=>!!x[j]}),[x]);return o.jsx(pd.Provider,{value:N,children:g})};var yd="AlertDialog",[ip,Yy]=hg(yd,[td]),ql=td(),vd=g=>{const{__scopeAlertDialog:b,...x}=g,d=ql(b);return o.jsx(Sg,{...d,...x,modal:!0})};vd.displayName=yd;var cp="AlertDialogTrigger",sp=E.forwardRef((g,b)=>{const{__scopeAlertDialog:x,...d}=g,N=ql(x);return o.jsx(Tg,{...N,...d,ref:b})});sp.displayName=cp;var op="AlertDialogPortal",bd=g=>{const{__scopeAlertDialog:b,...x}=g,d=ql(b);return o.jsx(dg,{...d,...x})};bd.displayName=op;var rp="AlertDialogOverlay",Sd=E.forwardRef((g,b)=>{const{__scopeAlertDialog:x,...d}=g,N=ql(x);return o.jsx(fg,{...N,...d,ref:b})});Sd.displayName=rp;var Na="AlertDialogContent",[fp,dp]=ip(Na),Td=E.forwardRef((g,b)=>{const{__scopeAlertDialog:x,children:d,...N}=g,j=ql(x),H=E.useRef(null),$=ad(b,H),Y=E.useRef(null);return o.jsx(mg,{contentName:Na,titleName:xd,docsSlug:"alert-dialog",children:o.jsx(fp,{scope:x,cancelRef:Y,children:o.jsxs(gg,{role:"alertdialog",...j,...N,ref:$,onOpenAutoFocus:pg(N.onOpenAutoFocus,W=>{var he;W.preventDefault(),(he=Y.current)==null||he.focus({preventScroll:!0})}),onPointerDownOutside:W=>W.preventDefault(),onInteractOutside:W=>W.preventDefault(),children:[o.jsx(yg,{children:d}),o.jsx(hp,{contentRef:H})]})})})});Td.displayName=Na;var xd="AlertDialogTitle",Ad=E.forwardRef((g,b)=>{const{__scopeAlertDialog:x,...d}=g,N=ql(x);return o.jsx(vg,{...N,...d,ref:b})});Ad.displayName=xd;var Dd="AlertDialogDescription",Nd=E.forwardRef((g,b)=>{const{__scopeAlertDialog:x,...d}=g,N=ql(x);return o.jsx(bg,{...N,...d,ref:b})});Nd.displayName=Dd;var mp="AlertDialogAction",Ed=E.forwardRef((g,b)=>{const{__scopeAlertDialog:x,...d}=g,N=ql(x);return o.jsx(nd,{...N,...d,ref:b})});Ed.displayName=mp;var Md="AlertDialogCancel",zd=E.forwardRef((g,b)=>{const{__scopeAlertDialog:x,...d}=g,{cancelRef:N}=dp(Md,x),j=ql(x),H=ad(b,N);return o.jsx(nd,{...j,...d,ref:H})});zd.displayName=Md;var hp=({contentRef:g})=>{const b=`\`${Na}\` requires a description for the component to be accessible for screen reader users. +`+t.stack}}function U(e){var l=e,t=e;if(e.alternate)for(;l.return;)l=l.return;else{e=l;do l=e,l.flags&4098&&(t=l.return),e=l.return;while(e)}return l.tag===3?t:null}function te(e){if(e.tag===13){var l=e.memoizedState;if(l===null&&(e=e.alternate,e!==null&&(l=e.memoizedState)),l!==null)return l.dehydrated}return null}function oe(e){if(U(e)!==e)throw Error(d(188))}function Xt(e){var l=e.alternate;if(!l){if(l=U(e),l===null)throw Error(d(188));return l!==e?null:e}for(var t=e,a=l;;){var n=t.return;if(n===null)break;var u=n.alternate;if(u===null){if(a=n.return,a!==null){t=a;continue}break}if(n.child===u.child){for(u=n.child;u;){if(u===t)return oe(n),e;if(u===a)return oe(n),l;u=u.sibling}throw Error(d(188))}if(t.return!==a.return)t=n,a=u;else{for(var i=!1,c=n.child;c;){if(c===t){i=!0,t=n,a=u;break}if(c===a){i=!0,a=n,t=u;break}c=c.sibling}if(!i){for(c=u.child;c;){if(c===t){i=!0,t=u,a=n;break}if(c===a){i=!0,a=u,t=n;break}c=c.sibling}if(!i)throw Error(d(189))}}if(t.alternate!==a)throw Error(d(190))}if(t.tag!==3)throw Error(d(188));return t.stateNode.current===t?e:l}function pt(e){var l=e.tag;if(l===5||l===26||l===27||l===6)return e;for(e=e.child;e!==null;){if(l=pt(e),l!==null)return l;e=e.sibling}return null}var vl=Array.isArray,Q=x.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,Qe={pending:!1,data:null,method:null,action:null},Ku=[],wt=-1;function sl(e){return{current:e}}function be(e){0>wt||(e.current=Ku[wt],Ku[wt]=null,wt--)}function ae(e,l){wt++,Ku[wt]=e.current,e.current=l}var ol=sl(null),za=sl(null),Gl=sl(null),jn=sl(null);function Rn(e,l){switch(ae(Gl,l),ae(za,e),ae(ol,null),e=l.nodeType,e){case 9:case 11:l=(l=l.documentElement)&&(l=l.namespaceURI)?xf(l):0;break;default:if(e=e===8?l.parentNode:l,l=e.tagName,e=e.namespaceURI)e=xf(e),l=Af(e,l);else switch(l){case"svg":l=1;break;case"math":l=2;break;default:l=0}}be(ol),ae(ol,l)}function Vt(){be(ol),be(za),be(Gl)}function ku(e){e.memoizedState!==null&&ae(jn,e);var l=ol.current,t=Af(l,e.type);l!==t&&(ae(za,e),ae(ol,t))}function Un(e){za.current===e&&(be(ol),be(za)),jn.current===e&&(be(jn),Tn._currentValue=Qe)}var Ju=Object.prototype.hasOwnProperty,Fu=g.unstable_scheduleCallback,$u=g.unstable_cancelCallback,Vd=g.unstable_shouldYield,Qd=g.unstable_requestPaint,rl=g.unstable_now,Zd=g.unstable_getCurrentPriorityLevel,os=g.unstable_ImmediatePriority,rs=g.unstable_UserBlockingPriority,_n=g.unstable_NormalPriority,Kd=g.unstable_LowPriority,fs=g.unstable_IdlePriority,kd=g.log,Jd=g.unstable_setDisableYieldValue,Ca=null,He=null;function Fd(e){if(He&&typeof He.onCommitFiberRoot=="function")try{He.onCommitFiberRoot(Ca,e,void 0,(e.current.flags&128)===128)}catch{}}function Yl(e){if(typeof kd=="function"&&Jd(e),He&&typeof He.setStrictMode=="function")try{He.setStrictMode(Ca,e)}catch{}}var Le=Math.clz32?Math.clz32:Pd,$d=Math.log,Wd=Math.LN2;function Pd(e){return e>>>=0,e===0?32:31-($d(e)/Wd|0)|0}var Hn=128,Ln=4194304;function yt(e){var l=e&42;if(l!==0)return l;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194176;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function Bn(e,l){var t=e.pendingLanes;if(t===0)return 0;var a=0,n=e.suspendedLanes,u=e.pingedLanes,i=e.warmLanes;e=e.finishedLanes!==0;var c=t&134217727;return c!==0?(t=c&~n,t!==0?a=yt(t):(u&=c,u!==0?a=yt(u):e||(i=c&~i,i!==0&&(a=yt(i))))):(c=t&~n,c!==0?a=yt(c):u!==0?a=yt(u):e||(i=t&~i,i!==0&&(a=yt(i)))),a===0?0:l!==0&&l!==a&&!(l&n)&&(n=a&-a,i=l&-l,n>=i||n===32&&(i&4194176)!==0)?l:a}function Oa(e,l){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&l)===0}function Id(e,l){switch(e){case 1:case 2:case 4:case 8:return l+250;case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return l+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function ds(){var e=Hn;return Hn<<=1,!(Hn&4194176)&&(Hn=128),e}function ms(){var e=Ln;return Ln<<=1,!(Ln&62914560)&&(Ln=4194304),e}function Wu(e){for(var l=[],t=0;31>t;t++)l.push(e);return l}function ja(e,l){e.pendingLanes|=l,l!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function em(e,l,t,a,n,u){var i=e.pendingLanes;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=t,e.entangledLanes&=t,e.errorRecoveryDisabledLanes&=t,e.shellSuspendCounter=0;var c=e.entanglements,s=e.expirationTimes,f=e.hiddenUpdates;for(t=i&~t;0"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),nm=RegExp("^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$"),Ts={},xs={};function um(e){return Ju.call(xs,e)?!0:Ju.call(Ts,e)?!1:nm.test(e)?xs[e]=!0:(Ts[e]=!0,!1)}function qn(e,l,t){if(um(l))if(t===null)e.removeAttribute(l);else{switch(typeof t){case"undefined":case"function":case"symbol":e.removeAttribute(l);return;case"boolean":var a=l.toLowerCase().slice(0,5);if(a!=="data-"&&a!=="aria-"){e.removeAttribute(l);return}}e.setAttribute(l,""+t)}}function Gn(e,l,t){if(t===null)e.removeAttribute(l);else{switch(typeof t){case"undefined":case"function":case"symbol":case"boolean":e.removeAttribute(l);return}e.setAttribute(l,""+t)}}function Sl(e,l,t,a){if(a===null)e.removeAttribute(t);else{switch(typeof a){case"undefined":case"function":case"symbol":case"boolean":e.removeAttribute(t);return}e.setAttributeNS(l,t,""+a)}}function Ze(e){switch(typeof e){case"bigint":case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function As(e){var l=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(l==="checkbox"||l==="radio")}function im(e){var l=As(e)?"checked":"value",t=Object.getOwnPropertyDescriptor(e.constructor.prototype,l),a=""+e[l];if(!e.hasOwnProperty(l)&&typeof t<"u"&&typeof t.get=="function"&&typeof t.set=="function"){var n=t.get,u=t.set;return Object.defineProperty(e,l,{configurable:!0,get:function(){return n.call(this)},set:function(i){a=""+i,u.call(this,i)}}),Object.defineProperty(e,l,{enumerable:t.enumerable}),{getValue:function(){return a},setValue:function(i){a=""+i},stopTracking:function(){e._valueTracker=null,delete e[l]}}}}function Yn(e){e._valueTracker||(e._valueTracker=im(e))}function Ds(e){if(!e)return!1;var l=e._valueTracker;if(!l)return!0;var t=l.getValue(),a="";return e&&(a=As(e)?e.checked?"true":"false":e.value),e=a,e!==t?(l.setValue(e),!0):!1}function Xn(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}var cm=/[\n"\\]/g;function Ke(e){return e.replace(cm,function(l){return"\\"+l.charCodeAt(0).toString(16)+" "})}function ei(e,l,t,a,n,u,i,c){e.name="",i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"?e.type=i:e.removeAttribute("type"),l!=null?i==="number"?(l===0&&e.value===""||e.value!=l)&&(e.value=""+Ze(l)):e.value!==""+Ze(l)&&(e.value=""+Ze(l)):i!=="submit"&&i!=="reset"||e.removeAttribute("value"),l!=null?li(e,i,Ze(l)):t!=null?li(e,i,Ze(t)):a!=null&&e.removeAttribute("value"),n==null&&u!=null&&(e.defaultChecked=!!u),n!=null&&(e.checked=n&&typeof n!="function"&&typeof n!="symbol"),c!=null&&typeof c!="function"&&typeof c!="symbol"&&typeof c!="boolean"?e.name=""+Ze(c):e.removeAttribute("name")}function Ns(e,l,t,a,n,u,i,c){if(u!=null&&typeof u!="function"&&typeof u!="symbol"&&typeof u!="boolean"&&(e.type=u),l!=null||t!=null){if(!(u!=="submit"&&u!=="reset"||l!=null))return;t=t!=null?""+Ze(t):"",l=l!=null?""+Ze(l):t,c||l===e.value||(e.value=l),e.defaultValue=l}a=a??n,a=typeof a!="function"&&typeof a!="symbol"&&!!a,e.checked=c?e.checked:!!a,e.defaultChecked=!!a,i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"&&(e.name=i)}function li(e,l,t){l==="number"&&Xn(e.ownerDocument)===e||e.defaultValue===""+t||(e.defaultValue=""+t)}function Jt(e,l,t,a){if(e=e.options,l){l={};for(var n=0;n=qa),qs=" ",Gs=!1;function Ys(e,l){switch(e){case"keyup":return Hm.indexOf(l.keyCode)!==-1;case"keydown":return l.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Xs(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Pt=!1;function Bm(e,l){switch(e){case"compositionend":return Xs(l);case"keypress":return l.which!==32?null:(Gs=!0,qs);case"textInput":return e=l.data,e===qs&&Gs?null:e;default:return null}}function qm(e,l){if(Pt)return e==="compositionend"||!di&&Ys(e,l)?(e=Rs(),Vn=ci=wl=null,Pt=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(l.ctrlKey||l.altKey||l.metaKey)||l.ctrlKey&&l.altKey){if(l.char&&1=l)return{node:t,offset:l-e};e=a}e:{for(;t;){if(t.nextSibling){t=t.nextSibling;break e}t=t.parentNode}t=void 0}t=Fs(t)}}function Ws(e,l){return e&&l?e===l?!0:e&&e.nodeType===3?!1:l&&l.nodeType===3?Ws(e,l.parentNode):"contains"in e?e.contains(l):e.compareDocumentPosition?!!(e.compareDocumentPosition(l)&16):!1:!1}function Ps(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var l=Xn(e.document);l instanceof e.HTMLIFrameElement;){try{var t=typeof l.contentWindow.location.href=="string"}catch{t=!1}if(t)e=l.contentWindow;else break;l=Xn(e.document)}return l}function gi(e){var l=e&&e.nodeName&&e.nodeName.toLowerCase();return l&&(l==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||l==="textarea"||e.contentEditable==="true")}function Km(e,l){var t=Ps(l);l=e.focusedElem;var a=e.selectionRange;if(t!==l&&l&&l.ownerDocument&&Ws(l.ownerDocument.documentElement,l)){if(a!==null&&gi(l)){if(e=a.start,t=a.end,t===void 0&&(t=e),"selectionStart"in l)l.selectionStart=e,l.selectionEnd=Math.min(t,l.value.length);else if(t=(e=l.ownerDocument||document)&&e.defaultView||window,t.getSelection){t=t.getSelection();var n=l.textContent.length,u=Math.min(a.start,n);a=a.end===void 0?u:Math.min(a.end,n),!t.extend&&u>a&&(n=a,a=u,u=n),n=$s(l,u);var i=$s(l,a);n&&i&&(t.rangeCount!==1||t.anchorNode!==n.node||t.anchorOffset!==n.offset||t.focusNode!==i.node||t.focusOffset!==i.offset)&&(e=e.createRange(),e.setStart(n.node,n.offset),t.removeAllRanges(),u>a?(t.addRange(e),t.extend(i.node,i.offset)):(e.setEnd(i.node,i.offset),t.addRange(e)))}}for(e=[],t=l;t=t.parentNode;)t.nodeType===1&&e.push({element:t,left:t.scrollLeft,top:t.scrollTop});for(typeof l.focus=="function"&&l.focus(),l=0;l=document.documentMode,It=null,pi=null,wa=null,yi=!1;function Is(e,l,t){var a=t.window===t?t.document:t.nodeType===9?t:t.ownerDocument;yi||It==null||It!==Xn(a)||(a=It,"selectionStart"in a&&gi(a)?a={start:a.selectionStart,end:a.selectionEnd}:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection(),a={anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset}),wa&&Xa(wa,a)||(wa=a,a=Ou(pi,"onSelect"),0>=i,n-=i,Tl=1<<32-Le(l)+n|t<O?(Ae=z,z=null):Ae=z.sibling;var K=p(m,z,h[O],S);if(K===null){z===null&&(z=Ae);break}e&&z&&K.alternate===null&&l(m,z),r=u(K,r,O),q===null?D=K:q.sibling=K,q=K,z=Ae}if(O===h.length)return t(m,z),Z&&Dt(m,O),D;if(z===null){for(;OO?(Ae=z,z=null):Ae=z.sibling;var st=p(m,z,K.value,S);if(st===null){z===null&&(z=Ae);break}e&&z&&st.alternate===null&&l(m,z),r=u(st,r,O),q===null?D=st:q.sibling=st,q=st,z=Ae}if(K.done)return t(m,z),Z&&Dt(m,O),D;if(z===null){for(;!K.done;O++,K=h.next())K=T(m,K.value,S),K!==null&&(r=u(K,r,O),q===null?D=K:q.sibling=K,q=K);return Z&&Dt(m,O),D}for(z=a(z);!K.done;O++,K=h.next())K=y(z,m,O,K.value,S),K!==null&&(e&&K.alternate!==null&&z.delete(K.key===null?O:K.key),r=u(K,r,O),q===null?D=K:q.sibling=K,q=K);return e&&z.forEach(function(rg){return l(m,rg)}),Z&&Dt(m,O),D}function se(m,r,h,S){if(typeof h=="object"&&h!==null&&h.type===Y&&h.key===null&&(h=h.props.children),typeof h=="object"&&h!==null){switch(h.$$typeof){case H:e:{for(var D=h.key;r!==null;){if(r.key===D){if(D=h.type,D===Y){if(r.tag===7){t(m,r.sibling),S=n(r,h.props.children),S.return=m,m=S;break e}}else if(r.elementType===D||typeof D=="object"&&D!==null&&D.$$typeof===je&&yo(D)===r.type){t(m,r.sibling),S=n(r,h.props),Fa(S,h),S.return=m,m=S;break e}t(m,r);break}else l(m,r);r=r.sibling}h.type===Y?(S=Ht(h.props.children,m.mode,S,h.key),S.return=m,m=S):(S=Su(h.type,h.key,h.props,null,m.mode,S),Fa(S,h),S.return=m,m=S)}return i(m);case $:e:{for(D=h.key;r!==null;){if(r.key===D)if(r.tag===4&&r.stateNode.containerInfo===h.containerInfo&&r.stateNode.implementation===h.implementation){t(m,r.sibling),S=n(r,h.children||[]),S.return=m,m=S;break e}else{t(m,r);break}else l(m,r);r=r.sibling}S=bc(h,m.mode,S),S.return=m,m=S}return i(m);case je:return D=h._init,h=D(h._payload),se(m,r,h,S)}if(vl(h))return M(m,r,h,S);if(al(h)){if(D=al(h),typeof D!="function")throw Error(d(150));return h=D.call(h),_(m,r,h,S)}if(typeof h.then=="function")return se(m,r,lu(h),S);if(h.$$typeof===pe)return se(m,r,yu(m,h),S);tu(m,h)}return typeof h=="string"&&h!==""||typeof h=="number"||typeof h=="bigint"?(h=""+h,r!==null&&r.tag===6?(t(m,r.sibling),S=n(r,h),S.return=m,m=S):(t(m,r),S=vc(h,m.mode,S),S.return=m,m=S),i(m)):t(m,r)}return function(m,r,h,S){try{Ja=0;var D=se(m,r,h,S);return ua=null,D}catch(z){if(z===Ka)throw z;var q=el(29,z,null,m.mode);return q.lanes=S,q.return=m,q}finally{}}}var Et=vo(!0),bo=vo(!1),ia=sl(null),au=sl(0);function So(e,l){e=Ul,ae(au,e),ae(ia,l),Ul=e|l.baseLanes}function Ni(){ae(au,Ul),ae(ia,ia.current)}function Ei(){Ul=au.current,be(ia),be(au)}var We=sl(null),dl=null;function Ql(e){var l=e.alternate;ae(ye,ye.current&1),ae(We,e),dl===null&&(l===null||ia.current!==null||l.memoizedState!==null)&&(dl=e)}function To(e){if(e.tag===22){if(ae(ye,ye.current),ae(We,e),dl===null){var l=e.alternate;l!==null&&l.memoizedState!==null&&(dl=e)}}else Zl()}function Zl(){ae(ye,ye.current),ae(We,We.current)}function Al(e){be(We),dl===e&&(dl=null),be(ye)}var ye=sl(0);function nu(e){for(var l=e;l!==null;){if(l.tag===13){var t=l.memoizedState;if(t!==null&&(t=t.dehydrated,t===null||t.data==="$?"||t.data==="$!"))return l}else if(l.tag===19&&l.memoizedProps.revealOrder!==void 0){if(l.flags&128)return l}else if(l.child!==null){l.child.return=l,l=l.child;continue}if(l===e)break;for(;l.sibling===null;){if(l.return===null||l.return===e)return null;l=l.return}l.sibling.return=l.return,l=l.sibling}return null}var Wm=typeof AbortController<"u"?AbortController:function(){var e=[],l=this.signal={aborted:!1,addEventListener:function(t,a){e.push(a)}};this.abort=function(){l.aborted=!0,e.forEach(function(t){return t()})}},Pm=g.unstable_scheduleCallback,Im=g.unstable_NormalPriority,ve={$$typeof:pe,Consumer:null,Provider:null,_currentValue:null,_currentValue2:null,_threadCount:0};function Mi(){return{controller:new Wm,data:new Map,refCount:0}}function $a(e){e.refCount--,e.refCount===0&&Pm(Im,function(){e.controller.abort()})}var Wa=null,zi=0,ca=0,sa=null;function eh(e,l){if(Wa===null){var t=Wa=[];zi=0,ca=_c(),sa={status:"pending",value:void 0,then:function(a){t.push(a)}}}return zi++,l.then(xo,xo),l}function xo(){if(--zi===0&&Wa!==null){sa!==null&&(sa.status="fulfilled");var e=Wa;Wa=null,ca=0,sa=null;for(var l=0;lu?u:8;var i=R.T,c={};R.T=c,Zi(e,!1,l,t);try{var s=n(),f=R.S;if(f!==null&&f(c,s),s!==null&&typeof s=="object"&&typeof s.then=="function"){var b=lh(s,a);en(e,l,b,Xe(e))}else en(e,l,a,Xe(e))}catch(T){en(e,l,{then:function(){},status:"rejected",reason:T},Xe())}finally{Q.p=u,R.T=i}}function ih(){}function Vi(e,l,t,a){if(e.tag!==5)throw Error(d(476));var n=Io(e).queue;Po(e,n,l,Qe,t===null?ih:function(){return er(e),t(a)})}function Io(e){var l=e.memoizedState;if(l!==null)return l;l={memoizedState:Qe,baseState:Qe,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Dl,lastRenderedState:Qe},next:null};var t={};return l.next={memoizedState:t,baseState:t,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Dl,lastRenderedState:t},next:null},e.memoizedState=l,e=e.alternate,e!==null&&(e.memoizedState=l),l}function er(e){var l=Io(e).next.queue;en(e,l,{},Xe())}function Qi(){return ze(Tn)}function lr(){return de().memoizedState}function tr(){return de().memoizedState}function ch(e){for(var l=e.return;l!==null;){switch(l.tag){case 24:case 3:var t=Xe();e=$l(t);var a=Wl(l,e,t);a!==null&&(Oe(a,l,t),an(a,l,t)),l={cache:Mi()},e.payload=l;return}l=l.return}}function sh(e,l,t){var a=Xe();t={lane:a,revertLane:0,action:t,hasEagerState:!1,eagerState:null,next:null},mu(e)?nr(l,t):(t=Si(e,l,t,a),t!==null&&(Oe(t,e,a),ur(t,l,a)))}function ar(e,l,t){var a=Xe();en(e,l,t,a)}function en(e,l,t,a){var n={lane:a,revertLane:0,action:t,hasEagerState:!1,eagerState:null,next:null};if(mu(e))nr(l,n);else{var u=e.alternate;if(e.lanes===0&&(u===null||u.lanes===0)&&(u=l.lastRenderedReducer,u!==null))try{var i=l.lastRenderedState,c=u(i,t);if(n.hasEagerState=!0,n.eagerState=c,Be(c,i))return $n(e,l,n,0),I===null&&Fn(),!1}catch{}finally{}if(t=Si(e,l,n,a),t!==null)return Oe(t,e,a),ur(t,l,a),!0}return!1}function Zi(e,l,t,a){if(a={lane:2,revertLane:_c(),action:a,hasEagerState:!1,eagerState:null,next:null},mu(e)){if(l)throw Error(d(479))}else l=Si(e,t,a,2),l!==null&&Oe(l,e,2)}function mu(e){var l=e.alternate;return e===B||l!==null&&l===B}function nr(e,l){oa=iu=!0;var t=e.pending;t===null?l.next=l:(l.next=t.next,t.next=l),e.pending=l}function ur(e,l,t){if(t&4194176){var a=l.lanes;a&=e.pendingLanes,t|=a,l.lanes=t,gs(e,t)}}var ml={readContext:ze,use:ou,useCallback:re,useContext:re,useEffect:re,useImperativeHandle:re,useLayoutEffect:re,useInsertionEffect:re,useMemo:re,useReducer:re,useRef:re,useState:re,useDebugValue:re,useDeferredValue:re,useTransition:re,useSyncExternalStore:re,useId:re};ml.useCacheRefresh=re,ml.useMemoCache=re,ml.useHostTransitionStatus=re,ml.useFormState=re,ml.useActionState=re,ml.useOptimistic=re;var Ct={readContext:ze,use:ou,useCallback:function(e,l){return _e().memoizedState=[e,l===void 0?null:l],e},useContext:ze,useEffect:Qo,useImperativeHandle:function(e,l,t){t=t!=null?t.concat([e]):null,fu(4194308,4,ko.bind(null,l,e),t)},useLayoutEffect:function(e,l){return fu(4194308,4,e,l)},useInsertionEffect:function(e,l){fu(4,2,e,l)},useMemo:function(e,l){var t=_e();l=l===void 0?null:l;var a=e();if(zt){Yl(!0);try{e()}finally{Yl(!1)}}return t.memoizedState=[a,l],a},useReducer:function(e,l,t){var a=_e();if(t!==void 0){var n=t(l);if(zt){Yl(!0);try{t(l)}finally{Yl(!1)}}}else n=l;return a.memoizedState=a.baseState=n,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:n},a.queue=e,e=e.dispatch=sh.bind(null,B,e),[a.memoizedState,e]},useRef:function(e){var l=_e();return e={current:e},l.memoizedState=e},useState:function(e){e=qi(e);var l=e.queue,t=ar.bind(null,B,l);return l.dispatch=t,[e.memoizedState,t]},useDebugValue:Xi,useDeferredValue:function(e,l){var t=_e();return wi(t,e,l)},useTransition:function(){var e=qi(!1);return e=Po.bind(null,B,e.queue,!0,!1),_e().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,l,t){var a=B,n=_e();if(Z){if(t===void 0)throw Error(d(407));t=t()}else{if(t=l(),I===null)throw Error(d(349));V&60||zo(a,l,t)}n.memoizedState=t;var u={value:t,getSnapshot:l};return n.queue=u,Qo(Oo.bind(null,a,u,e),[e]),a.flags|=2048,fa(9,Co.bind(null,a,u,t,l),{destroy:void 0},null),t},useId:function(){var e=_e(),l=I.identifierPrefix;if(Z){var t=xl,a=Tl;t=(a&~(1<<32-Le(a)-1)).toString(32)+t,l=":"+l+"R"+t,t=cu++,0 title"))),Ee(u,a,t),u[Me]=e,Se(u),a=u;break e;case"link":var i=Uf("link","href",n).get(a+(t.href||""));if(i){for(var c=0;c<\/script>",e=e.removeChild(e.firstChild);break;case"select":e=typeof a.is=="string"?n.createElement("select",{is:a.is}):n.createElement("select"),a.multiple?e.multiple=!0:a.size&&(e.size=a.size);break;default:e=typeof a.is=="string"?n.createElement(t,{is:a.is}):n.createElement(t)}}e[Me]=l,e[Re]=a;e:for(n=l.child;n!==null;){if(n.tag===5||n.tag===6)e.appendChild(n.stateNode);else if(n.tag!==4&&n.tag!==27&&n.child!==null){n.child.return=n,n=n.child;continue}if(n===l)break e;for(;n.sibling===null;){if(n.return===null||n.return===l)break e;n=n.return}n.sibling.return=n.return,n=n.sibling}l.stateNode=e;e:switch(Ee(e,t,a),t){case"button":case"input":case"select":case"textarea":e=!!a.autoFocus;break e;case"img":e=!0;break e;default:e=!1}e&&jl(l)}}return ne(l),l.flags&=-16777217,null;case 6:if(e&&l.stateNode!=null)e.memoizedProps!==a&&jl(l);else{if(typeof a!="string"&&l.stateNode===null)throw Error(d(166));if(e=Gl.current,Va(l)){if(e=l.stateNode,t=l.memoizedProps,a=null,n=Ce,n!==null)switch(n.tag){case 27:case 5:a=n.memoizedProps}e[Me]=l,e=!!(e.nodeValue===t||a!==null&&a.suppressHydrationWarning===!0||Tf(e.nodeValue,t)),e||Nt(l)}else e=Ru(e).createTextNode(a),e[Me]=l,l.stateNode=e}return ne(l),null;case 13:if(a=l.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(n=Va(l),a!==null&&a.dehydrated!==null){if(e===null){if(!n)throw Error(d(318));if(n=l.memoizedState,n=n!==null?n.dehydrated:null,!n)throw Error(d(317));n[Me]=l}else Qa(),!(l.flags&128)&&(l.memoizedState=null),l.flags|=4;ne(l),n=!1}else ul!==null&&(Mc(ul),ul=null),n=!0;if(!n)return l.flags&256?(Al(l),l):(Al(l),null)}if(Al(l),l.flags&128)return l.lanes=t,l;if(t=a!==null,e=e!==null&&e.memoizedState!==null,t){a=l.child,n=null,a.alternate!==null&&a.alternate.memoizedState!==null&&a.alternate.memoizedState.cachePool!==null&&(n=a.alternate.memoizedState.cachePool.pool);var u=null;a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(u=a.memoizedState.cachePool.pool),u!==n&&(a.flags|=2048)}return t!==e&&t&&(l.child.flags|=8192),Tu(l,l.updateQueue),ne(l),null;case 4:return Vt(),e===null&&qc(l.stateNode.containerInfo),ne(l),null;case 10:return Ml(l.type),ne(l),null;case 19:if(be(ye),n=l.memoizedState,n===null)return ne(l),null;if(a=(l.flags&128)!==0,u=n.rendering,u===null)if(a)fn(n,!1);else{if(ce!==0||e!==null&&e.flags&128)for(e=l.child;e!==null;){if(u=nu(e),u!==null){for(l.flags|=128,fn(n,!1),e=u.updateQueue,l.updateQueue=e,Tu(l,e),l.subtreeFlags=0,e=t,t=l.child;t!==null;)Jr(t,e),t=t.sibling;return ae(ye,ye.current&1|2),l.child}e=e.sibling}n.tail!==null&&rl()>xu&&(l.flags|=128,a=!0,fn(n,!1),l.lanes=4194304)}else{if(!a)if(e=nu(u),e!==null){if(l.flags|=128,a=!0,e=e.updateQueue,l.updateQueue=e,Tu(l,e),fn(n,!0),n.tail===null&&n.tailMode==="hidden"&&!u.alternate&&!Z)return ne(l),null}else 2*rl()-n.renderingStartTime>xu&&t!==536870912&&(l.flags|=128,a=!0,fn(n,!1),l.lanes=4194304);n.isBackwards?(u.sibling=l.child,l.child=u):(e=n.last,e!==null?e.sibling=u:l.child=u,n.last=u)}return n.tail!==null?(l=n.tail,n.rendering=l,n.tail=l.sibling,n.renderingStartTime=rl(),l.sibling=null,e=ye.current,ae(ye,a?e&1|2:e&1),l):(ne(l),null);case 22:case 23:return Al(l),Ei(),a=l.memoizedState!==null,e!==null?e.memoizedState!==null!==a&&(l.flags|=8192):a&&(l.flags|=8192),a?t&536870912&&!(l.flags&128)&&(ne(l),l.subtreeFlags&6&&(l.flags|=8192)):ne(l),t=l.updateQueue,t!==null&&Tu(l,t.retryQueue),t=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(t=e.memoizedState.cachePool.pool),a=null,l.memoizedState!==null&&l.memoizedState.cachePool!==null&&(a=l.memoizedState.cachePool.pool),a!==t&&(l.flags|=2048),e!==null&&be(Mt),null;case 24:return t=null,e!==null&&(t=e.memoizedState.cache),l.memoizedState.cache!==t&&(l.flags|=2048),Ml(ve),ne(l),null;case 25:return null}throw Error(d(156,l.tag))}function gh(e,l){switch(xi(l),l.tag){case 1:return e=l.flags,e&65536?(l.flags=e&-65537|128,l):null;case 3:return Ml(ve),Vt(),e=l.flags,e&65536&&!(e&128)?(l.flags=e&-65537|128,l):null;case 26:case 27:case 5:return Un(l),null;case 13:if(Al(l),e=l.memoizedState,e!==null&&e.dehydrated!==null){if(l.alternate===null)throw Error(d(340));Qa()}return e=l.flags,e&65536?(l.flags=e&-65537|128,l):null;case 19:return be(ye),null;case 4:return Vt(),null;case 10:return Ml(l.type),null;case 22:case 23:return Al(l),Ei(),e!==null&&be(Mt),e=l.flags,e&65536?(l.flags=e&-65537|128,l):null;case 24:return Ml(ve),null;case 25:return null;default:return null}}function Wr(e,l){switch(xi(l),l.tag){case 3:Ml(ve),Vt();break;case 26:case 27:case 5:Un(l);break;case 4:Vt();break;case 13:Al(l);break;case 19:be(ye);break;case 10:Ml(l.type);break;case 22:case 23:Al(l),Ei(),e!==null&&be(Mt);break;case 24:Ml(ve)}}var ph={getCacheForType:function(e){var l=ze(ve),t=l.data.get(e);return t===void 0&&(t=e(),l.data.set(e,t)),t}},yh=typeof WeakMap=="function"?WeakMap:Map,ue=0,I=null,G=null,V=0,ee=0,Ye=null,Rl=!1,ga=!1,Sc=!1,Ul=0,ce=0,tt=0,Lt=0,Tc=0,ll=0,pa=0,dn=null,hl=null,xc=!1,Ac=0,xu=1/0,Au=null,at=null,Du=!1,Bt=null,mn=0,Dc=0,Nc=null,hn=0,Ec=null;function Xe(){if(ue&2&&V!==0)return V&-V;if(R.T!==null){var e=ca;return e!==0?e:_c()}return ys()}function Pr(){ll===0&&(ll=!(V&536870912)||Z?ds():536870912);var e=We.current;return e!==null&&(e.flags|=32),ll}function Oe(e,l,t){(e===I&&ee===2||e.cancelPendingCommit!==null)&&(ya(e,0),_l(e,V,ll,!1)),ja(e,t),(!(ue&2)||e!==I)&&(e===I&&(!(ue&2)&&(Lt|=t),ce===4&&_l(e,V,ll,!1)),gl(e))}function Ir(e,l,t){if(ue&6)throw Error(d(327));var a=!t&&(l&60)===0&&(l&e.expiredLanes)===0||Oa(e,l),n=a?Sh(e,l):Oc(e,l,!0),u=a;do{if(n===0){ga&&!a&&_l(e,l,0,!1);break}else if(n===6)_l(e,l,0,!Rl);else{if(t=e.current.alternate,u&&!vh(t)){n=Oc(e,l,!1),u=!1;continue}if(n===2){if(u=l,e.errorRecoveryDisabledLanes&u)var i=0;else i=e.pendingLanes&-536870913,i=i!==0?i:i&536870912?536870912:0;if(i!==0){l=i;e:{var c=e;n=dn;var s=c.current.memoizedState.isDehydrated;if(s&&(ya(c,i).flags|=256),i=Oc(c,i,!1),i!==2){if(Sc&&!s){c.errorRecoveryDisabledLanes|=u,Lt|=u,n=4;break e}u=hl,hl=n,u!==null&&Mc(u)}n=i}if(u=!1,n!==2)continue}}if(n===1){ya(e,0),_l(e,l,0,!0);break}e:{switch(a=e,n){case 0:case 1:throw Error(d(345));case 4:if((l&4194176)===l){_l(a,l,ll,!Rl);break e}break;case 2:hl=null;break;case 3:case 5:break;default:throw Error(d(329))}if(a.finishedWork=t,a.finishedLanes=l,(l&62914560)===l&&(u=Ac+300-rl(),10t?32:t,R.T=null,Bt===null)var u=!1;else{t=Nc,Nc=null;var i=Bt,c=mn;if(Bt=null,mn=0,ue&6)throw Error(d(331));var s=ue;if(ue|=4,Kr(i.current),Vr(i,i.current,c,t),ue=s,gn(0,!1),He&&typeof He.onPostCommitFiberRoot=="function")try{He.onPostCommitFiberRoot(Ca,i)}catch{}u=!0}return u}finally{Q.p=n,R.T=a,of(e,l)}}return!1}function rf(e,l,t){l=Je(t,l),l=Ji(e.stateNode,l,2),e=Wl(e,l,2),e!==null&&(ja(e,2),gl(e))}function P(e,l,t){if(e.tag===3)rf(e,e,t);else for(;l!==null;){if(l.tag===3){rf(l,e,t);break}else if(l.tag===1){var a=l.stateNode;if(typeof l.type.getDerivedStateFromError=="function"||typeof a.componentDidCatch=="function"&&(at===null||!at.has(a))){e=Je(t,e),t=dr(2),a=Wl(l,t,2),a!==null&&(mr(t,a,l,e),ja(a,2),gl(a));break}}l=l.return}}function jc(e,l,t){var a=e.pingCache;if(a===null){a=e.pingCache=new yh;var n=new Set;a.set(l,n)}else n=a.get(l),n===void 0&&(n=new Set,a.set(l,n));n.has(t)||(Sc=!0,n.add(t),e=Ah.bind(null,e,l,t),l.then(e,e))}function Ah(e,l,t){var a=e.pingCache;a!==null&&a.delete(l),e.pingedLanes|=e.suspendedLanes&t,e.warmLanes&=~t,I===e&&(V&t)===t&&(ce===4||ce===3&&(V&62914560)===V&&300>rl()-Ac?!(ue&2)&&ya(e,0):Tc|=t,pa===V&&(pa=0)),gl(e)}function ff(e,l){l===0&&(l=ms()),e=Vl(e,l),e!==null&&(ja(e,l),gl(e))}function Dh(e){var l=e.memoizedState,t=0;l!==null&&(t=l.retryLane),ff(e,t)}function Nh(e,l){var t=0;switch(e.tag){case 13:var a=e.stateNode,n=e.memoizedState;n!==null&&(t=n.retryLane);break;case 19:a=e.stateNode;break;case 22:a=e.stateNode._retryCache;break;default:throw Error(d(314))}a!==null&&a.delete(l),ff(e,t)}function Eh(e,l){return Fu(e,l)}var Mu=null,Sa=null,Rc=!1,zu=!1,Uc=!1,qt=0;function gl(e){e!==Sa&&e.next===null&&(Sa===null?Mu=Sa=e:Sa=Sa.next=e),zu=!0,Rc||(Rc=!0,zh(Mh))}function gn(e,l){if(!Uc&&zu){Uc=!0;do for(var t=!1,a=Mu;a!==null;){if(e!==0){var n=a.pendingLanes;if(n===0)var u=0;else{var i=a.suspendedLanes,c=a.pingedLanes;u=(1<<31-Le(42|e)+1)-1,u&=n&~(i&~c),u=u&201326677?u&201326677|1:u?u|2:0}u!==0&&(t=!0,hf(a,u))}else u=V,u=Bn(a,a===I?u:0),!(u&3)||Oa(a,u)||(t=!0,hf(a,u));a=a.next}while(t);Uc=!1}}function Mh(){zu=Rc=!1;var e=0;qt!==0&&(Lh()&&(e=qt),qt=0);for(var l=rl(),t=null,a=Mu;a!==null;){var n=a.next,u=df(a,l);u===0?(a.next=null,t===null?Mu=n:t.next=n,n===null&&(Sa=t)):(t=a,(e!==0||u&3)&&(zu=!0)),a=n}gn(e)}function df(e,l){for(var t=e.suspendedLanes,a=e.pingedLanes,n=e.expirationTimes,u=e.pendingLanes&-62914561;0"u"?null:document;function Cf(e,l,t){var a=xa;if(a&&typeof l=="string"&&l){var n=Ke(l);n='link[rel="'+e+'"][href="'+n+'"]',typeof t=="string"&&(n+='[crossorigin="'+t+'"]'),zf.has(n)||(zf.add(n),e={rel:e,crossOrigin:t,href:l},a.querySelector(n)===null&&(l=a.createElement("link"),Ee(l,"link",e),Se(l),a.head.appendChild(l)))}}function Qh(e){Hl.D(e),Cf("dns-prefetch",e,null)}function Zh(e,l){Hl.C(e,l),Cf("preconnect",e,l)}function Kh(e,l,t){Hl.L(e,l,t);var a=xa;if(a&&e&&l){var n='link[rel="preload"][as="'+Ke(l)+'"]';l==="image"&&t&&t.imageSrcSet?(n+='[imagesrcset="'+Ke(t.imageSrcSet)+'"]',typeof t.imageSizes=="string"&&(n+='[imagesizes="'+Ke(t.imageSizes)+'"]')):n+='[href="'+Ke(e)+'"]';var u=n;switch(l){case"style":u=Aa(e);break;case"script":u=Da(e)}tl.has(u)||(e=k({rel:"preload",href:l==="image"&&t&&t.imageSrcSet?void 0:e,as:l},t),tl.set(u,e),a.querySelector(n)!==null||l==="style"&&a.querySelector(vn(u))||l==="script"&&a.querySelector(bn(u))||(l=a.createElement("link"),Ee(l,"link",e),Se(l),a.head.appendChild(l)))}}function kh(e,l){Hl.m(e,l);var t=xa;if(t&&e){var a=l&&typeof l.as=="string"?l.as:"script",n='link[rel="modulepreload"][as="'+Ke(a)+'"][href="'+Ke(e)+'"]',u=n;switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":u=Da(e)}if(!tl.has(u)&&(e=k({rel:"modulepreload",href:e},l),tl.set(u,e),t.querySelector(n)===null)){switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(t.querySelector(bn(u)))return}a=t.createElement("link"),Ee(a,"link",e),Se(a),t.head.appendChild(a)}}}function Jh(e,l,t){Hl.S(e,l,t);var a=xa;if(a&&e){var n=Kt(a).hoistableStyles,u=Aa(e);l=l||"default";var i=n.get(u);if(!i){var c={loading:0,preload:null};if(i=a.querySelector(vn(u)))c.loading=5;else{e=k({rel:"stylesheet",href:e,"data-precedence":l},t),(t=tl.get(u))&&kc(e,t);var s=i=a.createElement("link");Se(s),Ee(s,"link",e),s._p=new Promise(function(f,b){s.onload=f,s.onerror=b}),s.addEventListener("load",function(){c.loading|=1}),s.addEventListener("error",function(){c.loading|=2}),c.loading|=4,_u(i,l,a)}i={type:"stylesheet",instance:i,count:1,state:c},n.set(u,i)}}}function Fh(e,l){Hl.X(e,l);var t=xa;if(t&&e){var a=Kt(t).hoistableScripts,n=Da(e),u=a.get(n);u||(u=t.querySelector(bn(n)),u||(e=k({src:e,async:!0},l),(l=tl.get(n))&&Jc(e,l),u=t.createElement("script"),Se(u),Ee(u,"link",e),t.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function $h(e,l){Hl.M(e,l);var t=xa;if(t&&e){var a=Kt(t).hoistableScripts,n=Da(e),u=a.get(n);u||(u=t.querySelector(bn(n)),u||(e=k({src:e,async:!0,type:"module"},l),(l=tl.get(n))&&Jc(e,l),u=t.createElement("script"),Se(u),Ee(u,"link",e),t.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function Of(e,l,t,a){var n=(n=Gl.current)?Uu(n):null;if(!n)throw Error(d(446));switch(e){case"meta":case"title":return null;case"style":return typeof t.precedence=="string"&&typeof t.href=="string"?(l=Aa(t.href),t=Kt(n).hoistableStyles,a=t.get(l),a||(a={type:"style",instance:null,count:0,state:null},t.set(l,a)),a):{type:"void",instance:null,count:0,state:null};case"link":if(t.rel==="stylesheet"&&typeof t.href=="string"&&typeof t.precedence=="string"){e=Aa(t.href);var u=Kt(n).hoistableStyles,i=u.get(e);if(i||(n=n.ownerDocument||n,i={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},u.set(e,i),(u=n.querySelector(vn(e)))&&!u._p&&(i.instance=u,i.state.loading=5),tl.has(e)||(t={rel:"preload",as:"style",href:t.href,crossOrigin:t.crossOrigin,integrity:t.integrity,media:t.media,hrefLang:t.hrefLang,referrerPolicy:t.referrerPolicy},tl.set(e,t),u||Wh(n,e,t,i.state))),l&&a===null)throw Error(d(528,""));return i}if(l&&a!==null)throw Error(d(529,""));return null;case"script":return l=t.async,t=t.src,typeof t=="string"&&l&&typeof l!="function"&&typeof l!="symbol"?(l=Da(t),t=Kt(n).hoistableScripts,a=t.get(l),a||(a={type:"script",instance:null,count:0,state:null},t.set(l,a)),a):{type:"void",instance:null,count:0,state:null};default:throw Error(d(444,e))}}function Aa(e){return'href="'+Ke(e)+'"'}function vn(e){return'link[rel="stylesheet"]['+e+"]"}function jf(e){return k({},e,{"data-precedence":e.precedence,precedence:null})}function Wh(e,l,t,a){e.querySelector('link[rel="preload"][as="style"]['+l+"]")?a.loading=1:(l=e.createElement("link"),a.preload=l,l.addEventListener("load",function(){return a.loading|=1}),l.addEventListener("error",function(){return a.loading|=2}),Ee(l,"link",t),Se(l),e.head.appendChild(l))}function Da(e){return'[src="'+Ke(e)+'"]'}function bn(e){return"script[async]"+e}function Rf(e,l,t){if(l.count++,l.instance===null)switch(l.type){case"style":var a=e.querySelector('style[data-href~="'+Ke(t.href)+'"]');if(a)return l.instance=a,Se(a),a;var n=k({},t,{"data-href":t.href,"data-precedence":t.precedence,href:null,precedence:null});return a=(e.ownerDocument||e).createElement("style"),Se(a),Ee(a,"style",n),_u(a,t.precedence,e),l.instance=a;case"stylesheet":n=Aa(t.href);var u=e.querySelector(vn(n));if(u)return l.state.loading|=4,l.instance=u,Se(u),u;a=jf(t),(n=tl.get(n))&&kc(a,n),u=(e.ownerDocument||e).createElement("link"),Se(u);var i=u;return i._p=new Promise(function(c,s){i.onload=c,i.onerror=s}),Ee(u,"link",a),l.state.loading|=4,_u(u,t.precedence,e),l.instance=u;case"script":return u=Da(t.src),(n=e.querySelector(bn(u)))?(l.instance=n,Se(n),n):(a=t,(n=tl.get(u))&&(a=k({},t),Jc(a,n)),e=e.ownerDocument||e,n=e.createElement("script"),Se(n),Ee(n,"link",a),e.head.appendChild(n),l.instance=n);case"void":return null;default:throw Error(d(443,l.type))}else l.type==="stylesheet"&&!(l.state.loading&4)&&(a=l.instance,l.state.loading|=4,_u(a,t.precedence,e));return l.instance}function _u(e,l,t){for(var a=t.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),n=a.length?a[a.length-1]:null,u=n,i=0;i title"):null)}function Ph(e,l,t){if(t===1||l.itemProp!=null)return!1;switch(e){case"meta":case"title":return!0;case"style":if(typeof l.precedence!="string"||typeof l.href!="string"||l.href==="")break;return!0;case"link":if(typeof l.rel!="string"||typeof l.href!="string"||l.href===""||l.onLoad||l.onError)break;switch(l.rel){case"stylesheet":return e=l.disabled,typeof l.precedence=="string"&&e==null;default:return!0}case"script":if(l.async&&typeof l.async!="function"&&typeof l.async!="symbol"&&!l.onLoad&&!l.onError&&l.src&&typeof l.src=="string")return!0}return!1}function Hf(e){return!(e.type==="stylesheet"&&!(e.state.loading&3))}var Sn=null;function Ih(){}function eg(e,l,t){if(Sn===null)throw Error(d(475));var a=Sn;if(l.type==="stylesheet"&&(typeof t.media!="string"||matchMedia(t.media).matches!==!1)&&!(l.state.loading&4)){if(l.instance===null){var n=Aa(t.href),u=e.querySelector(vn(n));if(u){e=u._p,e!==null&&typeof e=="object"&&typeof e.then=="function"&&(a.count++,a=Lu.bind(a),e.then(a,a)),l.state.loading|=4,l.instance=u,Se(u);return}u=e.ownerDocument||e,t=jf(t),(n=tl.get(n))&&kc(t,n),u=u.createElement("link"),Se(u);var i=u;i._p=new Promise(function(c,s){i.onload=c,i.onerror=s}),Ee(u,"link",t),l.instance=u}a.stylesheets===null&&(a.stylesheets=new Map),a.stylesheets.set(l,e),(e=l.state.preload)&&!(l.state.loading&3)&&(a.count++,l=Lu.bind(a),e.addEventListener("load",l),e.addEventListener("error",l))}}function lg(){if(Sn===null)throw Error(d(475));var e=Sn;return e.stylesheets&&e.count===0&&Fc(e,e.stylesheets),0"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(g)}catch(v){console.error(v)}}return g(),ts.exports=lp(),ts.exports}var ap=tp();const np={visibleTabs:{},setTabVisibility:()=>{},isTabVisible:()=>!1},pd=E.createContext(np),up=({children:g})=>{const v=we.use.currentTab(),[x,d]=E.useState(()=>({documents:!0,"knowledge-graph":!0,retrieval:!0,api:!0}));E.useEffect(()=>{d(j=>({...j,documents:!0,"knowledge-graph":!0,retrieval:!0,api:!0}))},[v]);const N=E.useMemo(()=>({visibleTabs:x,setTabVisibility:(j,H)=>{d($=>({...$,[j]:H}))},isTabVisible:j=>!!x[j]}),[x]);return o.jsx(pd.Provider,{value:N,children:g})};var yd="AlertDialog",[ip,Yy]=hg(yd,[td]),ql=td(),vd=g=>{const{__scopeAlertDialog:v,...x}=g,d=ql(v);return o.jsx(Sg,{...d,...x,modal:!0})};vd.displayName=yd;var cp="AlertDialogTrigger",sp=E.forwardRef((g,v)=>{const{__scopeAlertDialog:x,...d}=g,N=ql(x);return o.jsx(Tg,{...N,...d,ref:v})});sp.displayName=cp;var op="AlertDialogPortal",bd=g=>{const{__scopeAlertDialog:v,...x}=g,d=ql(v);return o.jsx(dg,{...d,...x})};bd.displayName=op;var rp="AlertDialogOverlay",Sd=E.forwardRef((g,v)=>{const{__scopeAlertDialog:x,...d}=g,N=ql(x);return o.jsx(fg,{...N,...d,ref:v})});Sd.displayName=rp;var Na="AlertDialogContent",[fp,dp]=ip(Na),Td=E.forwardRef((g,v)=>{const{__scopeAlertDialog:x,children:d,...N}=g,j=ql(x),H=E.useRef(null),$=ad(v,H),Y=E.useRef(null);return o.jsx(mg,{contentName:Na,titleName:xd,docsSlug:"alert-dialog",children:o.jsx(fp,{scope:x,cancelRef:Y,children:o.jsxs(gg,{role:"alertdialog",...j,...N,ref:$,onOpenAutoFocus:pg(N.onOpenAutoFocus,W=>{var he;W.preventDefault(),(he=Y.current)==null||he.focus({preventScroll:!0})}),onPointerDownOutside:W=>W.preventDefault(),onInteractOutside:W=>W.preventDefault(),children:[o.jsx(yg,{children:d}),o.jsx(hp,{contentRef:H})]})})})});Td.displayName=Na;var xd="AlertDialogTitle",Ad=E.forwardRef((g,v)=>{const{__scopeAlertDialog:x,...d}=g,N=ql(x);return o.jsx(vg,{...N,...d,ref:v})});Ad.displayName=xd;var Dd="AlertDialogDescription",Nd=E.forwardRef((g,v)=>{const{__scopeAlertDialog:x,...d}=g,N=ql(x);return o.jsx(bg,{...N,...d,ref:v})});Nd.displayName=Dd;var mp="AlertDialogAction",Ed=E.forwardRef((g,v)=>{const{__scopeAlertDialog:x,...d}=g,N=ql(x);return o.jsx(nd,{...N,...d,ref:v})});Ed.displayName=mp;var Md="AlertDialogCancel",zd=E.forwardRef((g,v)=>{const{__scopeAlertDialog:x,...d}=g,{cancelRef:N}=dp(Md,x),j=ql(x),H=ad(v,N);return o.jsx(nd,{...j,...d,ref:H})});zd.displayName=Md;var hp=({contentRef:g})=>{const v=`\`${Na}\` requires a description for the component to be accessible for screen reader users. You can add a description to the \`${Na}\` by passing a \`${Dd}\` component as a child, which also benefits sighted users by adding visible context to the dialog. Alternatively, you can use your own component as a description by assigning it an \`id\` and passing the same value to the \`aria-describedby\` prop in \`${Na}\`. If the description is confusing or duplicative for sighted users, you can use the \`@radix-ui/react-visually-hidden\` primitive as a wrapper around your description component. -For more information, see https://radix-ui.com/primitives/docs/components/alert-dialog`;return E.useEffect(()=>{var d;document.getElementById((d=g.current)==null?void 0:d.getAttribute("aria-describedby"))||console.warn(b)},[b,g]),null},gp=vd,pp=bd,Cd=Sd,Od=Td,jd=Ed,Rd=zd,Ud=Ad,_d=Nd;const yp=gp,vp=pp,Hd=E.forwardRef(({className:g,...b},x)=>o.jsx(Cd,{className:Qe("data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",g),...b,ref:x}));Hd.displayName=Cd.displayName;const Ld=E.forwardRef(({className:g,...b},x)=>o.jsxs(vp,{children:[o.jsx(Hd,{}),o.jsx(Od,{ref:x,className:Qe("bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-top-[48%] fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg",g),...b})]}));Ld.displayName=Od.displayName;const Bd=({className:g,...b})=>o.jsx("div",{className:Qe("flex flex-col space-y-2 text-center sm:text-left",g),...b});Bd.displayName="AlertDialogHeader";const qd=E.forwardRef(({className:g,...b},x)=>o.jsx(Ud,{ref:x,className:Qe("text-lg font-semibold",g),...b}));qd.displayName=Ud.displayName;const Gd=E.forwardRef(({className:g,...b},x)=>o.jsx(_d,{ref:x,className:Qe("text-muted-foreground text-sm",g),...b}));Gd.displayName=_d.displayName;const bp=E.forwardRef(({className:g,...b},x)=>o.jsx(jd,{ref:x,className:Qe(od(),g),...b}));bp.displayName=jd.displayName;const Sp=E.forwardRef(({className:g,...b},x)=>o.jsx(Rd,{ref:x,className:Qe(od({variant:"outline"}),"mt-2 sm:mt-0",g),...b}));Sp.displayName=Rd.displayName;const Tp=({open:g,onOpenChange:b})=>{const{t:x}=Bl(),d=Ve.use.apiKey(),[N,j]=E.useState(""),H=Gt.use.message();E.useEffect(()=>{j(d||"")},[d,g]),E.useEffect(()=>{H&&(H.includes(rd)||H.includes(fd))&&b(!0)},[H,b]);const $=E.useCallback(()=>{Ve.setState({apiKey:N||null}),b(!1)},[N,b]),Y=E.useCallback(W=>{j(W.target.value)},[j]);return o.jsx(yp,{open:g,onOpenChange:b,children:o.jsxs(Ld,{children:[o.jsxs(Bd,{children:[o.jsx(qd,{children:x("apiKeyAlert.title")}),o.jsx(Gd,{children:x("apiKeyAlert.description")})]}),o.jsxs("div",{className:"flex flex-col gap-4",children:[o.jsxs("form",{className:"flex gap-2",onSubmit:W=>W.preventDefault(),children:[o.jsx(us,{type:"password",value:N,onChange:Y,placeholder:x("apiKeyAlert.placeholder"),className:"max-h-full w-full min-w-0",autoComplete:"off"}),o.jsx(Cn,{onClick:$,variant:"outline",size:"sm",children:x("apiKeyAlert.save")})]}),H&&o.jsx("div",{className:"text-sm text-red-500",children:H})]})]})})},xp=({status:g})=>{const{t:b}=Bl();return g?o.jsxs("div",{className:"min-w-[300px] space-y-2 text-xs",children:[o.jsxs("div",{className:"space-y-1",children:[o.jsx("h4",{className:"font-medium",children:b("graphPanel.statusCard.storageInfo")}),o.jsxs("div",{className:"text-foreground grid grid-cols-[120px_1fr] gap-1",children:[o.jsxs("span",{children:[b("graphPanel.statusCard.workingDirectory"),":"]}),o.jsx("span",{className:"truncate",children:g.working_directory}),o.jsxs("span",{children:[b("graphPanel.statusCard.inputDirectory"),":"]}),o.jsx("span",{className:"truncate",children:g.input_directory})]})]}),o.jsxs("div",{className:"space-y-1",children:[o.jsx("h4",{className:"font-medium",children:b("graphPanel.statusCard.llmConfig")}),o.jsxs("div",{className:"text-foreground grid grid-cols-[120px_1fr] gap-1",children:[o.jsxs("span",{children:[b("graphPanel.statusCard.llmBinding"),":"]}),o.jsx("span",{children:g.configuration.llm_binding}),o.jsxs("span",{children:[b("graphPanel.statusCard.llmBindingHost"),":"]}),o.jsx("span",{children:g.configuration.llm_binding_host}),o.jsxs("span",{children:[b("graphPanel.statusCard.llmModel"),":"]}),o.jsx("span",{children:g.configuration.llm_model}),o.jsxs("span",{children:[b("graphPanel.statusCard.maxTokens"),":"]}),o.jsx("span",{children:g.configuration.max_tokens})]})]}),o.jsxs("div",{className:"space-y-1",children:[o.jsx("h4",{className:"font-medium",children:b("graphPanel.statusCard.embeddingConfig")}),o.jsxs("div",{className:"text-foreground grid grid-cols-[120px_1fr] gap-1",children:[o.jsxs("span",{children:[b("graphPanel.statusCard.embeddingBinding"),":"]}),o.jsx("span",{children:g.configuration.embedding_binding}),o.jsxs("span",{children:[b("graphPanel.statusCard.embeddingBindingHost"),":"]}),o.jsx("span",{children:g.configuration.embedding_binding_host}),o.jsxs("span",{children:[b("graphPanel.statusCard.embeddingModel"),":"]}),o.jsx("span",{children:g.configuration.embedding_model})]})]}),o.jsxs("div",{className:"space-y-1",children:[o.jsx("h4",{className:"font-medium",children:b("graphPanel.statusCard.storageConfig")}),o.jsxs("div",{className:"text-foreground grid grid-cols-[120px_1fr] gap-1",children:[o.jsxs("span",{children:[b("graphPanel.statusCard.kvStorage"),":"]}),o.jsx("span",{children:g.configuration.kv_storage}),o.jsxs("span",{children:[b("graphPanel.statusCard.docStatusStorage"),":"]}),o.jsx("span",{children:g.configuration.doc_status_storage}),o.jsxs("span",{children:[b("graphPanel.statusCard.graphStorage"),":"]}),o.jsx("span",{children:g.configuration.graph_storage}),o.jsxs("span",{children:[b("graphPanel.statusCard.vectorStorage"),":"]}),o.jsx("span",{children:g.configuration.vector_storage})]})]})]}):o.jsx("div",{className:"text-foreground text-xs",children:b("graphPanel.statusCard.unavailable")})},Ap=({open:g,onOpenChange:b,status:x})=>{const{t:d}=Bl();return o.jsx(Mg,{open:g,onOpenChange:b,children:o.jsxs(zg,{className:"sm:max-w-[500px]",children:[o.jsxs(Cg,{children:[o.jsx(Og,{children:d("graphPanel.statusDialog.title")}),o.jsx(jg,{children:d("graphPanel.statusDialog.description")})]}),o.jsx(xp,{status:x})]})})},Dp=()=>{const{t:g}=Bl(),b=Gt.use.health(),x=Gt.use.lastCheckTime(),d=Gt.use.status(),[N,j]=E.useState(!1),[H,$]=E.useState(!1);return E.useEffect(()=>{j(!0);const Y=setTimeout(()=>j(!1),300);return()=>clearTimeout(Y)},[x]),o.jsxs("div",{className:"fixed right-4 bottom-4 flex items-center gap-2 opacity-80 select-none",children:[o.jsxs("div",{className:"flex cursor-pointer items-center gap-2",onClick:()=>$(!0),children:[o.jsx("div",{className:Qe("h-3 w-3 rounded-full transition-all duration-300","shadow-[0_0_8px_rgba(0,0,0,0.2)]",b?"bg-green-500":"bg-red-500",N&&"scale-125",N&&b&&"shadow-[0_0_12px_rgba(34,197,94,0.4)]",N&&!b&&"shadow-[0_0_12px_rgba(239,68,68,0.4)]")}),o.jsx("span",{className:"text-muted-foreground text-xs",children:g(b?"graphPanel.statusIndicator.connected":"graphPanel.statusIndicator.disconnected")})]}),o.jsx(Ap,{open:H,onOpenChange:$,status:d})]})};function Yd({className:g}){const[b,x]=E.useState(!1),{t:d}=Bl(),N=Ve.use.language(),j=Ve.use.setLanguage(),H=Ve.use.theme(),$=Ve.use.setTheme(),Y=E.useCallback(he=>{j(he)},[j]),W=E.useCallback(he=>{$(he)},[$]);return o.jsxs(Rg,{open:b,onOpenChange:x,children:[o.jsx(Ug,{asChild:!0,children:o.jsx(Cn,{variant:"ghost",size:"icon",className:Qe("h-9 w-9",g),children:o.jsx(_g,{className:"h-5 w-5"})})}),o.jsx(Hg,{side:"bottom",align:"end",className:"w-56",children:o.jsxs("div",{className:"flex flex-col gap-4",children:[o.jsxs("div",{className:"flex flex-col gap-2",children:[o.jsx("label",{className:"text-sm font-medium",children:d("settings.language")}),o.jsxs(kf,{value:N,onValueChange:Y,children:[o.jsx(Ff,{children:o.jsx($f,{})}),o.jsxs(Wf,{children:[o.jsx(ot,{value:"en",children:"English"}),o.jsx(ot,{value:"zh",children:"中文"}),o.jsx(ot,{value:"fr",children:"Français"}),o.jsx(ot,{value:"ar",children:"العربية"}),o.jsx(ot,{value:"zh_TW",children:"繁體中文"})]})]})]}),o.jsxs("div",{className:"flex flex-col gap-2",children:[o.jsx("label",{className:"text-sm font-medium",children:d("settings.theme")}),o.jsxs(kf,{value:H,onValueChange:W,children:[o.jsx(Ff,{children:o.jsx($f,{})}),o.jsxs(Wf,{children:[o.jsx(ot,{value:"light",children:d("settings.light")}),o.jsx(ot,{value:"dark",children:d("settings.dark")}),o.jsx(ot,{value:"system",children:d("settings.system")})]})]})]})]})})]})}const Np=xg,Xd=E.forwardRef(({className:g,...b},x)=>o.jsx(ud,{ref:x,className:Qe("bg-muted text-muted-foreground inline-flex h-10 items-center justify-center rounded-md p-1",g),...b}));Xd.displayName=ud.displayName;const Vd=E.forwardRef(({className:g,...b},x)=>o.jsx(id,{ref:x,className:Qe("ring-offset-background focus-visible:ring-ring data-[state=active]:bg-background data-[state=active]:text-foreground inline-flex items-center justify-center rounded-sm px-3 py-1.5 text-sm font-medium whitespace-nowrap transition-all focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm",g),...b}));Vd.displayName=id.displayName;const zn=E.forwardRef(({className:g,...b},x)=>o.jsx(cd,{ref:x,className:Qe("ring-offset-background focus-visible:ring-ring focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none","data-[state=inactive]:invisible data-[state=active]:visible","h-full w-full",g),forceMount:!0,...b}));zn.displayName=cd.displayName;function Zu({value:g,currentTab:b,children:x}){return o.jsx(Vd,{value:g,className:Qe("cursor-pointer px-2 py-1 transition-all",b===g?"!bg-emerald-400 !text-zinc-50":"hover:bg-background/60"),children:x})}function Ep(){const g=Ve.use.currentTab(),{t:b}=Bl();return o.jsx("div",{className:"flex h-8 self-center",children:o.jsxs(Xd,{className:"h-full gap-2",children:[o.jsx(Zu,{value:"documents",currentTab:g,children:b("header.documents")}),o.jsx(Zu,{value:"knowledge-graph",currentTab:g,children:b("header.knowledgeGraph")}),o.jsx(Zu,{value:"retrieval",currentTab:g,children:b("header.retrieval")}),o.jsx(Zu,{value:"api",currentTab:g,children:b("header.api")})]})})}function Mp(){const{t:g}=Bl(),{isGuestMode:b,coreVersion:x,apiVersion:d,username:N,webuiTitle:j,webuiDescription:H}=Ll(),$=x&&d?`${x}/${d}`:null,Y=()=>{md.navigateToLogin()};return o.jsxs("header",{className:"border-border/40 bg-background/95 supports-[backdrop-filter]:bg-background/60 sticky top-0 z-50 flex h-10 w-full border-b px-4 backdrop-blur",children:[o.jsxs("div",{className:"min-w-[200px] w-auto flex items-center",children:[o.jsxs("a",{href:dd,className:"flex items-center gap-2",children:[o.jsx(ss,{className:"size-4 text-emerald-400","aria-hidden":"true"}),o.jsx("span",{className:"font-bold md:inline-block",children:is.name})]}),j&&o.jsxs("div",{className:"flex items-center",children:[o.jsx("span",{className:"mx-1 text-xs text-gray-500 dark:text-gray-400",children:"|"}),o.jsx(Lg,{children:o.jsxs(Bg,{children:[o.jsx(qg,{asChild:!0,children:o.jsx("span",{className:"font-medium text-sm cursor-default",children:j})}),H&&o.jsx(Gg,{side:"bottom",children:H})]})})]})]}),o.jsxs("div",{className:"flex h-10 flex-1 items-center justify-center",children:[o.jsx(Ep,{}),b&&o.jsx("div",{className:"ml-2 self-center px-2 py-1 text-xs bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-200 rounded-md",children:g("login.guestMode","Guest Mode")})]}),o.jsx("nav",{className:"w-[200px] flex items-center justify-end",children:o.jsxs("div",{className:"flex items-center gap-2",children:[$&&o.jsxs("span",{className:"text-xs text-gray-500 dark:text-gray-400 mr-1",children:["v",$]}),o.jsx(Cn,{variant:"ghost",size:"icon",side:"bottom",tooltip:g("header.projectRepository"),children:o.jsx("a",{href:is.github,target:"_blank",rel:"noopener noreferrer",children:o.jsx(Yg,{className:"size-4","aria-hidden":"true"})})}),o.jsx(Yd,{}),!b&&o.jsx(Cn,{variant:"ghost",size:"icon",side:"bottom",tooltip:`${g("header.logout")} (${N})`,onClick:Y,children:o.jsx(Xg,{className:"size-4","aria-hidden":"true"})})]})})]})}const zp=()=>{const g=E.useContext(pd);if(!g)throw new Error("useTabVisibility must be used within a TabVisibilityProvider");return g};function Cp(){const{t:g}=Bl(),{isTabVisible:b}=zp(),x=b("api"),[d,N]=E.useState(!1);return E.useEffect(()=>{d||N(!0)},[d]),o.jsx("div",{className:`size-full ${x?"":"hidden"}`,children:d?o.jsx("iframe",{src:Vg+"/docs",className:"size-full w-full h-full",style:{width:"100%",height:"100%",border:"none"}},"api-docs-iframe"):o.jsx("div",{className:"flex h-full w-full items-center justify-center bg-background",children:o.jsxs("div",{className:"text-center",children:[o.jsx("div",{className:"mb-2 h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent"}),o.jsx("p",{children:g("apiSite.loading")})]})})})}function Op(){const g=Gt.use.message(),b=Ve.use.enableHealthCheck(),x=Ve.use.currentTab(),[d,N]=E.useState(!1),[j,H]=E.useState(!0),$=E.useRef(!1),Y=E.useRef(!1),W=E.useCallback(V=>{N(V),V||Gt.getState().clear()},[]),he=E.useRef(!0);E.useEffect(()=>{he.current=!0;const V=()=>{he.current=!1};return window.addEventListener("beforeunload",V),()=>{he.current=!1,window.removeEventListener("beforeunload",V)}},[]),E.useEffect(()=>{if(!b||d)return;const V=async()=>{try{he.current&&await Gt.getState().check()}catch(le){console.error("Health check error:",le)}};Y.current||(Y.current=!0,V());const pe=setInterval(V,Qg*1e3);return()=>clearInterval(pe)},[b,d]),E.useEffect(()=>{(async()=>{if($.current)return;if($.current=!0,sessionStorage.getItem("VERSION_CHECKED_FROM_LOGIN")==="true"){H(!1);return}try{H(!0);const le=localStorage.getItem("LIGHTRAG-API-TOKEN"),C=await gd();if(!C.auth_configured&&C.access_token)Ll.getState().login(C.access_token,!0,C.core_version,C.api_version,C.webui_title||null,C.webui_description||null);else if(le&&(C.core_version||C.api_version||C.webui_title||C.webui_description)){const pl=C.auth_mode==="disabled"||Ll.getState().isGuestMode;Ll.getState().login(le,pl,C.core_version,C.api_version,C.webui_title||null,C.webui_description||null)}sessionStorage.setItem("VERSION_CHECKED_FROM_LOGIN","true")}catch(le){console.error("Failed to get version info:",le)}finally{H(!1)}})()},[]);const ge=E.useCallback(V=>Ve.getState().setCurrentTab(V),[]);return E.useEffect(()=>{g&&(g.includes(rd)||g.includes(fd))&&N(!0)},[g]),o.jsx(hd,{children:o.jsx(up,{children:j?o.jsxs("div",{className:"flex h-screen w-screen flex-col",children:[o.jsxs("header",{className:"border-border/40 bg-background/95 supports-[backdrop-filter]:bg-background/60 sticky top-0 z-50 flex h-10 w-full border-b px-4 backdrop-blur",children:[o.jsx("div",{className:"min-w-[200px] w-auto flex items-center",children:o.jsxs("a",{href:dd,className:"flex items-center gap-2",children:[o.jsx(ss,{className:"size-4 text-emerald-400","aria-hidden":"true"}),o.jsx("span",{className:"font-bold md:inline-block",children:is.name})]})}),o.jsx("div",{className:"flex h-10 flex-1 items-center justify-center"}),o.jsx("nav",{className:"w-[200px] flex items-center justify-end"})]}),o.jsx("div",{className:"flex flex-1 items-center justify-center",children:o.jsxs("div",{className:"text-center",children:[o.jsx("div",{className:"mb-2 h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent"}),o.jsx("p",{children:"Initializing..."})]})})]}):o.jsxs("main",{className:"flex h-screen w-screen overflow-hidden",children:[o.jsxs(Np,{defaultValue:x,className:"!m-0 flex grow flex-col !p-0 overflow-hidden",onValueChange:ge,children:[o.jsx(Mp,{}),o.jsxs("div",{className:"relative grow",children:[o.jsx(zn,{value:"documents",className:"absolute top-0 right-0 bottom-0 left-0 overflow-auto",children:o.jsx(Pg,{})}),o.jsx(zn,{value:"knowledge-graph",className:"absolute top-0 right-0 bottom-0 left-0 overflow-hidden",children:o.jsx(wg,{})}),o.jsx(zn,{value:"retrieval",className:"absolute top-0 right-0 bottom-0 left-0 overflow-hidden",children:o.jsx(Wg,{})}),o.jsx(zn,{value:"api",className:"absolute top-0 right-0 bottom-0 left-0 overflow-hidden",children:o.jsx(Cp,{})})]})]}),b&&o.jsx(Dp,{}),o.jsx(Tp,{open:d,onOpenChange:W})]})})})}const jp=()=>{const g=sd(),{login:b,isAuthenticated:x}=Ll(),{t:d}=Bl(),[N,j]=E.useState(!1),[H,$]=E.useState(""),[Y,W]=E.useState(""),[he,ge]=E.useState(!0),V=E.useRef(!1);if(E.useEffect(()=>{console.log("LoginPage mounted")},[]),E.useEffect(()=>((async()=>{if(!V.current){V.current=!0;try{if(x){g("/");return}const C=await gd();if((C.core_version||C.api_version)&&sessionStorage.setItem("VERSION_CHECKED_FROM_LOGIN","true"),!C.auth_configured&&C.access_token){b(C.access_token,!0,C.core_version,C.api_version,C.webui_title||null,C.webui_description||null),C.message&&En.info(C.message),g("/");return}ge(!1)}catch(C){console.error("Failed to check auth configuration:",C),ge(!1)}}})(),()=>{}),[x,b,g]),he)return null;const pe=async le=>{if(le.preventDefault(),!H||!Y){En.error(d("login.errorEmptyFields"));return}try{j(!0);const C=await kg(H,Y);localStorage.getItem("LIGHTRAG-PREVIOUS-USER")===H?console.log("Same user logging in, preserving chat history"):(console.log("Different user logging in, clearing chat history"),Ve.getState().setRetrievalHistory([])),localStorage.setItem("LIGHTRAG-PREVIOUS-USER",H);const je=C.auth_mode==="disabled";b(C.access_token,je,C.core_version,C.api_version,C.webui_title||null,C.webui_description||null),(C.core_version||C.api_version)&&sessionStorage.setItem("VERSION_CHECKED_FROM_LOGIN","true"),je?En.info(C.message||d("login.authDisabled","Authentication is disabled. Using guest access.")):En.success(d("login.successMessage")),g("/")}catch(C){console.error("Login failed...",C),En.error(d("login.errorInvalidCredentials")),Ll.getState().logout(),localStorage.removeItem("LIGHTRAG-API-TOKEN")}finally{j(!1)}};return o.jsxs("div",{className:"flex h-screen w-screen items-center justify-center bg-gradient-to-br from-emerald-50 to-teal-100 dark:from-gray-900 dark:to-gray-800",children:[o.jsx("div",{className:"absolute top-4 right-4 flex items-center gap-2",children:o.jsx(Yd,{className:"bg-white/30 dark:bg-gray-800/30 backdrop-blur-sm rounded-md"})}),o.jsxs(Zg,{className:"w-full max-w-[480px] shadow-lg mx-4",children:[o.jsx(Kg,{className:"flex items-center justify-center space-y-2 pb-8 pt-6",children:o.jsxs("div",{className:"flex flex-col items-center space-y-4",children:[o.jsxs("div",{className:"flex items-center gap-3",children:[o.jsx("img",{src:"logo.svg",alt:"LightRAG Logo",className:"h-12 w-12"}),o.jsx(ss,{className:"size-10 text-emerald-400","aria-hidden":"true"})]}),o.jsxs("div",{className:"text-center space-y-2",children:[o.jsx("h1",{className:"text-3xl font-bold tracking-tight",children:"LightRAG"}),o.jsx("p",{className:"text-muted-foreground text-sm",children:d("login.description")})]})]})}),o.jsx(Jg,{className:"px-8 pb-8",children:o.jsxs("form",{onSubmit:pe,className:"space-y-6",children:[o.jsxs("div",{className:"flex items-center gap-4",children:[o.jsx("label",{htmlFor:"username-input",className:"text-sm font-medium w-16 shrink-0",children:d("login.username")}),o.jsx(us,{id:"username-input",placeholder:d("login.usernamePlaceholder"),value:H,onChange:le=>$(le.target.value),required:!0,className:"h-11 flex-1"})]}),o.jsxs("div",{className:"flex items-center gap-4",children:[o.jsx("label",{htmlFor:"password-input",className:"text-sm font-medium w-16 shrink-0",children:d("login.password")}),o.jsx(us,{id:"password-input",type:"password",placeholder:d("login.passwordPlaceholder"),value:Y,onChange:le=>W(le.target.value),required:!0,className:"h-11 flex-1"})]}),o.jsx(Cn,{type:"submit",className:"w-full h-11 text-base font-medium mt-2",disabled:N,children:d(N?"login.loggingIn":"login.loginButton")})]})})]})]})},Rp=()=>{const[g,b]=E.useState(!0),{isAuthenticated:x}=Ll(),d=sd();return E.useEffect(()=>{md.setNavigate(d)},[d]),E.useEffect(()=>((async()=>{try{const j=localStorage.getItem("LIGHTRAG-API-TOKEN");if(j&&x){b(!1);return}j||Ll.getState().logout()}catch(j){console.error("Auth initialization error:",j),x||Ll.getState().logout()}finally{b(!1)}})(),()=>{}),[x]),E.useEffect(()=>{!g&&!x&&window.location.hash.slice(1)!=="/login"&&(console.log("Not authenticated, redirecting to login"),d("/login"))},[g,x,d]),g?null:o.jsxs(Eg,{children:[o.jsx(Jf,{path:"/login",element:o.jsx(jp,{})}),o.jsx(Jf,{path:"/*",element:x?o.jsx(Op,{}):null})]})},Up=()=>o.jsx(hd,{children:o.jsxs(Ng,{children:[o.jsx(Rp,{}),o.jsx(Fg,{position:"bottom-center",theme:"system",closeButton:!0,richColors:!0})]})}),_p={language:"Language",theme:"Theme",light:"Light",dark:"Dark",system:"System"},Hp={documents:"Documents",knowledgeGraph:"Knowledge Graph",retrieval:"Retrieval",api:"API",projectRepository:"Project Repository",logout:"Logout",themeToggle:{switchToLight:"Switch to light theme",switchToDark:"Switch to dark theme"}},Lp={description:"Please enter your account and password to log in to the system",username:"Username",usernamePlaceholder:"Please input a username",password:"Password",passwordPlaceholder:"Please input a password",loginButton:"Login",loggingIn:"Logging in...",successMessage:"Login succeeded",errorEmptyFields:"Please enter your username and password",errorInvalidCredentials:"Login failed, please check username and password",authDisabled:"Authentication is disabled. Using login free mode.",guestMode:"Login Free"},Bp={cancel:"Cancel",save:"Save",saving:"Saving...",saveFailed:"Save failed"},qp={clearDocuments:{button:"Clear",tooltip:"Clear documents",title:"Clear Documents",description:"This will remove all documents from the system",warning:"WARNING: This action will permanently delete all documents and cannot be undone!",confirm:"Do you really want to clear all documents?",confirmPrompt:"Type 'yes' to confirm this action",confirmPlaceholder:"Type yes to confirm",clearCache:"Clear LLM cache",confirmButton:"YES",success:"Documents cleared successfully",cacheCleared:"Cache cleared successfully",cacheClearFailed:`Failed to clear cache: +For more information, see https://radix-ui.com/primitives/docs/components/alert-dialog`;return E.useEffect(()=>{var d;document.getElementById((d=g.current)==null?void 0:d.getAttribute("aria-describedby"))||console.warn(v)},[v,g]),null},gp=vd,pp=bd,Cd=Sd,Od=Td,jd=Ed,Rd=zd,Ud=Ad,_d=Nd;const yp=gp,vp=pp,Hd=E.forwardRef(({className:g,...v},x)=>o.jsx(Cd,{className:Ve("data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",g),...v,ref:x}));Hd.displayName=Cd.displayName;const Ld=E.forwardRef(({className:g,...v},x)=>o.jsxs(vp,{children:[o.jsx(Hd,{}),o.jsx(Od,{ref:x,className:Ve("bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-top-[48%] fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg",g),...v})]}));Ld.displayName=Od.displayName;const Bd=({className:g,...v})=>o.jsx("div",{className:Ve("flex flex-col space-y-2 text-center sm:text-left",g),...v});Bd.displayName="AlertDialogHeader";const qd=E.forwardRef(({className:g,...v},x)=>o.jsx(Ud,{ref:x,className:Ve("text-lg font-semibold",g),...v}));qd.displayName=Ud.displayName;const Gd=E.forwardRef(({className:g,...v},x)=>o.jsx(_d,{ref:x,className:Ve("text-muted-foreground text-sm",g),...v}));Gd.displayName=_d.displayName;const bp=E.forwardRef(({className:g,...v},x)=>o.jsx(jd,{ref:x,className:Ve(od(),g),...v}));bp.displayName=jd.displayName;const Sp=E.forwardRef(({className:g,...v},x)=>o.jsx(Rd,{ref:x,className:Ve(od({variant:"outline"}),"mt-2 sm:mt-0",g),...v}));Sp.displayName=Rd.displayName;const Tp=({open:g,onOpenChange:v})=>{const{t:x}=Bl(),d=we.use.apiKey(),[N,j]=E.useState(""),H=Gt.use.message();E.useEffect(()=>{j(d||"")},[d,g]),E.useEffect(()=>{H&&(H.includes(rd)||H.includes(fd))&&v(!0)},[H,v]);const $=E.useCallback(()=>{we.setState({apiKey:N||null}),v(!1)},[N,v]),Y=E.useCallback(W=>{j(W.target.value)},[j]);return o.jsx(yp,{open:g,onOpenChange:v,children:o.jsxs(Ld,{children:[o.jsxs(Bd,{children:[o.jsx(qd,{children:x("apiKeyAlert.title")}),o.jsx(Gd,{children:x("apiKeyAlert.description")})]}),o.jsxs("div",{className:"flex flex-col gap-4",children:[o.jsxs("form",{className:"flex gap-2",onSubmit:W=>W.preventDefault(),children:[o.jsx(us,{type:"password",value:N,onChange:Y,placeholder:x("apiKeyAlert.placeholder"),className:"max-h-full w-full min-w-0",autoComplete:"off"}),o.jsx(Cn,{onClick:$,variant:"outline",size:"sm",children:x("apiKeyAlert.save")})]}),H&&o.jsx("div",{className:"text-sm text-red-500",children:H})]})]})})},xp=({status:g})=>{const{t:v}=Bl();return g?o.jsxs("div",{className:"min-w-[300px] space-y-2 text-xs",children:[o.jsxs("div",{className:"space-y-1",children:[o.jsx("h4",{className:"font-medium",children:v("graphPanel.statusCard.storageInfo")}),o.jsxs("div",{className:"text-foreground grid grid-cols-[120px_1fr] gap-1",children:[o.jsxs("span",{children:[v("graphPanel.statusCard.workingDirectory"),":"]}),o.jsx("span",{className:"truncate",children:g.working_directory}),o.jsxs("span",{children:[v("graphPanel.statusCard.inputDirectory"),":"]}),o.jsx("span",{className:"truncate",children:g.input_directory})]})]}),o.jsxs("div",{className:"space-y-1",children:[o.jsx("h4",{className:"font-medium",children:v("graphPanel.statusCard.llmConfig")}),o.jsxs("div",{className:"text-foreground grid grid-cols-[120px_1fr] gap-1",children:[o.jsxs("span",{children:[v("graphPanel.statusCard.llmBinding"),":"]}),o.jsx("span",{children:g.configuration.llm_binding}),o.jsxs("span",{children:[v("graphPanel.statusCard.llmBindingHost"),":"]}),o.jsx("span",{children:g.configuration.llm_binding_host}),o.jsxs("span",{children:[v("graphPanel.statusCard.llmModel"),":"]}),o.jsx("span",{children:g.configuration.llm_model}),o.jsxs("span",{children:[v("graphPanel.statusCard.maxTokens"),":"]}),o.jsx("span",{children:g.configuration.max_tokens})]})]}),o.jsxs("div",{className:"space-y-1",children:[o.jsx("h4",{className:"font-medium",children:v("graphPanel.statusCard.embeddingConfig")}),o.jsxs("div",{className:"text-foreground grid grid-cols-[120px_1fr] gap-1",children:[o.jsxs("span",{children:[v("graphPanel.statusCard.embeddingBinding"),":"]}),o.jsx("span",{children:g.configuration.embedding_binding}),o.jsxs("span",{children:[v("graphPanel.statusCard.embeddingBindingHost"),":"]}),o.jsx("span",{children:g.configuration.embedding_binding_host}),o.jsxs("span",{children:[v("graphPanel.statusCard.embeddingModel"),":"]}),o.jsx("span",{children:g.configuration.embedding_model})]})]}),o.jsxs("div",{className:"space-y-1",children:[o.jsx("h4",{className:"font-medium",children:v("graphPanel.statusCard.storageConfig")}),o.jsxs("div",{className:"text-foreground grid grid-cols-[120px_1fr] gap-1",children:[o.jsxs("span",{children:[v("graphPanel.statusCard.kvStorage"),":"]}),o.jsx("span",{children:g.configuration.kv_storage}),o.jsxs("span",{children:[v("graphPanel.statusCard.docStatusStorage"),":"]}),o.jsx("span",{children:g.configuration.doc_status_storage}),o.jsxs("span",{children:[v("graphPanel.statusCard.graphStorage"),":"]}),o.jsx("span",{children:g.configuration.graph_storage}),o.jsxs("span",{children:[v("graphPanel.statusCard.vectorStorage"),":"]}),o.jsx("span",{children:g.configuration.vector_storage}),o.jsxs("span",{children:[v("graphPanel.statusCard.workspace"),":"]}),o.jsx("span",{children:g.configuration.workspace||"-"}),o.jsxs("span",{children:[v("graphPanel.statusCard.maxGraphNodes"),":"]}),o.jsx("span",{children:g.configuration.max_graph_nodes||"-"})]})]})]}):o.jsx("div",{className:"text-foreground text-xs",children:v("graphPanel.statusCard.unavailable")})},Ap=({open:g,onOpenChange:v,status:x})=>{const{t:d}=Bl();return o.jsx(Mg,{open:g,onOpenChange:v,children:o.jsxs(zg,{className:"sm:max-w-[500px]",children:[o.jsxs(Cg,{children:[o.jsx(Og,{children:d("graphPanel.statusDialog.title")}),o.jsx(jg,{children:d("graphPanel.statusDialog.description")})]}),o.jsx(xp,{status:x})]})})},Dp=()=>{const{t:g}=Bl(),v=Gt.use.health(),x=Gt.use.lastCheckTime(),d=Gt.use.status(),[N,j]=E.useState(!1),[H,$]=E.useState(!1);return E.useEffect(()=>{j(!0);const Y=setTimeout(()=>j(!1),300);return()=>clearTimeout(Y)},[x]),o.jsxs("div",{className:"fixed right-4 bottom-4 flex items-center gap-2 opacity-80 select-none",children:[o.jsxs("div",{className:"flex cursor-pointer items-center gap-2",onClick:()=>$(!0),children:[o.jsx("div",{className:Ve("h-3 w-3 rounded-full transition-all duration-300","shadow-[0_0_8px_rgba(0,0,0,0.2)]",v?"bg-green-500":"bg-red-500",N&&"scale-125",N&&v&&"shadow-[0_0_12px_rgba(34,197,94,0.4)]",N&&!v&&"shadow-[0_0_12px_rgba(239,68,68,0.4)]")}),o.jsx("span",{className:"text-muted-foreground text-xs",children:g(v?"graphPanel.statusIndicator.connected":"graphPanel.statusIndicator.disconnected")})]}),o.jsx(Ap,{open:H,onOpenChange:$,status:d})]})};function Yd({className:g}){const[v,x]=E.useState(!1),{t:d}=Bl(),N=we.use.language(),j=we.use.setLanguage(),H=we.use.theme(),$=we.use.setTheme(),Y=E.useCallback(he=>{j(he)},[j]),W=E.useCallback(he=>{$(he)},[$]);return o.jsxs(Rg,{open:v,onOpenChange:x,children:[o.jsx(Ug,{asChild:!0,children:o.jsx(Cn,{variant:"ghost",size:"icon",className:Ve("h-9 w-9",g),children:o.jsx(_g,{className:"h-5 w-5"})})}),o.jsx(Hg,{side:"bottom",align:"end",className:"w-56",children:o.jsxs("div",{className:"flex flex-col gap-4",children:[o.jsxs("div",{className:"flex flex-col gap-2",children:[o.jsx("label",{className:"text-sm font-medium",children:d("settings.language")}),o.jsxs(Jf,{value:N,onValueChange:Y,children:[o.jsx(Ff,{children:o.jsx($f,{})}),o.jsxs(Wf,{children:[o.jsx(ot,{value:"en",children:"English"}),o.jsx(ot,{value:"zh",children:"中文"}),o.jsx(ot,{value:"fr",children:"Français"}),o.jsx(ot,{value:"ar",children:"العربية"}),o.jsx(ot,{value:"zh_TW",children:"繁體中文"})]})]})]}),o.jsxs("div",{className:"flex flex-col gap-2",children:[o.jsx("label",{className:"text-sm font-medium",children:d("settings.theme")}),o.jsxs(Jf,{value:H,onValueChange:W,children:[o.jsx(Ff,{children:o.jsx($f,{})}),o.jsxs(Wf,{children:[o.jsx(ot,{value:"light",children:d("settings.light")}),o.jsx(ot,{value:"dark",children:d("settings.dark")}),o.jsx(ot,{value:"system",children:d("settings.system")})]})]})]})]})})]})}const Np=xg,Xd=E.forwardRef(({className:g,...v},x)=>o.jsx(ud,{ref:x,className:Ve("bg-muted text-muted-foreground inline-flex h-10 items-center justify-center rounded-md p-1",g),...v}));Xd.displayName=ud.displayName;const wd=E.forwardRef(({className:g,...v},x)=>o.jsx(id,{ref:x,className:Ve("ring-offset-background focus-visible:ring-ring data-[state=active]:bg-background data-[state=active]:text-foreground inline-flex items-center justify-center rounded-sm px-3 py-1.5 text-sm font-medium whitespace-nowrap transition-all focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm",g),...v}));wd.displayName=id.displayName;const zn=E.forwardRef(({className:g,...v},x)=>o.jsx(cd,{ref:x,className:Ve("ring-offset-background focus-visible:ring-ring focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none","data-[state=inactive]:invisible data-[state=active]:visible","h-full w-full",g),forceMount:!0,...v}));zn.displayName=cd.displayName;function Zu({value:g,currentTab:v,children:x}){return o.jsx(wd,{value:g,className:Ve("cursor-pointer px-2 py-1 transition-all",v===g?"!bg-emerald-400 !text-zinc-50":"hover:bg-background/60"),children:x})}function Ep(){const g=we.use.currentTab(),{t:v}=Bl();return o.jsx("div",{className:"flex h-8 self-center",children:o.jsxs(Xd,{className:"h-full gap-2",children:[o.jsx(Zu,{value:"documents",currentTab:g,children:v("header.documents")}),o.jsx(Zu,{value:"knowledge-graph",currentTab:g,children:v("header.knowledgeGraph")}),o.jsx(Zu,{value:"retrieval",currentTab:g,children:v("header.retrieval")}),o.jsx(Zu,{value:"api",currentTab:g,children:v("header.api")})]})})}function Mp(){const{t:g}=Bl(),{isGuestMode:v,coreVersion:x,apiVersion:d,username:N,webuiTitle:j,webuiDescription:H}=Ll(),$=x&&d?`${x}/${d}`:null,Y=()=>{md.navigateToLogin()};return o.jsxs("header",{className:"border-border/40 bg-background/95 supports-[backdrop-filter]:bg-background/60 sticky top-0 z-50 flex h-10 w-full border-b px-4 backdrop-blur",children:[o.jsxs("div",{className:"min-w-[200px] w-auto flex items-center",children:[o.jsxs("a",{href:dd,className:"flex items-center gap-2",children:[o.jsx(ss,{className:"size-4 text-emerald-400","aria-hidden":"true"}),o.jsx("span",{className:"font-bold md:inline-block",children:is.name})]}),j&&o.jsxs("div",{className:"flex items-center",children:[o.jsx("span",{className:"mx-1 text-xs text-gray-500 dark:text-gray-400",children:"|"}),o.jsx(Lg,{children:o.jsxs(Bg,{children:[o.jsx(qg,{asChild:!0,children:o.jsx("span",{className:"font-medium text-sm cursor-default",children:j})}),H&&o.jsx(Gg,{side:"bottom",children:H})]})})]})]}),o.jsxs("div",{className:"flex h-10 flex-1 items-center justify-center",children:[o.jsx(Ep,{}),v&&o.jsx("div",{className:"ml-2 self-center px-2 py-1 text-xs bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-200 rounded-md",children:g("login.guestMode","Guest Mode")})]}),o.jsx("nav",{className:"w-[200px] flex items-center justify-end",children:o.jsxs("div",{className:"flex items-center gap-2",children:[$&&o.jsxs("span",{className:"text-xs text-gray-500 dark:text-gray-400 mr-1",children:["v",$]}),o.jsx(Cn,{variant:"ghost",size:"icon",side:"bottom",tooltip:g("header.projectRepository"),children:o.jsx("a",{href:is.github,target:"_blank",rel:"noopener noreferrer",children:o.jsx(Yg,{className:"size-4","aria-hidden":"true"})})}),o.jsx(Yd,{}),!v&&o.jsx(Cn,{variant:"ghost",size:"icon",side:"bottom",tooltip:`${g("header.logout")} (${N})`,onClick:Y,children:o.jsx(Xg,{className:"size-4","aria-hidden":"true"})})]})})]})}const zp=()=>{const g=E.useContext(pd);if(!g)throw new Error("useTabVisibility must be used within a TabVisibilityProvider");return g};function Cp(){const{t:g}=Bl(),{isTabVisible:v}=zp(),x=v("api"),[d,N]=E.useState(!1);return E.useEffect(()=>{d||N(!0)},[d]),o.jsx("div",{className:`size-full ${x?"":"hidden"}`,children:d?o.jsx("iframe",{src:wg+"/docs",className:"size-full w-full h-full",style:{width:"100%",height:"100%",border:"none"}},"api-docs-iframe"):o.jsx("div",{className:"flex h-full w-full items-center justify-center bg-background",children:o.jsxs("div",{className:"text-center",children:[o.jsx("div",{className:"mb-2 h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent"}),o.jsx("p",{children:g("apiSite.loading")})]})})})}function Op(){const g=Gt.use.message(),v=we.use.enableHealthCheck(),x=we.use.currentTab(),[d,N]=E.useState(!1),[j,H]=E.useState(!0),$=E.useRef(!1),Y=E.useRef(!1),W=E.useCallback(w=>{N(w),w||Gt.getState().clear()},[]),he=E.useRef(!0);E.useEffect(()=>{he.current=!0;const w=()=>{he.current=!1};return window.addEventListener("beforeunload",w),()=>{he.current=!1,window.removeEventListener("beforeunload",w)}},[]),E.useEffect(()=>{if(!v||d)return;const w=async()=>{try{he.current&&await Gt.getState().check()}catch(le){console.error("Health check error:",le)}};Y.current||(Y.current=!0,w());const pe=setInterval(w,Vg*1e3);return()=>clearInterval(pe)},[v,d]),E.useEffect(()=>{(async()=>{if($.current)return;if($.current=!0,sessionStorage.getItem("VERSION_CHECKED_FROM_LOGIN")==="true"){H(!1);return}try{H(!0);const le=localStorage.getItem("LIGHTRAG-API-TOKEN"),C=await gd();if(!C.auth_configured&&C.access_token)Ll.getState().login(C.access_token,!0,C.core_version,C.api_version,C.webui_title||null,C.webui_description||null);else if(le&&(C.core_version||C.api_version||C.webui_title||C.webui_description)){const pl=C.auth_mode==="disabled"||Ll.getState().isGuestMode;Ll.getState().login(le,pl,C.core_version,C.api_version,C.webui_title||null,C.webui_description||null)}sessionStorage.setItem("VERSION_CHECKED_FROM_LOGIN","true")}catch(le){console.error("Failed to get version info:",le)}finally{H(!1)}})()},[]);const ge=E.useCallback(w=>we.getState().setCurrentTab(w),[]);return E.useEffect(()=>{g&&(g.includes(rd)||g.includes(fd))&&N(!0)},[g]),o.jsx(hd,{children:o.jsx(up,{children:j?o.jsxs("div",{className:"flex h-screen w-screen flex-col",children:[o.jsxs("header",{className:"border-border/40 bg-background/95 supports-[backdrop-filter]:bg-background/60 sticky top-0 z-50 flex h-10 w-full border-b px-4 backdrop-blur",children:[o.jsx("div",{className:"min-w-[200px] w-auto flex items-center",children:o.jsxs("a",{href:dd,className:"flex items-center gap-2",children:[o.jsx(ss,{className:"size-4 text-emerald-400","aria-hidden":"true"}),o.jsx("span",{className:"font-bold md:inline-block",children:is.name})]})}),o.jsx("div",{className:"flex h-10 flex-1 items-center justify-center"}),o.jsx("nav",{className:"w-[200px] flex items-center justify-end"})]}),o.jsx("div",{className:"flex flex-1 items-center justify-center",children:o.jsxs("div",{className:"text-center",children:[o.jsx("div",{className:"mb-2 h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent"}),o.jsx("p",{children:"Initializing..."})]})})]}):o.jsxs("main",{className:"flex h-screen w-screen overflow-hidden",children:[o.jsxs(Np,{defaultValue:x,className:"!m-0 flex grow flex-col !p-0 overflow-hidden",onValueChange:ge,children:[o.jsx(Mp,{}),o.jsxs("div",{className:"relative grow",children:[o.jsx(zn,{value:"documents",className:"absolute top-0 right-0 bottom-0 left-0 overflow-auto",children:o.jsx(Pg,{})}),o.jsx(zn,{value:"knowledge-graph",className:"absolute top-0 right-0 bottom-0 left-0 overflow-hidden",children:o.jsx(Qg,{})}),o.jsx(zn,{value:"retrieval",className:"absolute top-0 right-0 bottom-0 left-0 overflow-hidden",children:o.jsx(Wg,{})}),o.jsx(zn,{value:"api",className:"absolute top-0 right-0 bottom-0 left-0 overflow-hidden",children:o.jsx(Cp,{})})]})]}),v&&o.jsx(Dp,{}),o.jsx(Tp,{open:d,onOpenChange:W})]})})})}const jp=()=>{const g=sd(),{login:v,isAuthenticated:x}=Ll(),{t:d}=Bl(),[N,j]=E.useState(!1),[H,$]=E.useState(""),[Y,W]=E.useState(""),[he,ge]=E.useState(!0),w=E.useRef(!1);if(E.useEffect(()=>{console.log("LoginPage mounted")},[]),E.useEffect(()=>((async()=>{if(!w.current){w.current=!0;try{if(x){g("/");return}const C=await gd();if((C.core_version||C.api_version)&&sessionStorage.setItem("VERSION_CHECKED_FROM_LOGIN","true"),!C.auth_configured&&C.access_token){v(C.access_token,!0,C.core_version,C.api_version,C.webui_title||null,C.webui_description||null),C.message&&En.info(C.message),g("/");return}ge(!1)}catch(C){console.error("Failed to check auth configuration:",C),ge(!1)}}})(),()=>{}),[x,v,g]),he)return null;const pe=async le=>{if(le.preventDefault(),!H||!Y){En.error(d("login.errorEmptyFields"));return}try{j(!0);const C=await Jg(H,Y);localStorage.getItem("LIGHTRAG-PREVIOUS-USER")===H?console.log("Same user logging in, preserving chat history"):(console.log("Different user logging in, clearing chat history"),we.getState().setRetrievalHistory([])),localStorage.setItem("LIGHTRAG-PREVIOUS-USER",H);const je=C.auth_mode==="disabled";v(C.access_token,je,C.core_version,C.api_version,C.webui_title||null,C.webui_description||null),(C.core_version||C.api_version)&&sessionStorage.setItem("VERSION_CHECKED_FROM_LOGIN","true"),je?En.info(C.message||d("login.authDisabled","Authentication is disabled. Using guest access.")):En.success(d("login.successMessage")),g("/")}catch(C){console.error("Login failed...",C),En.error(d("login.errorInvalidCredentials")),Ll.getState().logout(),localStorage.removeItem("LIGHTRAG-API-TOKEN")}finally{j(!1)}};return o.jsxs("div",{className:"flex h-screen w-screen items-center justify-center bg-gradient-to-br from-emerald-50 to-teal-100 dark:from-gray-900 dark:to-gray-800",children:[o.jsx("div",{className:"absolute top-4 right-4 flex items-center gap-2",children:o.jsx(Yd,{className:"bg-white/30 dark:bg-gray-800/30 backdrop-blur-sm rounded-md"})}),o.jsxs(Zg,{className:"w-full max-w-[480px] shadow-lg mx-4",children:[o.jsx(Kg,{className:"flex items-center justify-center space-y-2 pb-8 pt-6",children:o.jsxs("div",{className:"flex flex-col items-center space-y-4",children:[o.jsxs("div",{className:"flex items-center gap-3",children:[o.jsx("img",{src:"logo.svg",alt:"LightRAG Logo",className:"h-12 w-12"}),o.jsx(ss,{className:"size-10 text-emerald-400","aria-hidden":"true"})]}),o.jsxs("div",{className:"text-center space-y-2",children:[o.jsx("h1",{className:"text-3xl font-bold tracking-tight",children:"LightRAG"}),o.jsx("p",{className:"text-muted-foreground text-sm",children:d("login.description")})]})]})}),o.jsx(kg,{className:"px-8 pb-8",children:o.jsxs("form",{onSubmit:pe,className:"space-y-6",children:[o.jsxs("div",{className:"flex items-center gap-4",children:[o.jsx("label",{htmlFor:"username-input",className:"text-sm font-medium w-16 shrink-0",children:d("login.username")}),o.jsx(us,{id:"username-input",placeholder:d("login.usernamePlaceholder"),value:H,onChange:le=>$(le.target.value),required:!0,className:"h-11 flex-1"})]}),o.jsxs("div",{className:"flex items-center gap-4",children:[o.jsx("label",{htmlFor:"password-input",className:"text-sm font-medium w-16 shrink-0",children:d("login.password")}),o.jsx(us,{id:"password-input",type:"password",placeholder:d("login.passwordPlaceholder"),value:Y,onChange:le=>W(le.target.value),required:!0,className:"h-11 flex-1"})]}),o.jsx(Cn,{type:"submit",className:"w-full h-11 text-base font-medium mt-2",disabled:N,children:d(N?"login.loggingIn":"login.loginButton")})]})})]})]})},Rp=()=>{const[g,v]=E.useState(!0),{isAuthenticated:x}=Ll(),d=sd();return E.useEffect(()=>{md.setNavigate(d)},[d]),E.useEffect(()=>((async()=>{try{const j=localStorage.getItem("LIGHTRAG-API-TOKEN");if(j&&x){v(!1);return}j||Ll.getState().logout()}catch(j){console.error("Auth initialization error:",j),x||Ll.getState().logout()}finally{v(!1)}})(),()=>{}),[x]),E.useEffect(()=>{!g&&!x&&window.location.hash.slice(1)!=="/login"&&(console.log("Not authenticated, redirecting to login"),d("/login"))},[g,x,d]),g?null:o.jsxs(Eg,{children:[o.jsx(kf,{path:"/login",element:o.jsx(jp,{})}),o.jsx(kf,{path:"/*",element:x?o.jsx(Op,{}):null})]})},Up=()=>o.jsx(hd,{children:o.jsxs(Ng,{children:[o.jsx(Rp,{}),o.jsx(Fg,{position:"bottom-center",theme:"system",closeButton:!0,richColors:!0})]})}),_p={language:"Language",theme:"Theme",light:"Light",dark:"Dark",system:"System"},Hp={documents:"Documents",knowledgeGraph:"Knowledge Graph",retrieval:"Retrieval",api:"API",projectRepository:"Project Repository",logout:"Logout",themeToggle:{switchToLight:"Switch to light theme",switchToDark:"Switch to dark theme"}},Lp={description:"Please enter your account and password to log in to the system",username:"Username",usernamePlaceholder:"Please input a username",password:"Password",passwordPlaceholder:"Please input a password",loginButton:"Login",loggingIn:"Logging in...",successMessage:"Login succeeded",errorEmptyFields:"Please enter your username and password",errorInvalidCredentials:"Login failed, please check username and password",authDisabled:"Authentication is disabled. Using login free mode.",guestMode:"Login Free"},Bp={cancel:"Cancel",save:"Save",saving:"Saving...",saveFailed:"Save failed"},qp={clearDocuments:{button:"Clear",tooltip:"Clear documents",title:"Clear Documents",description:"This will remove all documents from the system",warning:"WARNING: This action will permanently delete all documents and cannot be undone!",confirm:"Do you really want to clear all documents?",confirmPrompt:"Type 'yes' to confirm this action",confirmPlaceholder:"Type yes to confirm",clearCache:"Clear LLM cache",confirmButton:"YES",success:"Documents cleared successfully",cacheCleared:"Cache cleared successfully",cacheClearFailed:`Failed to clear cache: {{error}}`,failed:`Clear Documents Failed: {{message}}`,error:`Clear Documents Failed: {{error}}`},deleteDocuments:{button:"Delete",tooltip:"Delete selected documents",title:"Delete Documents",description:"This will permanently delete the selected documents from the system",warning:"WARNING: This action will permanently delete the selected documents and cannot be undone!",confirm:"Do you really want to delete {{count}} selected document(s)?",confirmPrompt:"Type 'yes' to confirm this action",confirmPlaceholder:"Type yes to confirm",confirmButton:"YES",deleteFileOption:"Also delete uploaded files",deleteFileTooltip:"Check this option to also delete the corresponding uploaded files on the server",success:"Document deletion pipeline started successfully",failed:`Delete Documents Failed: @@ -43,7 +43,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert- {{error}}`,scanFailed:`Failed to scan documents {{error}}`,scanProgressFailed:`Failed to get scan progress {{error}}`},fileNameLabel:"File Name",showButton:"Show",hideButton:"Hide",showFileNameTooltip:"Show file name",hideFileNameTooltip:"Hide file name"},pipelineStatus:{title:"Pipeline Status",busy:"Pipeline Busy",requestPending:"Request Pending",jobName:"Job Name",startTime:"Start Time",progress:"Progress",unit:"batch",latestMessage:"Latest Message",historyMessages:"History Messages",errors:{fetchFailed:`Failed to get pipeline status -{{error}}`}}},Gp={dataIsTruncated:"Graph data is truncated to Max Nodes",statusDialog:{title:"LightRAG Server Settings",description:"View current system status and connection information"},legend:"Legend",nodeTypes:{person:"Person",category:"Category",geo:"Geographic",location:"Location",organization:"Organization",event:"Event",equipment:"Equipment",weapon:"Weapon",animal:"Animal",unknown:"Unknown",object:"Object",group:"Group",technology:"Technology"},sideBar:{settings:{settings:"Settings",healthCheck:"Health Check",showPropertyPanel:"Show Property Panel",showSearchBar:"Show Search Bar",showNodeLabel:"Show Node Label",nodeDraggable:"Node Draggable",showEdgeLabel:"Show Edge Label",hideUnselectedEdges:"Hide Unselected Edges",edgeEvents:"Edge Events",maxQueryDepth:"Max Query Depth",maxNodes:"Max Nodes",maxLayoutIterations:"Max Layout Iterations",resetToDefault:"Reset to default",edgeSizeRange:"Edge Size Range",depth:"D",max:"Max",degree:"Degree",apiKey:"API Key",enterYourAPIkey:"Enter your API key",save:"Save",refreshLayout:"Refresh Layout"},zoomControl:{zoomIn:"Zoom In",zoomOut:"Zoom Out",resetZoom:"Reset Zoom",rotateCamera:"Clockwise Rotate",rotateCameraCounterClockwise:"Counter-Clockwise Rotate"},layoutsControl:{startAnimation:"Continue layout animation",stopAnimation:"Stop layout animation",layoutGraph:"Layout Graph",layouts:{Circular:"Circular",Circlepack:"Circlepack",Random:"Random",Noverlaps:"Noverlaps","Force Directed":"Force Directed","Force Atlas":"Force Atlas"}},fullScreenControl:{fullScreen:"Full Screen",windowed:"Windowed"},legendControl:{toggleLegend:"Toggle Legend"}},statusIndicator:{connected:"Connected",disconnected:"Disconnected"},statusCard:{unavailable:"Status information unavailable",storageInfo:"Storage Info",workingDirectory:"Working Directory",inputDirectory:"Input Directory",llmConfig:"LLM Configuration",llmBinding:"LLM Binding",llmBindingHost:"LLM Binding Host",llmModel:"LLM Model",maxTokens:"Max Tokens",embeddingConfig:"Embedding Configuration",embeddingBinding:"Embedding Binding",embeddingBindingHost:"Embedding Binding Host",embeddingModel:"Embedding Model",storageConfig:"Storage Configuration",kvStorage:"KV Storage",docStatusStorage:"Doc Status Storage",graphStorage:"Graph Storage",vectorStorage:"Vector Storage"},propertiesView:{editProperty:"Edit {{property}}",editPropertyDescription:"Edit the property value in the text area below.",errors:{duplicateName:"Node name already exists",updateFailed:"Failed to update node",tryAgainLater:"Please try again later"},success:{entityUpdated:"Node updated successfully",relationUpdated:"Relation updated successfully"},node:{title:"Node",id:"ID",labels:"Labels",degree:"Degree",properties:"Properties",relationships:"Relations(within subgraph)",expandNode:"Expand Node",pruneNode:"Prune Node",deleteAllNodesError:"Refuse to delete all nodes in the graph",nodesRemoved:"{{count}} nodes removed, including orphan nodes",noNewNodes:"No expandable nodes found",propertyNames:{description:"Description",entity_id:"Name",entity_type:"Type",source_id:"SrcID",Neighbour:"Neigh",file_path:"Source",keywords:"Keys",weight:"Weight"}},edge:{title:"Relationship",id:"ID",type:"Type",source:"Source",target:"Target",properties:"Properties"}},search:{placeholder:"Search nodes...",message:"And {count} others"},graphLabels:{selectTooltip:"Select query label",noLabels:"No labels found",label:"Label",placeholder:"Search labels...",andOthers:"And {count} others",refreshTooltip:"Reload data(After file added)"},emptyGraph:"Empty(Try Reload Again)"},Yp={chatMessage:{copyTooltip:"Copy to clipboard",copyError:"Failed to copy text to clipboard"},retrieval:{startPrompt:"Start a retrieval by typing your query below",clear:"Clear",send:"Send",placeholder:"Enter your query (Support prefix: /)",error:"Error: Failed to get response",queryModeError:"Only supports the following query modes: {{modes}}",queryModePrefixInvalid:"Invalid query mode prefix. Use: / [space] your query"},querySettings:{parametersTitle:"Parameters",parametersDescription:"Configure your query parameters",queryMode:"Query Mode",queryModeTooltip:`Select the retrieval strategy: +{{error}}`}}},Gp={dataIsTruncated:"Graph data is truncated to Max Nodes",statusDialog:{title:"LightRAG Server Settings",description:"View current system status and connection information"},legend:"Legend",nodeTypes:{person:"Person",category:"Category",geo:"Geographic",location:"Location",organization:"Organization",event:"Event",equipment:"Equipment",weapon:"Weapon",animal:"Animal",unknown:"Unknown",object:"Object",group:"Group",technology:"Technology"},sideBar:{settings:{settings:"Settings",healthCheck:"Health Check",showPropertyPanel:"Show Property Panel",showSearchBar:"Show Search Bar",showNodeLabel:"Show Node Label",nodeDraggable:"Node Draggable",showEdgeLabel:"Show Edge Label",hideUnselectedEdges:"Hide Unselected Edges",edgeEvents:"Edge Events",maxQueryDepth:"Max Query Depth",maxNodes:"Max Nodes",maxLayoutIterations:"Max Layout Iterations",resetToDefault:"Reset to default",edgeSizeRange:"Edge Size Range",depth:"D",max:"Max",degree:"Degree",apiKey:"API Key",enterYourAPIkey:"Enter your API key",save:"Save",refreshLayout:"Refresh Layout"},zoomControl:{zoomIn:"Zoom In",zoomOut:"Zoom Out",resetZoom:"Reset Zoom",rotateCamera:"Clockwise Rotate",rotateCameraCounterClockwise:"Counter-Clockwise Rotate"},layoutsControl:{startAnimation:"Continue layout animation",stopAnimation:"Stop layout animation",layoutGraph:"Layout Graph",layouts:{Circular:"Circular",Circlepack:"Circlepack",Random:"Random",Noverlaps:"Noverlaps","Force Directed":"Force Directed","Force Atlas":"Force Atlas"}},fullScreenControl:{fullScreen:"Full Screen",windowed:"Windowed"},legendControl:{toggleLegend:"Toggle Legend"}},statusIndicator:{connected:"Connected",disconnected:"Disconnected"},statusCard:{unavailable:"Status information unavailable",storageInfo:"Storage Info",workingDirectory:"Working Directory",inputDirectory:"Input Directory",llmConfig:"LLM Configuration",llmBinding:"LLM Binding",llmBindingHost:"LLM Binding Host",llmModel:"LLM Model",maxTokens:"Max Tokens",embeddingConfig:"Embedding Configuration",embeddingBinding:"Embedding Binding",embeddingBindingHost:"Embedding Binding Host",embeddingModel:"Embedding Model",storageConfig:"Storage Configuration",kvStorage:"KV Storage",docStatusStorage:"Doc Status Storage",graphStorage:"Graph Storage",vectorStorage:"Vector Storage",workspace:"Workspace",maxGraphNodes:"Max Graph Nodes"},propertiesView:{editProperty:"Edit {{property}}",editPropertyDescription:"Edit the property value in the text area below.",errors:{duplicateName:"Node name already exists",updateFailed:"Failed to update node",tryAgainLater:"Please try again later"},success:{entityUpdated:"Node updated successfully",relationUpdated:"Relation updated successfully"},node:{title:"Node",id:"ID",labels:"Labels",degree:"Degree",properties:"Properties",relationships:"Relations(within subgraph)",expandNode:"Expand Node",pruneNode:"Prune Node",deleteAllNodesError:"Refuse to delete all nodes in the graph",nodesRemoved:"{{count}} nodes removed, including orphan nodes",noNewNodes:"No expandable nodes found",propertyNames:{description:"Description",entity_id:"Name",entity_type:"Type",source_id:"SrcID",Neighbour:"Neigh",file_path:"Source",keywords:"Keys",weight:"Weight"}},edge:{title:"Relationship",id:"ID",type:"Type",source:"Source",target:"Target",properties:"Properties"}},search:{placeholder:"Search nodes...",message:"And {count} others"},graphLabels:{selectTooltip:"Select query label",noLabels:"No labels found",label:"Label",placeholder:"Search labels...",andOthers:"And {count} others",refreshTooltip:"Reload data(After file added)"},emptyGraph:"Empty(Try Reload Again)"},Yp={chatMessage:{copyTooltip:"Copy to clipboard",copyError:"Failed to copy text to clipboard"},retrieval:{startPrompt:"Start a retrieval by typing your query below",clear:"Clear",send:"Send",placeholder:"Enter your query (Support prefix: /)",error:"Error: Failed to get response",queryModeError:"Only supports the following query modes: {{modes}}",queryModePrefixInvalid:"Invalid query mode prefix. Use: / [space] your query"},querySettings:{parametersTitle:"Parameters",parametersDescription:"Configure your query parameters",queryMode:"Query Mode",queryModeTooltip:`Select the retrieval strategy: • Naive: Basic search without advanced techniques • Local: Context-dependent information retrieval • Global: Utilizes global knowledge base @@ -52,7 +52,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert- • Bypass: Passes query directly to LLM without retrieval`,queryModeOptions:{naive:"Naive",local:"Local",global:"Global",hybrid:"Hybrid",mix:"Mix",bypass:"Bypass"},responseFormat:"Response Format",responseFormatTooltip:`Defines the response format. Examples: • Multiple Paragraphs • Single Paragraph -• Bullet Points`,responseFormatOptions:{multipleParagraphs:"Multiple Paragraphs",singleParagraph:"Single Paragraph",bulletPoints:"Bullet Points"},topK:"Top K Results",topKTooltip:"Number of top items to retrieve. Represents entities in 'local' mode and relationships in 'global' mode",topKPlaceholder:"Number of results",maxTokensTextUnit:"Max Tokens for Text Unit",maxTokensTextUnitTooltip:"Maximum number of tokens allowed for each retrieved text chunk",maxTokensGlobalContext:"Max Tokens for Global Context",maxTokensGlobalContextTooltip:"Maximum number of tokens allocated for relationship descriptions in global retrieval",maxTokensLocalContext:"Max Tokens for Local Context",maxTokensLocalContextTooltip:"Maximum number of tokens allocated for entity descriptions in local retrieval",historyTurns:"History Turns",historyTurnsTooltip:"Number of complete conversation turns (user-assistant pairs) to consider in the response context",historyTurnsPlaceholder:"Number of history turns",onlyNeedContext:"Only Need Context",onlyNeedContextTooltip:"If True, only returns the retrieved context without generating a response",onlyNeedPrompt:"Only Need Prompt",onlyNeedPromptTooltip:"If True, only returns the generated prompt without producing a response",streamResponse:"Stream Response",streamResponseTooltip:"If True, enables streaming output for real-time responses",userPrompt:"User Prompt",userPromptTooltip:"Provide additional response requirements to the LLM (unrelated to query content, only for output processing).",userPromptPlaceholder:"Enter custom prompt (optional)"}},Xp={loading:"Loading API Documentation..."},Vp={title:"API Key is required",description:"Please enter your API key to access the service",placeholder:"Enter your API key",save:"Save"},Qp={settings:_p,header:Hp,login:Lp,common:Bp,documentPanel:qp,graphPanel:Gp,retrievePanel:Yp,apiSite:Xp,apiKeyAlert:Vp},wp={language:"语言",theme:"主题",light:"浅色",dark:"深色",system:"系统"},Zp={documents:"文档",knowledgeGraph:"知识图谱",retrieval:"检索",api:"API",projectRepository:"项目仓库",logout:"退出登录",themeToggle:{switchToLight:"切换到浅色主题",switchToDark:"切换到深色主题"}},Kp={description:"请输入您的账号和密码登录系统",username:"用户名",usernamePlaceholder:"请输入用户名",password:"密码",passwordPlaceholder:"请输入密码",loginButton:"登录",loggingIn:"登录中...",successMessage:"登录成功",errorEmptyFields:"请输入您的用户名和密码",errorInvalidCredentials:"登录失败,请检查用户名和密码",authDisabled:"认证已禁用,使用无需登陆模式。",guestMode:"无需登陆"},Jp={cancel:"取消",save:"保存",saving:"保存中...",saveFailed:"保存失败"},kp={clearDocuments:{button:"清空",tooltip:"清空文档",title:"清空文档",description:"此操作将从系统中移除所有文档",warning:"警告:此操作将永久删除所有文档,无法恢复!",confirm:"确定要清空所有文档吗?",confirmPrompt:"请输入 yes 确认操作",confirmPlaceholder:"输入 yes 确认",clearCache:"清空LLM缓存",confirmButton:"确定",success:"文档清空成功",cacheCleared:"缓存清空成功",cacheClearFailed:`清空缓存失败: +• Bullet Points`,responseFormatOptions:{multipleParagraphs:"Multiple Paragraphs",singleParagraph:"Single Paragraph",bulletPoints:"Bullet Points"},topK:"Top K Results",topKTooltip:"Number of top items to retrieve. Represents entities in 'local' mode and relationships in 'global' mode",topKPlaceholder:"Number of results",maxTokensTextUnit:"Max Tokens for Text Unit",maxTokensTextUnitTooltip:"Maximum number of tokens allowed for each retrieved text chunk",maxTokensGlobalContext:"Max Tokens for Global Context",maxTokensGlobalContextTooltip:"Maximum number of tokens allocated for relationship descriptions in global retrieval",maxTokensLocalContext:"Max Tokens for Local Context",maxTokensLocalContextTooltip:"Maximum number of tokens allocated for entity descriptions in local retrieval",historyTurns:"History Turns",historyTurnsTooltip:"Number of complete conversation turns (user-assistant pairs) to consider in the response context",historyTurnsPlaceholder:"Number of history turns",onlyNeedContext:"Only Need Context",onlyNeedContextTooltip:"If True, only returns the retrieved context without generating a response",onlyNeedPrompt:"Only Need Prompt",onlyNeedPromptTooltip:"If True, only returns the generated prompt without producing a response",streamResponse:"Stream Response",streamResponseTooltip:"If True, enables streaming output for real-time responses",userPrompt:"User Prompt",userPromptTooltip:"Provide additional response requirements to the LLM (unrelated to query content, only for output processing).",userPromptPlaceholder:"Enter custom prompt (optional)"}},Xp={loading:"Loading API Documentation..."},wp={title:"API Key is required",description:"Please enter your API key to access the service",placeholder:"Enter your API key",save:"Save"},Vp={settings:_p,header:Hp,login:Lp,common:Bp,documentPanel:qp,graphPanel:Gp,retrievePanel:Yp,apiSite:Xp,apiKeyAlert:wp},Qp={language:"语言",theme:"主题",light:"浅色",dark:"深色",system:"系统"},Zp={documents:"文档",knowledgeGraph:"知识图谱",retrieval:"检索",api:"API",projectRepository:"项目仓库",logout:"退出登录",themeToggle:{switchToLight:"切换到浅色主题",switchToDark:"切换到深色主题"}},Kp={description:"请输入您的账号和密码登录系统",username:"用户名",usernamePlaceholder:"请输入用户名",password:"密码",passwordPlaceholder:"请输入密码",loginButton:"登录",loggingIn:"登录中...",successMessage:"登录成功",errorEmptyFields:"请输入您的用户名和密码",errorInvalidCredentials:"登录失败,请检查用户名和密码",authDisabled:"认证已禁用,使用无需登陆模式。",guestMode:"无需登陆"},kp={cancel:"取消",save:"保存",saving:"保存中...",saveFailed:"保存失败"},Jp={clearDocuments:{button:"清空",tooltip:"清空文档",title:"清空文档",description:"此操作将从系统中移除所有文档",warning:"警告:此操作将永久删除所有文档,无法恢复!",confirm:"确定要清空所有文档吗?",confirmPrompt:"请输入 yes 确认操作",confirmPlaceholder:"输入 yes 确认",clearCache:"清空LLM缓存",confirmButton:"确定",success:"文档清空成功",cacheCleared:"缓存清空成功",cacheClearFailed:`清空缓存失败: {{error}}`,failed:`清空文档失败: {{message}}`,error:`清空文档失败: {{error}}`},deleteDocuments:{button:"删除",tooltip:"删除选中的文档",title:"删除文档",description:"此操作将永久删除选中的文档",warning:"警告:此操作将永久删除选中的文档,无法恢复!",confirm:"确定要删除 {{count}} 个选中的文档吗?",confirmPrompt:"请输入 yes 确认操作",confirmPlaceholder:"输入 yes 确认",confirmButton:"确定",deleteFileOption:"同时删除上传文件",deleteFileTooltip:"选中此选项将同时删除服务器上对应的上传文件",success:"文档删除流水线启动成功",failed:`删除文档失败: @@ -67,7 +67,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert- {{error}}`,scanFailed:`扫描文档失败 {{error}}`,scanProgressFailed:`获取扫描进度失败 {{error}}`},fileNameLabel:"文件名",showButton:"显示",hideButton:"隐藏",showFileNameTooltip:"显示文件名",hideFileNameTooltip:"隐藏文件名"},pipelineStatus:{title:"流水线状态",busy:"流水线忙碌",requestPending:"待处理请求",jobName:"作业名称",startTime:"开始时间",progress:"进度",unit:"批",latestMessage:"最新消息",historyMessages:"历史消息",errors:{fetchFailed:`获取流水线状态失败 -{{error}}`}}},Fp={dataIsTruncated:"图数据已截断至最大返回节点数",statusDialog:{title:"LightRAG 服务器设置",description:"查看当前系统状态和连接信息"},legend:"图例",nodeTypes:{person:"人物角色",category:"分类",geo:"地理名称",location:"位置",organization:"组织机构",event:"事件",equipment:"装备",weapon:"武器",animal:"动物",unknown:"未知",object:"物品",group:"群组",technology:"技术"},sideBar:{settings:{settings:"设置",healthCheck:"健康检查",showPropertyPanel:"显示属性面板",showSearchBar:"显示搜索栏",showNodeLabel:"显示节点标签",nodeDraggable:"节点可拖动",showEdgeLabel:"显示边标签",hideUnselectedEdges:"隐藏未选中的边",edgeEvents:"边事件",maxQueryDepth:"最大查询深度",maxNodes:"最大返回节点数",maxLayoutIterations:"最大布局迭代次数",resetToDefault:"重置为默认值",edgeSizeRange:"边粗细范围",depth:"深",max:"Max",degree:"邻边",apiKey:"API密钥",enterYourAPIkey:"输入您的API密钥",save:"保存",refreshLayout:"刷新布局"},zoomControl:{zoomIn:"放大",zoomOut:"缩小",resetZoom:"重置缩放",rotateCamera:"顺时针旋转图形",rotateCameraCounterClockwise:"逆时针旋转图形"},layoutsControl:{startAnimation:"继续布局动画",stopAnimation:"停止布局动画",layoutGraph:"图布局",layouts:{Circular:"环形",Circlepack:"圆形打包",Random:"随机",Noverlaps:"无重叠","Force Directed":"力导向","Force Atlas":"力地图"}},fullScreenControl:{fullScreen:"全屏",windowed:"窗口"},legendControl:{toggleLegend:"切换图例显示"}},statusIndicator:{connected:"已连接",disconnected:"未连接"},statusCard:{unavailable:"状态信息不可用",storageInfo:"存储信息",workingDirectory:"工作目录",inputDirectory:"输入目录",llmConfig:"LLM配置",llmBinding:"LLM绑定",llmBindingHost:"LLM绑定主机",llmModel:"LLM模型",maxTokens:"最大令牌数",embeddingConfig:"嵌入配置",embeddingBinding:"嵌入绑定",embeddingBindingHost:"嵌入绑定主机",embeddingModel:"嵌入模型",storageConfig:"存储配置",kvStorage:"KV存储",docStatusStorage:"文档状态存储",graphStorage:"图存储",vectorStorage:"向量存储"},propertiesView:{editProperty:"编辑{{property}}",editPropertyDescription:"在下方文本区域编辑属性值。",errors:{duplicateName:"节点名称已存在",updateFailed:"更新节点失败",tryAgainLater:"请稍后重试"},success:{entityUpdated:"节点更新成功",relationUpdated:"关系更新成功"},node:{title:"节点",id:"ID",labels:"标签",degree:"度数",properties:"属性",relationships:"关系(子图内)",expandNode:"扩展节点",pruneNode:"修剪节点",deleteAllNodesError:"拒绝删除图中的所有节点",nodesRemoved:"已删除 {{count}} 个节点,包括孤立节点",noNewNodes:"没有发现可以扩展的节点",propertyNames:{description:"描述",entity_id:"名称",entity_type:"类型",source_id:"信源ID",Neighbour:"邻接",file_path:"信源",keywords:"Keys",weight:"权重"}},edge:{title:"关系",id:"ID",type:"类型",source:"源节点",target:"目标节点",properties:"属性"}},search:{placeholder:"搜索节点...",message:"还有 {count} 个"},graphLabels:{selectTooltip:"选择查询标签",noLabels:"未找到标签",label:"标签",placeholder:"搜索标签...",andOthers:"还有 {count} 个",refreshTooltip:"重载图形数据(添加文件后需重载)"},emptyGraph:"无数据(请重载图形数据)"},$p={chatMessage:{copyTooltip:"复制到剪贴板",copyError:"复制文本到剪贴板失败"},retrieval:{startPrompt:"输入查询开始检索",clear:"清空",send:"发送",placeholder:"输入查询内容 (支持模式前缀: /)",error:"错误:获取响应失败",queryModeError:"仅支持以下查询模式:{{modes}}",queryModePrefixInvalid:"无效的查询模式前缀。请使用:/<模式> [空格] 查询内容"},querySettings:{parametersTitle:"参数",parametersDescription:"配置查询参数",queryMode:"查询模式",queryModeTooltip:`选择检索策略: +{{error}}`}}},Fp={dataIsTruncated:"图数据已截断至最大返回节点数",statusDialog:{title:"LightRAG 服务器设置",description:"查看当前系统状态和连接信息"},legend:"图例",nodeTypes:{person:"人物角色",category:"分类",geo:"地理名称",location:"位置",organization:"组织机构",event:"事件",equipment:"装备",weapon:"武器",animal:"动物",unknown:"未知",object:"物品",group:"群组",technology:"技术"},sideBar:{settings:{settings:"设置",healthCheck:"健康检查",showPropertyPanel:"显示属性面板",showSearchBar:"显示搜索栏",showNodeLabel:"显示节点标签",nodeDraggable:"节点可拖动",showEdgeLabel:"显示边标签",hideUnselectedEdges:"隐藏未选中的边",edgeEvents:"边事件",maxQueryDepth:"最大查询深度",maxNodes:"最大返回节点数",maxLayoutIterations:"最大布局迭代次数",resetToDefault:"重置为默认值",edgeSizeRange:"边粗细范围",depth:"深",max:"Max",degree:"邻边",apiKey:"API密钥",enterYourAPIkey:"输入您的API密钥",save:"保存",refreshLayout:"刷新布局"},zoomControl:{zoomIn:"放大",zoomOut:"缩小",resetZoom:"重置缩放",rotateCamera:"顺时针旋转图形",rotateCameraCounterClockwise:"逆时针旋转图形"},layoutsControl:{startAnimation:"继续布局动画",stopAnimation:"停止布局动画",layoutGraph:"图布局",layouts:{Circular:"环形",Circlepack:"圆形打包",Random:"随机",Noverlaps:"无重叠","Force Directed":"力导向","Force Atlas":"力地图"}},fullScreenControl:{fullScreen:"全屏",windowed:"窗口"},legendControl:{toggleLegend:"切换图例显示"}},statusIndicator:{connected:"已连接",disconnected:"未连接"},statusCard:{unavailable:"状态信息不可用",storageInfo:"存储信息",workingDirectory:"工作目录",inputDirectory:"输入目录",llmConfig:"LLM配置",llmBinding:"LLM绑定",llmBindingHost:"LLM绑定主机",llmModel:"LLM模型",maxTokens:"最大令牌数",embeddingConfig:"嵌入配置",embeddingBinding:"嵌入绑定",embeddingBindingHost:"嵌入绑定主机",embeddingModel:"嵌入模型",storageConfig:"存储配置",kvStorage:"KV存储",docStatusStorage:"文档状态存储",graphStorage:"图存储",vectorStorage:"向量存储",workspace:"工作空间",maxGraphNodes:"最大图节点数"},propertiesView:{editProperty:"编辑{{property}}",editPropertyDescription:"在下方文本区域编辑属性值。",errors:{duplicateName:"节点名称已存在",updateFailed:"更新节点失败",tryAgainLater:"请稍后重试"},success:{entityUpdated:"节点更新成功",relationUpdated:"关系更新成功"},node:{title:"节点",id:"ID",labels:"标签",degree:"度数",properties:"属性",relationships:"关系(子图内)",expandNode:"扩展节点",pruneNode:"修剪节点",deleteAllNodesError:"拒绝删除图中的所有节点",nodesRemoved:"已删除 {{count}} 个节点,包括孤立节点",noNewNodes:"没有发现可以扩展的节点",propertyNames:{description:"描述",entity_id:"名称",entity_type:"类型",source_id:"信源ID",Neighbour:"邻接",file_path:"信源",keywords:"Keys",weight:"权重"}},edge:{title:"关系",id:"ID",type:"类型",source:"源节点",target:"目标节点",properties:"属性"}},search:{placeholder:"搜索节点...",message:"还有 {count} 个"},graphLabels:{selectTooltip:"选择查询标签",noLabels:"未找到标签",label:"标签",placeholder:"搜索标签...",andOthers:"还有 {count} 个",refreshTooltip:"重载图形数据(添加文件后需重载)"},emptyGraph:"无数据(请重载图形数据)"},$p={chatMessage:{copyTooltip:"复制到剪贴板",copyError:"复制文本到剪贴板失败"},retrieval:{startPrompt:"输入查询开始检索",clear:"清空",send:"发送",placeholder:"输入查询内容 (支持模式前缀: /)",error:"错误:获取响应失败",queryModeError:"仅支持以下查询模式:{{modes}}",queryModePrefixInvalid:"无效的查询模式前缀。请使用:/<模式> [空格] 查询内容"},querySettings:{parametersTitle:"参数",parametersDescription:"配置查询参数",queryMode:"查询模式",queryModeTooltip:`选择检索策略: • Naive:基础搜索,无高级技术 • Local:上下文相关信息检索 • Global:利用全局知识库 @@ -76,7 +76,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert- • Bypass:直接传递查询到LLM,不进行检索`,queryModeOptions:{naive:"Naive",local:"Local",global:"Global",hybrid:"Hybrid",mix:"Mix",bypass:"Bypass"},responseFormat:"响应格式",responseFormatTooltip:`定义响应格式。例如: • 多段落 • 单段落 -• 要点`,responseFormatOptions:{multipleParagraphs:"多段落",singleParagraph:"单段落",bulletPoints:"要点"},topK:"Top K结果",topKTooltip:"检索的顶部项目数。在'local'模式下表示实体,在'global'模式下表示关系",topKPlaceholder:"结果数量",maxTokensTextUnit:"文本单元最大令牌数",maxTokensTextUnitTooltip:"每个检索文本块允许的最大令牌数",maxTokensGlobalContext:"全局上下文最大令牌数",maxTokensGlobalContextTooltip:"全局检索中关系描述的最大令牌数",maxTokensLocalContext:"本地上下文最大令牌数",maxTokensLocalContextTooltip:"本地检索中实体描述的最大令牌数",historyTurns:"历史轮次",historyTurnsTooltip:"响应上下文中考虑的完整对话轮次(用户-助手对)数量",historyTurnsPlaceholder:"历史轮次数",onlyNeedContext:"仅需上下文",onlyNeedContextTooltip:"如果为True,仅返回检索到的上下文而不生成响应",onlyNeedPrompt:"仅需提示",onlyNeedPromptTooltip:"如果为True,仅返回生成的提示而不产生响应",streamResponse:"流式响应",streamResponseTooltip:"如果为True,启用实时流式输出响应",userPrompt:"用户提示词",userPromptTooltip:"向LLM提供额外的响应要求(与查询内容无关,仅用于处理输出)。",userPromptPlaceholder:"输入自定义提示词(可选)"}},Wp={loading:"正在加载 API 文档..."},Pp={title:"需要 API Key",description:"请输入您的 API Key 以访问服务",placeholder:"请输入 API Key",save:"保存"},Ip={settings:wp,header:Zp,login:Kp,common:Jp,documentPanel:kp,graphPanel:Fp,retrievePanel:$p,apiSite:Wp,apiKeyAlert:Pp},ey={language:"Langue",theme:"Thème",light:"Clair",dark:"Sombre",system:"Système"},ly={documents:"Documents",knowledgeGraph:"Graphe de connaissances",retrieval:"Récupération",api:"API",projectRepository:"Référentiel du projet",logout:"Déconnexion",themeToggle:{switchToLight:"Passer au thème clair",switchToDark:"Passer au thème sombre"}},ty={description:"Veuillez entrer votre compte et mot de passe pour vous connecter au système",username:"Nom d'utilisateur",usernamePlaceholder:"Veuillez saisir un nom d'utilisateur",password:"Mot de passe",passwordPlaceholder:"Veuillez saisir un mot de passe",loginButton:"Connexion",loggingIn:"Connexion en cours...",successMessage:"Connexion réussie",errorEmptyFields:"Veuillez saisir votre nom d'utilisateur et mot de passe",errorInvalidCredentials:"Échec de la connexion, veuillez vérifier le nom d'utilisateur et le mot de passe",authDisabled:"L'authentification est désactivée. Utilisation du mode sans connexion.",guestMode:"Mode sans connexion"},ay={cancel:"Annuler",save:"Sauvegarder",saving:"Sauvegarde en cours...",saveFailed:"Échec de la sauvegarde"},ny={clearDocuments:{button:"Effacer",tooltip:"Effacer les documents",title:"Effacer les documents",description:"Cette action supprimera tous les documents du système",warning:"ATTENTION : Cette action supprimera définitivement tous les documents et ne peut pas être annulée !",confirm:"Voulez-vous vraiment effacer tous les documents ?",confirmPrompt:"Tapez 'yes' pour confirmer cette action",confirmPlaceholder:"Tapez yes pour confirmer",clearCache:"Effacer le cache LLM",confirmButton:"OUI",success:"Documents effacés avec succès",cacheCleared:"Cache effacé avec succès",cacheClearFailed:`Échec de l'effacement du cache : +• 要点`,responseFormatOptions:{multipleParagraphs:"多段落",singleParagraph:"单段落",bulletPoints:"要点"},topK:"Top K结果",topKTooltip:"检索的顶部项目数。在'local'模式下表示实体,在'global'模式下表示关系",topKPlaceholder:"结果数量",maxTokensTextUnit:"文本单元最大令牌数",maxTokensTextUnitTooltip:"每个检索文本块允许的最大令牌数",maxTokensGlobalContext:"全局上下文最大令牌数",maxTokensGlobalContextTooltip:"全局检索中关系描述的最大令牌数",maxTokensLocalContext:"本地上下文最大令牌数",maxTokensLocalContextTooltip:"本地检索中实体描述的最大令牌数",historyTurns:"历史轮次",historyTurnsTooltip:"响应上下文中考虑的完整对话轮次(用户-助手对)数量",historyTurnsPlaceholder:"历史轮次数",onlyNeedContext:"仅需上下文",onlyNeedContextTooltip:"如果为True,仅返回检索到的上下文而不生成响应",onlyNeedPrompt:"仅需提示",onlyNeedPromptTooltip:"如果为True,仅返回生成的提示而不产生响应",streamResponse:"流式响应",streamResponseTooltip:"如果为True,启用实时流式输出响应",userPrompt:"用户提示词",userPromptTooltip:"向LLM提供额外的响应要求(与查询内容无关,仅用于处理输出)。",userPromptPlaceholder:"输入自定义提示词(可选)"}},Wp={loading:"正在加载 API 文档..."},Pp={title:"需要 API Key",description:"请输入您的 API Key 以访问服务",placeholder:"请输入 API Key",save:"保存"},Ip={settings:Qp,header:Zp,login:Kp,common:kp,documentPanel:Jp,graphPanel:Fp,retrievePanel:$p,apiSite:Wp,apiKeyAlert:Pp},ey={language:"Langue",theme:"Thème",light:"Clair",dark:"Sombre",system:"Système"},ly={documents:"Documents",knowledgeGraph:"Graphe de connaissances",retrieval:"Récupération",api:"API",projectRepository:"Référentiel du projet",logout:"Déconnexion",themeToggle:{switchToLight:"Passer au thème clair",switchToDark:"Passer au thème sombre"}},ty={description:"Veuillez entrer votre compte et mot de passe pour vous connecter au système",username:"Nom d'utilisateur",usernamePlaceholder:"Veuillez saisir un nom d'utilisateur",password:"Mot de passe",passwordPlaceholder:"Veuillez saisir un mot de passe",loginButton:"Connexion",loggingIn:"Connexion en cours...",successMessage:"Connexion réussie",errorEmptyFields:"Veuillez saisir votre nom d'utilisateur et mot de passe",errorInvalidCredentials:"Échec de la connexion, veuillez vérifier le nom d'utilisateur et le mot de passe",authDisabled:"L'authentification est désactivée. Utilisation du mode sans connexion.",guestMode:"Mode sans connexion"},ay={cancel:"Annuler",save:"Sauvegarder",saving:"Sauvegarde en cours...",saveFailed:"Échec de la sauvegarde"},ny={clearDocuments:{button:"Effacer",tooltip:"Effacer les documents",title:"Effacer les documents",description:"Cette action supprimera tous les documents du système",warning:"ATTENTION : Cette action supprimera définitivement tous les documents et ne peut pas être annulée !",confirm:"Voulez-vous vraiment effacer tous les documents ?",confirmPrompt:"Tapez 'yes' pour confirmer cette action",confirmPlaceholder:"Tapez yes pour confirmer",clearCache:"Effacer le cache LLM",confirmButton:"OUI",success:"Documents effacés avec succès",cacheCleared:"Cache effacé avec succès",cacheClearFailed:`Échec de l'effacement du cache : {{error}}`,failed:`Échec de l'effacement des documents : {{message}}`,error:`Échec de l'effacement des documents : {{error}}`},deleteDocuments:{button:"Supprimer",tooltip:"Supprimer les documents sélectionnés",title:"Supprimer les documents",description:"Cette action supprimera définitivement les documents sélectionnés du système",warning:"ATTENTION : Cette action supprimera définitivement les documents sélectionnés et ne peut pas être annulée !",confirm:"Voulez-vous vraiment supprimer {{count}} document(s) sélectionné(s) ?",confirmPrompt:"Tapez 'yes' pour confirmer cette action",confirmPlaceholder:"Tapez yes pour confirmer",confirmButton:"OUI",deleteFileOption:"Supprimer également les fichiers téléchargés",deleteFileTooltip:"Cochez cette option pour supprimer également les fichiers téléchargés correspondants sur le serveur",success:"Pipeline de suppression de documents démarré avec succès",failed:`Échec de la suppression des documents : @@ -91,7 +91,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert- {{error}}`,scanFailed:`Échec de la numérisation des documents {{error}}`,scanProgressFailed:`Échec de l'obtention de la progression de la numérisation {{error}}`},fileNameLabel:"Nom du fichier",showButton:"Afficher",hideButton:"Masquer",showFileNameTooltip:"Afficher le nom du fichier",hideFileNameTooltip:"Masquer le nom du fichier"},pipelineStatus:{title:"État du Pipeline",busy:"Pipeline occupé",requestPending:"Requête en attente",jobName:"Nom du travail",startTime:"Heure de début",progress:"Progression",unit:"lot",latestMessage:"Dernier message",historyMessages:"Historique des messages",errors:{fetchFailed:`Échec de la récupération de l'état du pipeline -{{error}}`}}},uy={dataIsTruncated:"Les données du graphe sont tronquées au nombre maximum de nœuds",statusDialog:{title:"Paramètres du Serveur LightRAG",description:"Afficher l'état actuel du système et les informations de connexion"},legend:"Légende",nodeTypes:{person:"Personne",category:"Catégorie",geo:"Géographique",location:"Emplacement",organization:"Organisation",event:"Événement",equipment:"Équipement",weapon:"Arme",animal:"Animal",unknown:"Inconnu",object:"Objet",group:"Groupe",technology:"Technologie"},sideBar:{settings:{settings:"Paramètres",healthCheck:"Vérification de l'état",showPropertyPanel:"Afficher le panneau des propriétés",showSearchBar:"Afficher la barre de recherche",showNodeLabel:"Afficher l'étiquette du nœud",nodeDraggable:"Nœud déplaçable",showEdgeLabel:"Afficher l'étiquette de l'arête",hideUnselectedEdges:"Masquer les arêtes non sélectionnées",edgeEvents:"Événements des arêtes",maxQueryDepth:"Profondeur maximale de la requête",maxNodes:"Nombre maximum de nœuds",maxLayoutIterations:"Itérations maximales de mise en page",resetToDefault:"Réinitialiser par défaut",edgeSizeRange:"Plage de taille des arêtes",depth:"D",max:"Max",degree:"Degré",apiKey:"Clé API",enterYourAPIkey:"Entrez votre clé API",save:"Sauvegarder",refreshLayout:"Actualiser la mise en page"},zoomControl:{zoomIn:"Zoom avant",zoomOut:"Zoom arrière",resetZoom:"Réinitialiser le zoom",rotateCamera:"Rotation horaire",rotateCameraCounterClockwise:"Rotation antihoraire"},layoutsControl:{startAnimation:"Démarrer l'animation de mise en page",stopAnimation:"Arrêter l'animation de mise en page",layoutGraph:"Mettre en page le graphe",layouts:{Circular:"Circulaire",Circlepack:"Paquet circulaire",Random:"Aléatoire",Noverlaps:"Sans chevauchement","Force Directed":"Dirigé par la force","Force Atlas":"Atlas de force"}},fullScreenControl:{fullScreen:"Plein écran",windowed:"Fenêtré"},legendControl:{toggleLegend:"Basculer la légende"}},statusIndicator:{connected:"Connecté",disconnected:"Déconnecté"},statusCard:{unavailable:"Informations sur l'état indisponibles",storageInfo:"Informations de stockage",workingDirectory:"Répertoire de travail",inputDirectory:"Répertoire d'entrée",llmConfig:"Configuration du modèle de langage",llmBinding:"Liaison du modèle de langage",llmBindingHost:"Hôte de liaison du modèle de langage",llmModel:"Modèle de langage",maxTokens:"Nombre maximum de jetons",embeddingConfig:"Configuration d'incorporation",embeddingBinding:"Liaison d'incorporation",embeddingBindingHost:"Hôte de liaison d'incorporation",embeddingModel:"Modèle d'incorporation",storageConfig:"Configuration de stockage",kvStorage:"Stockage clé-valeur",docStatusStorage:"Stockage de l'état des documents",graphStorage:"Stockage du graphe",vectorStorage:"Stockage vectoriel"},propertiesView:{editProperty:"Modifier {{property}}",editPropertyDescription:"Modifiez la valeur de la propriété dans la zone de texte ci-dessous.",errors:{duplicateName:"Le nom du nœud existe déjà",updateFailed:"Échec de la mise à jour du nœud",tryAgainLater:"Veuillez réessayer plus tard"},success:{entityUpdated:"Nœud mis à jour avec succès",relationUpdated:"Relation mise à jour avec succès"},node:{title:"Nœud",id:"ID",labels:"Étiquettes",degree:"Degré",properties:"Propriétés",relationships:"Relations(dans le sous-graphe)",expandNode:"Développer le nœud",pruneNode:"Élaguer le nœud",deleteAllNodesError:"Refus de supprimer tous les nœuds du graphe",nodesRemoved:"{{count}} nœuds supprimés, y compris les nœuds orphelins",noNewNodes:"Aucun nœud développable trouvé",propertyNames:{description:"Description",entity_id:"Nom",entity_type:"Type",source_id:"ID source",Neighbour:"Voisin",file_path:"Source",keywords:"Keys",weight:"Poids"}},edge:{title:"Relation",id:"ID",type:"Type",source:"Source",target:"Cible",properties:"Propriétés"}},search:{placeholder:"Rechercher des nœuds...",message:"Et {{count}} autres"},graphLabels:{selectTooltip:"Sélectionner l'étiquette de la requête",noLabels:"Aucune étiquette trouvée",label:"Étiquette",placeholder:"Rechercher des étiquettes...",andOthers:"Et {{count}} autres",refreshTooltip:"Recharger les données (Après l'ajout de fichier)"},emptyGraph:"Vide (Essayez de recharger)"},iy={chatMessage:{copyTooltip:"Copier dans le presse-papiers",copyError:"Échec de la copie du texte dans le presse-papiers"},retrieval:{startPrompt:"Démarrez une récupération en tapant votre requête ci-dessous",clear:"Effacer",send:"Envoyer",placeholder:"Tapez votre requête (Préfixe de requête : /)",error:"Erreur : Échec de l'obtention de la réponse",queryModeError:"Seuls les modes de requête suivants sont pris en charge : {{modes}}",queryModePrefixInvalid:"Préfixe de mode de requête invalide. Utilisez : / [espace] votre requête"},querySettings:{parametersTitle:"Paramètres",parametersDescription:"Configurez vos paramètres de requête",queryMode:"Mode de requête",queryModeTooltip:`Sélectionnez la stratégie de récupération : +{{error}}`}}},uy={dataIsTruncated:"Les données du graphe sont tronquées au nombre maximum de nœuds",statusDialog:{title:"Paramètres du Serveur LightRAG",description:"Afficher l'état actuel du système et les informations de connexion"},legend:"Légende",nodeTypes:{person:"Personne",category:"Catégorie",geo:"Géographique",location:"Emplacement",organization:"Organisation",event:"Événement",equipment:"Équipement",weapon:"Arme",animal:"Animal",unknown:"Inconnu",object:"Objet",group:"Groupe",technology:"Technologie"},sideBar:{settings:{settings:"Paramètres",healthCheck:"Vérification de l'état",showPropertyPanel:"Afficher le panneau des propriétés",showSearchBar:"Afficher la barre de recherche",showNodeLabel:"Afficher l'étiquette du nœud",nodeDraggable:"Nœud déplaçable",showEdgeLabel:"Afficher l'étiquette de l'arête",hideUnselectedEdges:"Masquer les arêtes non sélectionnées",edgeEvents:"Événements des arêtes",maxQueryDepth:"Profondeur maximale de la requête",maxNodes:"Nombre maximum de nœuds",maxLayoutIterations:"Itérations maximales de mise en page",resetToDefault:"Réinitialiser par défaut",edgeSizeRange:"Plage de taille des arêtes",depth:"D",max:"Max",degree:"Degré",apiKey:"Clé API",enterYourAPIkey:"Entrez votre clé API",save:"Sauvegarder",refreshLayout:"Actualiser la mise en page"},zoomControl:{zoomIn:"Zoom avant",zoomOut:"Zoom arrière",resetZoom:"Réinitialiser le zoom",rotateCamera:"Rotation horaire",rotateCameraCounterClockwise:"Rotation antihoraire"},layoutsControl:{startAnimation:"Démarrer l'animation de mise en page",stopAnimation:"Arrêter l'animation de mise en page",layoutGraph:"Mettre en page le graphe",layouts:{Circular:"Circulaire",Circlepack:"Paquet circulaire",Random:"Aléatoire",Noverlaps:"Sans chevauchement","Force Directed":"Dirigé par la force","Force Atlas":"Atlas de force"}},fullScreenControl:{fullScreen:"Plein écran",windowed:"Fenêtré"},legendControl:{toggleLegend:"Basculer la légende"}},statusIndicator:{connected:"Connecté",disconnected:"Déconnecté"},statusCard:{unavailable:"Informations sur l'état indisponibles",storageInfo:"Informations de stockage",workingDirectory:"Répertoire de travail",inputDirectory:"Répertoire d'entrée",llmConfig:"Configuration du modèle de langage",llmBinding:"Liaison du modèle de langage",llmBindingHost:"Hôte de liaison du modèle de langage",llmModel:"Modèle de langage",maxTokens:"Nombre maximum de jetons",embeddingConfig:"Configuration d'incorporation",embeddingBinding:"Liaison d'incorporation",embeddingBindingHost:"Hôte de liaison d'incorporation",embeddingModel:"Modèle d'incorporation",storageConfig:"Configuration de stockage",kvStorage:"Stockage clé-valeur",docStatusStorage:"Stockage de l'état des documents",graphStorage:"Stockage du graphe",vectorStorage:"Stockage vectoriel",workspace:"Espace de travail",maxGraphNodes:"Nombre maximum de nœuds du graphe"},propertiesView:{editProperty:"Modifier {{property}}",editPropertyDescription:"Modifiez la valeur de la propriété dans la zone de texte ci-dessous.",errors:{duplicateName:"Le nom du nœud existe déjà",updateFailed:"Échec de la mise à jour du nœud",tryAgainLater:"Veuillez réessayer plus tard"},success:{entityUpdated:"Nœud mis à jour avec succès",relationUpdated:"Relation mise à jour avec succès"},node:{title:"Nœud",id:"ID",labels:"Étiquettes",degree:"Degré",properties:"Propriétés",relationships:"Relations(dans le sous-graphe)",expandNode:"Développer le nœud",pruneNode:"Élaguer le nœud",deleteAllNodesError:"Refus de supprimer tous les nœuds du graphe",nodesRemoved:"{{count}} nœuds supprimés, y compris les nœuds orphelins",noNewNodes:"Aucun nœud développable trouvé",propertyNames:{description:"Description",entity_id:"Nom",entity_type:"Type",source_id:"ID source",Neighbour:"Voisin",file_path:"Source",keywords:"Keys",weight:"Poids"}},edge:{title:"Relation",id:"ID",type:"Type",source:"Source",target:"Cible",properties:"Propriétés"}},search:{placeholder:"Rechercher des nœuds...",message:"Et {{count}} autres"},graphLabels:{selectTooltip:"Sélectionner l'étiquette de la requête",noLabels:"Aucune étiquette trouvée",label:"Étiquette",placeholder:"Rechercher des étiquettes...",andOthers:"Et {{count}} autres",refreshTooltip:"Recharger les données (Après l'ajout de fichier)"},emptyGraph:"Vide (Essayez de recharger)"},iy={chatMessage:{copyTooltip:"Copier dans le presse-papiers",copyError:"Échec de la copie du texte dans le presse-papiers"},retrieval:{startPrompt:"Démarrez une récupération en tapant votre requête ci-dessous",clear:"Effacer",send:"Envoyer",placeholder:"Tapez votre requête (Préfixe de requête : /)",error:"Erreur : Échec de l'obtention de la réponse",queryModeError:"Seuls les modes de requête suivants sont pris en charge : {{modes}}",queryModePrefixInvalid:"Préfixe de mode de requête invalide. Utilisez : / [espace] votre requête"},querySettings:{parametersTitle:"Paramètres",parametersDescription:"Configurez vos paramètres de requête",queryMode:"Mode de requête",queryModeTooltip:`Sélectionnez la stratégie de récupération : • Naïf : Recherche de base sans techniques avancées • Local : Récupération d'informations dépendante du contexte • Global : Utilise une base de connaissances globale @@ -115,7 +115,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert- {{error}}`,scanFailed:`فشل مسح المستندات {{error}}`,scanProgressFailed:`فشل الحصول على تقدم المسح {{error}}`},fileNameLabel:"اسم الملف",showButton:"عرض",hideButton:"إخفاء",showFileNameTooltip:"عرض اسم الملف",hideFileNameTooltip:"إخفاء اسم الملف"},pipelineStatus:{title:"حالة خط المعالجة",busy:"خط المعالجة مشغول",requestPending:"الطلب معلق",jobName:"اسم المهمة",startTime:"وقت البدء",progress:"التقدم",unit:"دفعة",latestMessage:"آخر رسالة",historyMessages:"سجل الرسائل",errors:{fetchFailed:`فشل في جلب حالة خط المعالجة -{{error}}`}}},gy={dataIsTruncated:"تم اقتصار بيانات الرسم البياني على الحد الأقصى للعقد",statusDialog:{title:"إعدادات خادم LightRAG",description:"عرض حالة النظام الحالية ومعلومات الاتصال"},legend:"المفتاح",nodeTypes:{person:"شخص",category:"فئة",geo:"كيان جغرافي",location:"موقع",organization:"منظمة",event:"حدث",equipment:"معدات",weapon:"سلاح",animal:"حيوان",unknown:"غير معروف",object:"مصنوع",group:"مجموعة",technology:"العلوم"},sideBar:{settings:{settings:"الإعدادات",healthCheck:"فحص الحالة",showPropertyPanel:"إظهار لوحة الخصائص",showSearchBar:"إظهار شريط البحث",showNodeLabel:"إظهار تسمية العقدة",nodeDraggable:"العقدة قابلة للسحب",showEdgeLabel:"إظهار تسمية الحافة",hideUnselectedEdges:"إخفاء الحواف غير المحددة",edgeEvents:"أحداث الحافة",maxQueryDepth:"أقصى عمق للاستعلام",maxNodes:"الحد الأقصى للعقد",maxLayoutIterations:"أقصى تكرارات التخطيط",resetToDefault:"إعادة التعيين إلى الافتراضي",edgeSizeRange:"نطاق حجم الحافة",depth:"D",max:"Max",degree:"الدرجة",apiKey:"مفتاح واجهة برمجة التطبيقات",enterYourAPIkey:"أدخل مفتاح واجهة برمجة التطبيقات الخاص بك",save:"حفظ",refreshLayout:"تحديث التخطيط"},zoomControl:{zoomIn:"تكبير",zoomOut:"تصغير",resetZoom:"إعادة تعيين التكبير",rotateCamera:"تدوير في اتجاه عقارب الساعة",rotateCameraCounterClockwise:"تدوير عكس اتجاه عقارب الساعة"},layoutsControl:{startAnimation:"بدء حركة التخطيط",stopAnimation:"إيقاف حركة التخطيط",layoutGraph:"تخطيط الرسم البياني",layouts:{Circular:"دائري",Circlepack:"حزمة دائرية",Random:"عشوائي",Noverlaps:"بدون تداخل","Force Directed":"موجه بالقوة","Force Atlas":"أطلس القوة"}},fullScreenControl:{fullScreen:"شاشة كاملة",windowed:"نوافذ"},legendControl:{toggleLegend:"تبديل المفتاح"}},statusIndicator:{connected:"متصل",disconnected:"غير متصل"},statusCard:{unavailable:"معلومات الحالة غير متوفرة",storageInfo:"معلومات التخزين",workingDirectory:"دليل العمل",inputDirectory:"دليل الإدخال",llmConfig:"تكوين نموذج اللغة الكبير",llmBinding:"ربط نموذج اللغة الكبير",llmBindingHost:"مضيف ربط نموذج اللغة الكبير",llmModel:"نموذج اللغة الكبير",maxTokens:"أقصى عدد من الرموز",embeddingConfig:"تكوين التضمين",embeddingBinding:"ربط التضمين",embeddingBindingHost:"مضيف ربط التضمين",embeddingModel:"نموذج التضمين",storageConfig:"تكوين التخزين",kvStorage:"تخزين المفتاح-القيمة",docStatusStorage:"تخزين حالة المستند",graphStorage:"تخزين الرسم البياني",vectorStorage:"تخزين المتجهات"},propertiesView:{editProperty:"تعديل {{property}}",editPropertyDescription:"قم بتحرير قيمة الخاصية في منطقة النص أدناه.",errors:{duplicateName:"اسم العقدة موجود بالفعل",updateFailed:"فشل تحديث العقدة",tryAgainLater:"يرجى المحاولة مرة أخرى لاحقًا"},success:{entityUpdated:"تم تحديث العقدة بنجاح",relationUpdated:"تم تحديث العلاقة بنجاح"},node:{title:"عقدة",id:"المعرف",labels:"التسميات",degree:"الدرجة",properties:"الخصائص",relationships:"العلاقات (داخل الرسم الفرعي)",expandNode:"توسيع العقدة",pruneNode:"تقليم العقدة",deleteAllNodesError:"رفض حذف جميع العقد في الرسم البياني",nodesRemoved:"تم إزالة {{count}} عقدة، بما في ذلك العقد اليتيمة",noNewNodes:"لم يتم العثور على عقد قابلة للتوسيع",propertyNames:{description:"الوصف",entity_id:"الاسم",entity_type:"النوع",source_id:"معرف المصدر",Neighbour:"الجار",file_path:"المصدر",keywords:"الكلمات الرئيسية",weight:"الوزن"}},edge:{title:"علاقة",id:"المعرف",type:"النوع",source:"المصدر",target:"الهدف",properties:"الخصائص"}},search:{placeholder:"ابحث في العقد...",message:"و {{count}} آخرون"},graphLabels:{selectTooltip:"حدد تسمية الاستعلام",noLabels:"لم يتم العثور على تسميات",label:"التسمية",placeholder:"ابحث في التسميات...",andOthers:"و {{count}} آخرون",refreshTooltip:"إعادة تحميل البيانات (بعد إضافة الملف)"},emptyGraph:"فارغ (حاول إعادة التحميل)"},py={chatMessage:{copyTooltip:"نسخ إلى الحافظة",copyError:"فشل نسخ النص إلى الحافظة"},retrieval:{startPrompt:"ابدأ الاسترجاع بكتابة استفسارك أدناه",clear:"مسح",send:"إرسال",placeholder:"اكتب استفسارك (بادئة وضع الاستعلام: /)",error:"خطأ: فشل الحصول على الرد",queryModeError:"يُسمح فقط بأنماط الاستعلام التالية: {{modes}}",queryModePrefixInvalid:"بادئة وضع الاستعلام غير صالحة. استخدم: /<الوضع> [مسافة] استفسارك"},querySettings:{parametersTitle:"المعلمات",parametersDescription:"تكوين معلمات الاستعلام الخاص بك",queryMode:"وضع الاستعلام",queryModeTooltip:`حدد استراتيجية الاسترجاع: +{{error}}`}}},gy={dataIsTruncated:"تم اقتصار بيانات الرسم البياني على الحد الأقصى للعقد",statusDialog:{title:"إعدادات خادم LightRAG",description:"عرض حالة النظام الحالية ومعلومات الاتصال"},legend:"المفتاح",nodeTypes:{person:"شخص",category:"فئة",geo:"كيان جغرافي",location:"موقع",organization:"منظمة",event:"حدث",equipment:"معدات",weapon:"سلاح",animal:"حيوان",unknown:"غير معروف",object:"مصنوع",group:"مجموعة",technology:"العلوم"},sideBar:{settings:{settings:"الإعدادات",healthCheck:"فحص الحالة",showPropertyPanel:"إظهار لوحة الخصائص",showSearchBar:"إظهار شريط البحث",showNodeLabel:"إظهار تسمية العقدة",nodeDraggable:"العقدة قابلة للسحب",showEdgeLabel:"إظهار تسمية الحافة",hideUnselectedEdges:"إخفاء الحواف غير المحددة",edgeEvents:"أحداث الحافة",maxQueryDepth:"أقصى عمق للاستعلام",maxNodes:"الحد الأقصى للعقد",maxLayoutIterations:"أقصى تكرارات التخطيط",resetToDefault:"إعادة التعيين إلى الافتراضي",edgeSizeRange:"نطاق حجم الحافة",depth:"D",max:"Max",degree:"الدرجة",apiKey:"مفتاح واجهة برمجة التطبيقات",enterYourAPIkey:"أدخل مفتاح واجهة برمجة التطبيقات الخاص بك",save:"حفظ",refreshLayout:"تحديث التخطيط"},zoomControl:{zoomIn:"تكبير",zoomOut:"تصغير",resetZoom:"إعادة تعيين التكبير",rotateCamera:"تدوير في اتجاه عقارب الساعة",rotateCameraCounterClockwise:"تدوير عكس اتجاه عقارب الساعة"},layoutsControl:{startAnimation:"بدء حركة التخطيط",stopAnimation:"إيقاف حركة التخطيط",layoutGraph:"تخطيط الرسم البياني",layouts:{Circular:"دائري",Circlepack:"حزمة دائرية",Random:"عشوائي",Noverlaps:"بدون تداخل","Force Directed":"موجه بالقوة","Force Atlas":"أطلس القوة"}},fullScreenControl:{fullScreen:"شاشة كاملة",windowed:"نوافذ"},legendControl:{toggleLegend:"تبديل المفتاح"}},statusIndicator:{connected:"متصل",disconnected:"غير متصل"},statusCard:{unavailable:"معلومات الحالة غير متوفرة",storageInfo:"معلومات التخزين",workingDirectory:"دليل العمل",inputDirectory:"دليل الإدخال",llmConfig:"تكوين نموذج اللغة الكبير",llmBinding:"ربط نموذج اللغة الكبير",llmBindingHost:"مضيف ربط نموذج اللغة الكبير",llmModel:"نموذج اللغة الكبير",maxTokens:"أقصى عدد من الرموز",embeddingConfig:"تكوين التضمين",embeddingBinding:"ربط التضمين",embeddingBindingHost:"مضيف ربط التضمين",embeddingModel:"نموذج التضمين",storageConfig:"تكوين التخزين",kvStorage:"تخزين المفتاح-القيمة",docStatusStorage:"تخزين حالة المستند",graphStorage:"تخزين الرسم البياني",vectorStorage:"تخزين المتجهات",workspace:"مساحة العمل",maxGraphNodes:"الحد الأقصى لعقد الرسم البياني"},propertiesView:{editProperty:"تعديل {{property}}",editPropertyDescription:"قم بتحرير قيمة الخاصية في منطقة النص أدناه.",errors:{duplicateName:"اسم العقدة موجود بالفعل",updateFailed:"فشل تحديث العقدة",tryAgainLater:"يرجى المحاولة مرة أخرى لاحقًا"},success:{entityUpdated:"تم تحديث العقدة بنجاح",relationUpdated:"تم تحديث العلاقة بنجاح"},node:{title:"عقدة",id:"المعرف",labels:"التسميات",degree:"الدرجة",properties:"الخصائص",relationships:"العلاقات (داخل الرسم الفرعي)",expandNode:"توسيع العقدة",pruneNode:"تقليم العقدة",deleteAllNodesError:"رفض حذف جميع العقد في الرسم البياني",nodesRemoved:"تم إزالة {{count}} عقدة، بما في ذلك العقد اليتيمة",noNewNodes:"لم يتم العثور على عقد قابلة للتوسيع",propertyNames:{description:"الوصف",entity_id:"الاسم",entity_type:"النوع",source_id:"معرف المصدر",Neighbour:"الجار",file_path:"المصدر",keywords:"الكلمات الرئيسية",weight:"الوزن"}},edge:{title:"علاقة",id:"المعرف",type:"النوع",source:"المصدر",target:"الهدف",properties:"الخصائص"}},search:{placeholder:"ابحث في العقد...",message:"و {{count}} آخرون"},graphLabels:{selectTooltip:"حدد تسمية الاستعلام",noLabels:"لم يتم العثور على تسميات",label:"التسمية",placeholder:"ابحث في التسميات...",andOthers:"و {{count}} آخرون",refreshTooltip:"إعادة تحميل البيانات (بعد إضافة الملف)"},emptyGraph:"فارغ (حاول إعادة التحميل)"},py={chatMessage:{copyTooltip:"نسخ إلى الحافظة",copyError:"فشل نسخ النص إلى الحافظة"},retrieval:{startPrompt:"ابدأ الاسترجاع بكتابة استفسارك أدناه",clear:"مسح",send:"إرسال",placeholder:"اكتب استفسارك (بادئة وضع الاستعلام: /)",error:"خطأ: فشل الحصول على الرد",queryModeError:"يُسمح فقط بأنماط الاستعلام التالية: {{modes}}",queryModePrefixInvalid:"بادئة وضع الاستعلام غير صالحة. استخدم: /<الوضع> [مسافة] استفسارك"},querySettings:{parametersTitle:"المعلمات",parametersDescription:"تكوين معلمات الاستعلام الخاص بك",queryMode:"وضع الاستعلام",queryModeTooltip:`حدد استراتيجية الاسترجاع: • ساذج: بحث أساسي بدون تقنيات متقدمة • محلي: استرجاع معلومات يعتمد على السياق • عالمي: يستخدم قاعدة المعرفة العالمية @@ -139,7 +139,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert- {{error}}`,scanFailed:`掃描文件失敗 {{error}}`,scanProgressFailed:`取得掃描進度失敗 {{error}}`},fileNameLabel:"檔案名稱",showButton:"顯示",hideButton:"隱藏",showFileNameTooltip:"顯示檔案名稱",hideFileNameTooltip:"隱藏檔案名稱"},pipelineStatus:{title:"pipeline 狀態",busy:"pipeline 忙碌中",requestPending:"待處理請求",jobName:"工作名稱",startTime:"開始時間",progress:"進度",unit:"梯次",latestMessage:"最新訊息",historyMessages:"歷史訊息",errors:{fetchFailed:`取得pipeline 狀態失敗 -{{error}}`}}},Ny={dataIsTruncated:"圖資料已截斷至最大回傳節點數",statusDialog:{title:"LightRAG 伺服器設定",description:"查看目前系統狀態和連線資訊"},legend:"圖例",nodeTypes:{person:"人物角色",category:"分類",geo:"地理名稱",location:"位置",organization:"組織機構",event:"事件",equipment:"設備",weapon:"武器",animal:"動物",unknown:"未知",object:"物品",group:"群組",technology:"技術"},sideBar:{settings:{settings:"設定",healthCheck:"健康檢查",showPropertyPanel:"顯示屬性面板",showSearchBar:"顯示搜尋列",showNodeLabel:"顯示節點標籤",nodeDraggable:"節點可拖曳",showEdgeLabel:"顯示 Edge 標籤",hideUnselectedEdges:"隱藏未選取的 Edge",edgeEvents:"Edge 事件",maxQueryDepth:"最大查詢深度",maxNodes:"最大回傳節點數",maxLayoutIterations:"最大版面配置迭代次數",resetToDefault:"重設為預設值",edgeSizeRange:"Edge 粗細範圍",depth:"深度",max:"最大值",degree:"鄰邊",apiKey:"API key",enterYourAPIkey:"輸入您的 API key",save:"儲存",refreshLayout:"重新整理版面配置"},zoomControl:{zoomIn:"放大",zoomOut:"縮小",resetZoom:"重設縮放",rotateCamera:"順時針旋轉圖形",rotateCameraCounterClockwise:"逆時針旋轉圖形"},layoutsControl:{startAnimation:"繼續版面配置動畫",stopAnimation:"停止版面配置動畫",layoutGraph:"圖形版面配置",layouts:{Circular:"環形",Circlepack:"圓形打包",Random:"隨機",Noverlaps:"無重疊","Force Directed":"力導向","Force Atlas":"力圖"}},fullScreenControl:{fullScreen:"全螢幕",windowed:"視窗"},legendControl:{toggleLegend:"切換圖例顯示"}},statusIndicator:{connected:"已連線",disconnected:"未連線"},statusCard:{unavailable:"狀態資訊不可用",storageInfo:"儲存資訊",workingDirectory:"工作目錄",inputDirectory:"輸入目錄",llmConfig:"LLM 設定",llmBinding:"LLM 綁定",llmBindingHost:"LLM 綁定主機",llmModel:"LLM 模型",maxTokens:"最大權杖數",embeddingConfig:"嵌入設定",embeddingBinding:"嵌入綁定",embeddingBindingHost:"嵌入綁定主機",embeddingModel:"嵌入模型",storageConfig:"儲存設定",kvStorage:"KV 儲存",docStatusStorage:"文件狀態儲存",graphStorage:"圖形儲存",vectorStorage:"向量儲存"},propertiesView:{editProperty:"編輯{{property}}",editPropertyDescription:"在下方文字區域編輯屬性值。",errors:{duplicateName:"節點名稱已存在",updateFailed:"更新節點失敗",tryAgainLater:"請稍後重試"},success:{entityUpdated:"節點更新成功",relationUpdated:"關係更新成功"},node:{title:"節點",id:"ID",labels:"標籤",degree:"度數",properties:"屬性",relationships:"關係(子圖內)",expandNode:"展開節點",pruneNode:"修剪節點",deleteAllNodesError:"拒絕刪除圖中的所有節點",nodesRemoved:"已刪除 {{count}} 個節點,包括孤立節點",noNewNodes:"沒有發現可以展開的節點",propertyNames:{description:"描述",entity_id:"名稱",entity_type:"類型",source_id:"來源ID",Neighbour:"鄰接",file_path:"來源",keywords:"Keys",weight:"權重"}},edge:{title:"關係",id:"ID",type:"類型",source:"來源節點",target:"目標節點",properties:"屬性"}},search:{placeholder:"搜尋節點...",message:"還有 {count} 個"},graphLabels:{selectTooltip:"選擇查詢標籤",noLabels:"未找到標籤",label:"標籤",placeholder:"搜尋標籤...",andOthers:"還有 {count} 個",refreshTooltip:"重載圖形數據(新增檔案後需重載)"},emptyGraph:"無數據(請重載圖形數據)"},Ey={chatMessage:{copyTooltip:"複製到剪貼簿",copyError:"複製文字到剪貼簿失敗"},retrieval:{startPrompt:"輸入查詢開始檢索",clear:"清空",send:"送出",placeholder:"輸入查詢內容 (支援模式前綴:/)",error:"錯誤:取得回應失敗",queryModeError:"僅支援以下查詢模式:{{modes}}",queryModePrefixInvalid:"無效的查詢模式前綴。請使用:/<模式> [空格] 查詢內容"},querySettings:{parametersTitle:"參數",parametersDescription:"設定查詢參數",queryMode:"查詢模式",queryModeTooltip:`選擇檢索策略: +{{error}}`}}},Ny={dataIsTruncated:"圖資料已截斷至最大回傳節點數",statusDialog:{title:"LightRAG 伺服器設定",description:"查看目前系統狀態和連線資訊"},legend:"圖例",nodeTypes:{person:"人物角色",category:"分類",geo:"地理名稱",location:"位置",organization:"組織機構",event:"事件",equipment:"設備",weapon:"武器",animal:"動物",unknown:"未知",object:"物品",group:"群組",technology:"技術"},sideBar:{settings:{settings:"設定",healthCheck:"健康檢查",showPropertyPanel:"顯示屬性面板",showSearchBar:"顯示搜尋列",showNodeLabel:"顯示節點標籤",nodeDraggable:"節點可拖曳",showEdgeLabel:"顯示 Edge 標籤",hideUnselectedEdges:"隱藏未選取的 Edge",edgeEvents:"Edge 事件",maxQueryDepth:"最大查詢深度",maxNodes:"最大回傳節點數",maxLayoutIterations:"最大版面配置迭代次數",resetToDefault:"重設為預設值",edgeSizeRange:"Edge 粗細範圍",depth:"深度",max:"最大值",degree:"鄰邊",apiKey:"API key",enterYourAPIkey:"輸入您的 API key",save:"儲存",refreshLayout:"重新整理版面配置"},zoomControl:{zoomIn:"放大",zoomOut:"縮小",resetZoom:"重設縮放",rotateCamera:"順時針旋轉圖形",rotateCameraCounterClockwise:"逆時針旋轉圖形"},layoutsControl:{startAnimation:"繼續版面配置動畫",stopAnimation:"停止版面配置動畫",layoutGraph:"圖形版面配置",layouts:{Circular:"環形",Circlepack:"圓形打包",Random:"隨機",Noverlaps:"無重疊","Force Directed":"力導向","Force Atlas":"力圖"}},fullScreenControl:{fullScreen:"全螢幕",windowed:"視窗"},legendControl:{toggleLegend:"切換圖例顯示"}},statusIndicator:{connected:"已連線",disconnected:"未連線"},statusCard:{unavailable:"狀態資訊不可用",storageInfo:"儲存資訊",workingDirectory:"工作目錄",inputDirectory:"輸入目錄",llmConfig:"LLM 設定",llmBinding:"LLM 綁定",llmBindingHost:"LLM 綁定主機",llmModel:"LLM 模型",maxTokens:"最大權杖數",embeddingConfig:"嵌入設定",embeddingBinding:"嵌入綁定",embeddingBindingHost:"嵌入綁定主機",embeddingModel:"嵌入模型",storageConfig:"儲存設定",kvStorage:"KV 儲存",docStatusStorage:"文件狀態儲存",graphStorage:"圖形儲存",vectorStorage:"向量儲存",workspace:"工作空間",maxGraphNodes:"最大圖形節點數"},propertiesView:{editProperty:"編輯{{property}}",editPropertyDescription:"在下方文字區域編輯屬性值。",errors:{duplicateName:"節點名稱已存在",updateFailed:"更新節點失敗",tryAgainLater:"請稍後重試"},success:{entityUpdated:"節點更新成功",relationUpdated:"關係更新成功"},node:{title:"節點",id:"ID",labels:"標籤",degree:"度數",properties:"屬性",relationships:"關係(子圖內)",expandNode:"展開節點",pruneNode:"修剪節點",deleteAllNodesError:"拒絕刪除圖中的所有節點",nodesRemoved:"已刪除 {{count}} 個節點,包括孤立節點",noNewNodes:"沒有發現可以展開的節點",propertyNames:{description:"描述",entity_id:"名稱",entity_type:"類型",source_id:"來源ID",Neighbour:"鄰接",file_path:"來源",keywords:"Keys",weight:"權重"}},edge:{title:"關係",id:"ID",type:"類型",source:"來源節點",target:"目標節點",properties:"屬性"}},search:{placeholder:"搜尋節點...",message:"還有 {count} 個"},graphLabels:{selectTooltip:"選擇查詢標籤",noLabels:"未找到標籤",label:"標籤",placeholder:"搜尋標籤...",andOthers:"還有 {count} 個",refreshTooltip:"重載圖形數據(新增檔案後需重載)"},emptyGraph:"無數據(請重載圖形數據)"},Ey={chatMessage:{copyTooltip:"複製到剪貼簿",copyError:"複製文字到剪貼簿失敗"},retrieval:{startPrompt:"輸入查詢開始檢索",clear:"清空",send:"送出",placeholder:"輸入查詢內容 (支援模式前綴:/)",error:"錯誤:取得回應失敗",queryModeError:"僅支援以下查詢模式:{{modes}}",queryModePrefixInvalid:"無效的查詢模式前綴。請使用:/<模式> [空格] 查詢內容"},querySettings:{parametersTitle:"參數",parametersDescription:"設定查詢參數",queryMode:"查詢模式",queryModeTooltip:`選擇檢索策略: • Naive:基礎搜尋,無進階技術 • Local:上下文相關資訊檢索 • Global:利用全域知識庫 @@ -148,4 +148,4 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert- • Bypass:直接傳遞查詢到LLM,不進行檢索`,queryModeOptions:{naive:"Naive",local:"Local",global:"Global",hybrid:"Hybrid",mix:"Mix",bypass:"Bypass"},responseFormat:"回應格式",responseFormatTooltip:`定義回應格式。例如: • 多段落 • 單段落 -• 重點`,responseFormatOptions:{multipleParagraphs:"多段落",singleParagraph:"單段落",bulletPoints:"重點"},topK:"Top K結果",topKTooltip:"檢索的前幾項結果數。在'local'模式下表示實體,在'global'模式下表示關係",topKPlaceholder:"結果數量",maxTokensTextUnit:"文字單元最大權杖數",maxTokensTextUnitTooltip:"每個檢索文字區塊允許的最大權杖數",maxTokensGlobalContext:"全域上下文最大權杖數",maxTokensGlobalContextTooltip:"全域檢索中關係描述的最大權杖數",maxTokensLocalContext:"本地上下文最大權杖數",maxTokensLocalContextTooltip:"本地檢索中實體描述的最大權杖數",historyTurns:"歷史輪次",historyTurnsTooltip:"回應上下文中考慮的完整對話輪次(使用者-助手對)數量",historyTurnsPlaceholder:"歷史輪次數",onlyNeedContext:"僅需上下文",onlyNeedContextTooltip:"如果為True,僅回傳檢索到的上下文而不產生回應",onlyNeedPrompt:"僅需提示",onlyNeedPromptTooltip:"如果為True,僅回傳產生的提示而不產生回應",streamResponse:"串流回應",streamResponseTooltip:"如果為True,啟用即時串流輸出回應",userPrompt:"用戶提示詞",userPromptTooltip:"向LLM提供額外的響應要求(與查詢內容無關,僅用於處理輸出)。",userPromptPlaceholder:"輸入自定義提示詞(可選)"}},My={loading:"正在載入 API 文件..."},zy={title:"需要 API key",description:"請輸入您的 API key 以存取服務",placeholder:"請輸入 API key",save:"儲存"},Cy={settings:Sy,header:Ty,login:xy,common:Ay,documentPanel:Dy,graphPanel:Ny,retrievePanel:Ey,apiSite:My,apiKeyAlert:zy},Oy=()=>{var g;try{const b=localStorage.getItem("settings-storage");if(b)return((g=JSON.parse(b).state)==null?void 0:g.language)||"en"}catch(b){console.error("Failed to get stored language:",b)}return"en"};cs.use($g).init({resources:{en:{translation:Qp},zh:{translation:Ip},fr:{translation:oy},ar:{translation:by},zh_TW:{translation:Cy}},lng:Oy(),fallbackLng:"en",interpolation:{escapeValue:!1},returnEmptyString:!1,returnNull:!1});Ve.subscribe(g=>{const b=g.language;cs.language!==b&&cs.changeLanguage(b)});ap.createRoot(document.getElementById("root")).render(o.jsx(E.StrictMode,{children:o.jsx(Up,{})})); +• 重點`,responseFormatOptions:{multipleParagraphs:"多段落",singleParagraph:"單段落",bulletPoints:"重點"},topK:"Top K結果",topKTooltip:"檢索的前幾項結果數。在'local'模式下表示實體,在'global'模式下表示關係",topKPlaceholder:"結果數量",maxTokensTextUnit:"文字單元最大權杖數",maxTokensTextUnitTooltip:"每個檢索文字區塊允許的最大權杖數",maxTokensGlobalContext:"全域上下文最大權杖數",maxTokensGlobalContextTooltip:"全域檢索中關係描述的最大權杖數",maxTokensLocalContext:"本地上下文最大權杖數",maxTokensLocalContextTooltip:"本地檢索中實體描述的最大權杖數",historyTurns:"歷史輪次",historyTurnsTooltip:"回應上下文中考慮的完整對話輪次(使用者-助手對)數量",historyTurnsPlaceholder:"歷史輪次數",onlyNeedContext:"僅需上下文",onlyNeedContextTooltip:"如果為True,僅回傳檢索到的上下文而不產生回應",onlyNeedPrompt:"僅需提示",onlyNeedPromptTooltip:"如果為True,僅回傳產生的提示而不產生回應",streamResponse:"串流回應",streamResponseTooltip:"如果為True,啟用即時串流輸出回應",userPrompt:"用戶提示詞",userPromptTooltip:"向LLM提供額外的響應要求(與查詢內容無關,僅用於處理輸出)。",userPromptPlaceholder:"輸入自定義提示詞(可選)"}},My={loading:"正在載入 API 文件..."},zy={title:"需要 API key",description:"請輸入您的 API key 以存取服務",placeholder:"請輸入 API key",save:"儲存"},Cy={settings:Sy,header:Ty,login:xy,common:Ay,documentPanel:Dy,graphPanel:Ny,retrievePanel:Ey,apiSite:My,apiKeyAlert:zy},Oy=()=>{var g;try{const v=localStorage.getItem("settings-storage");if(v)return((g=JSON.parse(v).state)==null?void 0:g.language)||"en"}catch(v){console.error("Failed to get stored language:",v)}return"en"};cs.use($g).init({resources:{en:{translation:Vp},zh:{translation:Ip},fr:{translation:oy},ar:{translation:by},zh_TW:{translation:Cy}},lng:Oy(),fallbackLng:"en",interpolation:{escapeValue:!1},returnEmptyString:!1,returnNull:!1});we.subscribe(g=>{const v=g.language;cs.language!==v&&cs.changeLanguage(v)});ap.createRoot(document.getElementById("root")).render(o.jsx(E.StrictMode,{children:o.jsx(Up,{})})); diff --git a/lightrag/api/webui/index.html b/lightrag/api/webui/index.html index fa024670..d156be81 100644 --- a/lightrag/api/webui/index.html +++ b/lightrag/api/webui/index.html @@ -8,7 +8,7 @@ Lightrag - + diff --git a/lightrag/base.py b/lightrag/base.py index 7820b4da..57cb2ac6 100644 --- a/lightrag/base.py +++ b/lightrag/base.py @@ -103,6 +103,7 @@ class QueryParam: @dataclass class StorageNameSpace(ABC): namespace: str + workspace: str global_config: dict[str, Any] async def initialize(self): diff --git a/lightrag/kg/faiss_impl.py b/lightrag/kg/faiss_impl.py index af691458..c6ee099d 100644 --- a/lightrag/kg/faiss_impl.py +++ b/lightrag/kg/faiss_impl.py @@ -38,9 +38,19 @@ class FaissVectorDBStorage(BaseVectorStorage): self.cosine_better_than_threshold = cosine_threshold # Where to save index file if you want persistent storage - self._faiss_index_file = os.path.join( - self.global_config["working_dir"], f"faiss_index_{self.namespace}.index" - ) + working_dir = self.global_config["working_dir"] + if self.workspace: + # Include workspace in the file path for data isolation + workspace_dir = os.path.join(working_dir, self.workspace) + os.makedirs(workspace_dir, exist_ok=True) + self._faiss_index_file = os.path.join( + workspace_dir, f"faiss_index_{self.namespace}.index" + ) + else: + # Default behavior when workspace is empty + self._faiss_index_file = os.path.join( + working_dir, f"faiss_index_{self.namespace}.index" + ) self._meta_file = self._faiss_index_file + ".meta.json" self._max_batch_size = self.global_config["embedding_batch_num"] diff --git a/lightrag/kg/json_doc_status_impl.py b/lightrag/kg/json_doc_status_impl.py index ab6ab390..317509b3 100644 --- a/lightrag/kg/json_doc_status_impl.py +++ b/lightrag/kg/json_doc_status_impl.py @@ -30,7 +30,18 @@ class JsonDocStatusStorage(DocStatusStorage): def __post_init__(self): working_dir = self.global_config["working_dir"] - self._file_name = os.path.join(working_dir, f"kv_store_{self.namespace}.json") + if self.workspace: + # Include workspace in the file path for data isolation + workspace_dir = os.path.join(working_dir, self.workspace) + os.makedirs(workspace_dir, exist_ok=True) + self._file_name = os.path.join( + workspace_dir, f"kv_store_{self.namespace}.json" + ) + else: + # Default behavior when workspace is empty + self._file_name = os.path.join( + working_dir, f"kv_store_{self.namespace}.json" + ) self._data = None self._storage_lock = None self.storage_updated = None diff --git a/lightrag/kg/json_kv_impl.py b/lightrag/kg/json_kv_impl.py index 98835f8c..f76c9e13 100644 --- a/lightrag/kg/json_kv_impl.py +++ b/lightrag/kg/json_kv_impl.py @@ -26,7 +26,18 @@ from .shared_storage import ( class JsonKVStorage(BaseKVStorage): def __post_init__(self): working_dir = self.global_config["working_dir"] - self._file_name = os.path.join(working_dir, f"kv_store_{self.namespace}.json") + if self.workspace: + # Include workspace in the file path for data isolation + workspace_dir = os.path.join(working_dir, self.workspace) + os.makedirs(workspace_dir, exist_ok=True) + self._file_name = os.path.join( + workspace_dir, f"kv_store_{self.namespace}.json" + ) + else: + # Default behavior when workspace is empty + self._file_name = os.path.join( + working_dir, f"kv_store_{self.namespace}.json" + ) self._data = None self._storage_lock = None self.storage_updated = None diff --git a/lightrag/kg/milvus_impl.py b/lightrag/kg/milvus_impl.py index c64239a9..2414787a 100644 --- a/lightrag/kg/milvus_impl.py +++ b/lightrag/kg/milvus_impl.py @@ -7,10 +7,6 @@ from lightrag.utils import logger, compute_mdhash_id from ..base import BaseVectorStorage import pipmaster as pm - -if not pm.is_installed("configparser"): - pm.install("configparser") - if not pm.is_installed("pymilvus"): pm.install("pymilvus") @@ -660,6 +656,29 @@ class MilvusVectorDBStorage(BaseVectorStorage): raise def __post_init__(self): + # Check for MILVUS_WORKSPACE environment variable first (higher priority) + # This allows administrators to force a specific workspace for all Milvus storage instances + milvus_workspace = os.environ.get("MILVUS_WORKSPACE") + if milvus_workspace and milvus_workspace.strip(): + # Use environment variable value, overriding the passed workspace parameter + effective_workspace = milvus_workspace.strip() + logger.info( + f"Using MILVUS_WORKSPACE environment variable: '{effective_workspace}' (overriding passed workspace: '{self.workspace}')" + ) + else: + # Use the workspace parameter passed during initialization + effective_workspace = self.workspace + if effective_workspace: + logger.debug( + f"Using passed workspace parameter: '{effective_workspace}'" + ) + + # Build namespace with workspace prefix for data isolation + if effective_workspace: + self.namespace = f"{effective_workspace}_{self.namespace}" + logger.debug(f"Final namespace with workspace prefix: '{self.namespace}'") + # When workspace is empty, keep the original namespace unchanged + kwargs = self.global_config.get("vector_db_storage_cls_kwargs", {}) cosine_threshold = kwargs.get("cosine_better_than_threshold") if cosine_threshold is None: diff --git a/lightrag/kg/mongo_impl.py b/lightrag/kg/mongo_impl.py index 2ac3aff2..527ef5db 100644 --- a/lightrag/kg/mongo_impl.py +++ b/lightrag/kg/mongo_impl.py @@ -25,6 +25,7 @@ if not pm.is_installed("pymongo"): pm.install("pymongo") from pymongo import AsyncMongoClient # type: ignore +from pymongo import UpdateOne # type: ignore from pymongo.asynchronous.database import AsyncDatabase # type: ignore from pymongo.asynchronous.collection import AsyncCollection # type: ignore from pymongo.operations import SearchIndexModel # type: ignore @@ -81,7 +82,39 @@ class MongoKVStorage(BaseKVStorage): db: AsyncDatabase = field(default=None) _data: AsyncCollection = field(default=None) + def __init__(self, namespace, global_config, embedding_func, workspace=None): + super().__init__( + namespace=namespace, + workspace=workspace or "", + global_config=global_config, + embedding_func=embedding_func, + ) + self.__post_init__() + def __post_init__(self): + # Check for MONGODB_WORKSPACE environment variable first (higher priority) + # This allows administrators to force a specific workspace for all MongoDB storage instances + mongodb_workspace = os.environ.get("MONGODB_WORKSPACE") + if mongodb_workspace and mongodb_workspace.strip(): + # Use environment variable value, overriding the passed workspace parameter + effective_workspace = mongodb_workspace.strip() + logger.info( + f"Using MONGODB_WORKSPACE environment variable: '{effective_workspace}' (overriding passed workspace: '{self.workspace}')" + ) + else: + # Use the workspace parameter passed during initialization + effective_workspace = self.workspace + if effective_workspace: + logger.debug( + f"Using passed workspace parameter: '{effective_workspace}'" + ) + + # Build namespace with workspace prefix for data isolation + if effective_workspace: + self.namespace = f"{effective_workspace}_{self.namespace}" + logger.debug(f"Final namespace with workspace prefix: '{self.namespace}'") + # When workspace is empty, keep the original namespace unchanged + self._collection_name = self.namespace async def initialize(self): @@ -142,7 +175,6 @@ class MongoKVStorage(BaseKVStorage): # Unified handling for all namespaces with flattened keys # Use bulk_write for better performance - from pymongo import UpdateOne operations = [] current_time = int(time.time()) # Get current Unix timestamp @@ -252,7 +284,39 @@ class MongoDocStatusStorage(DocStatusStorage): db: AsyncDatabase = field(default=None) _data: AsyncCollection = field(default=None) + def __init__(self, namespace, global_config, embedding_func, workspace=None): + super().__init__( + namespace=namespace, + workspace=workspace or "", + global_config=global_config, + embedding_func=embedding_func, + ) + self.__post_init__() + def __post_init__(self): + # Check for MONGODB_WORKSPACE environment variable first (higher priority) + # This allows administrators to force a specific workspace for all MongoDB storage instances + mongodb_workspace = os.environ.get("MONGODB_WORKSPACE") + if mongodb_workspace and mongodb_workspace.strip(): + # Use environment variable value, overriding the passed workspace parameter + effective_workspace = mongodb_workspace.strip() + logger.info( + f"Using MONGODB_WORKSPACE environment variable: '{effective_workspace}' (overriding passed workspace: '{self.workspace}')" + ) + else: + # Use the workspace parameter passed during initialization + effective_workspace = self.workspace + if effective_workspace: + logger.debug( + f"Using passed workspace parameter: '{effective_workspace}'" + ) + + # Build namespace with workspace prefix for data isolation + if effective_workspace: + self.namespace = f"{effective_workspace}_{self.namespace}" + logger.debug(f"Final namespace with workspace prefix: '{self.namespace}'") + # When workspace is empty, keep the original namespace unchanged + self._collection_name = self.namespace async def initialize(self): @@ -367,12 +431,36 @@ class MongoGraphStorage(BaseGraphStorage): # edge collection storing source_node_id, target_node_id, and edge_properties edgeCollection: AsyncCollection = field(default=None) - def __init__(self, namespace, global_config, embedding_func): + def __init__(self, namespace, global_config, embedding_func, workspace=None): super().__init__( namespace=namespace, + workspace=workspace or "", global_config=global_config, embedding_func=embedding_func, ) + # Check for MONGODB_WORKSPACE environment variable first (higher priority) + # This allows administrators to force a specific workspace for all MongoDB storage instances + mongodb_workspace = os.environ.get("MONGODB_WORKSPACE") + if mongodb_workspace and mongodb_workspace.strip(): + # Use environment variable value, overriding the passed workspace parameter + effective_workspace = mongodb_workspace.strip() + logger.info( + f"Using MONGODB_WORKSPACE environment variable: '{effective_workspace}' (overriding passed workspace: '{self.workspace}')" + ) + else: + # Use the workspace parameter passed during initialization + effective_workspace = self.workspace + if effective_workspace: + logger.debug( + f"Using passed workspace parameter: '{effective_workspace}'" + ) + + # Build namespace with workspace prefix for data isolation + if effective_workspace: + self.namespace = f"{effective_workspace}_{self.namespace}" + logger.debug(f"Final namespace with workspace prefix: '{self.namespace}'") + # When workspace is empty, keep the original namespace unchanged + self._collection_name = self.namespace self._edge_collection_name = f"{self._collection_name}_edges" @@ -1230,8 +1318,52 @@ class MongoGraphStorage(BaseGraphStorage): class MongoVectorDBStorage(BaseVectorStorage): db: AsyncDatabase | None = field(default=None) _data: AsyncCollection | None = field(default=None) + _index_name: str = field(default="", init=False) + + def __init__( + self, namespace, global_config, embedding_func, workspace=None, meta_fields=None + ): + super().__init__( + namespace=namespace, + workspace=workspace or "", + global_config=global_config, + embedding_func=embedding_func, + meta_fields=meta_fields or set(), + ) + self.__post_init__() def __post_init__(self): + # Check for MONGODB_WORKSPACE environment variable first (higher priority) + # This allows administrators to force a specific workspace for all MongoDB storage instances + mongodb_workspace = os.environ.get("MONGODB_WORKSPACE") + if mongodb_workspace and mongodb_workspace.strip(): + # Use environment variable value, overriding the passed workspace parameter + effective_workspace = mongodb_workspace.strip() + logger.info( + f"Using MONGODB_WORKSPACE environment variable: '{effective_workspace}' (overriding passed workspace: '{self.workspace}')" + ) + else: + # Use the workspace parameter passed during initialization + effective_workspace = self.workspace + if effective_workspace: + logger.debug( + f"Using passed workspace parameter: '{effective_workspace}'" + ) + + # Build namespace with workspace prefix for data isolation + if effective_workspace: + self.namespace = f"{effective_workspace}_{self.namespace}" + logger.debug(f"Final namespace with workspace prefix: '{self.namespace}'") + # When workspace is empty, keep the original namespace unchanged + + # Set index name based on workspace for backward compatibility + if effective_workspace: + # Use collection-specific index name for workspaced collections to avoid conflicts + self._index_name = f"vector_knn_index_{self.namespace}" + else: + # Keep original index name for backward compatibility with existing deployments + self._index_name = "vector_knn_index" + kwargs = self.global_config.get("vector_db_storage_cls_kwargs", {}) cosine_threshold = kwargs.get("cosine_better_than_threshold") if cosine_threshold is None: @@ -1261,13 +1393,11 @@ class MongoVectorDBStorage(BaseVectorStorage): async def create_vector_index_if_not_exists(self): """Creates an Atlas Vector Search index.""" try: - index_name = "vector_knn_index" - indexes_cursor = await self._data.list_search_indexes() indexes = await indexes_cursor.to_list(length=None) for index in indexes: - if index["name"] == index_name: - logger.debug("vector index already exist") + if index["name"] == self._index_name: + logger.info(f"vector index {self._index_name} already exist") return search_index_model = SearchIndexModel( @@ -1281,15 +1411,15 @@ class MongoVectorDBStorage(BaseVectorStorage): } ] }, - name=index_name, + name=self._index_name, type="vectorSearch", ) await self._data.create_search_index(search_index_model) - logger.info("Vector index created successfully.") + logger.info(f"Vector index {self._index_name} created successfully.") - except PyMongoError as _: - logger.debug("vector index already exist") + except PyMongoError as e: + logger.error(f"Error creating vector index {self._index_name}: {e}") async def upsert(self, data: dict[str, dict[str, Any]]) -> None: logger.debug(f"Inserting {len(data)} to {self.namespace}") @@ -1344,7 +1474,7 @@ class MongoVectorDBStorage(BaseVectorStorage): pipeline = [ { "$vectorSearch": { - "index": "vector_knn_index", # Ensure this matches the created index name + "index": self._index_name, # Use stored index name for consistency "path": "vector", "queryVector": query_vector, "numCandidates": 100, # Adjust for performance diff --git a/lightrag/kg/nano_vector_db_impl.py b/lightrag/kg/nano_vector_db_impl.py index fa56a214..4eae2db5 100644 --- a/lightrag/kg/nano_vector_db_impl.py +++ b/lightrag/kg/nano_vector_db_impl.py @@ -41,9 +41,19 @@ class NanoVectorDBStorage(BaseVectorStorage): ) self.cosine_better_than_threshold = cosine_threshold - self._client_file_name = os.path.join( - self.global_config["working_dir"], f"vdb_{self.namespace}.json" - ) + working_dir = self.global_config["working_dir"] + if self.workspace: + # Include workspace in the file path for data isolation + workspace_dir = os.path.join(working_dir, self.workspace) + os.makedirs(workspace_dir, exist_ok=True) + self._client_file_name = os.path.join( + workspace_dir, f"vdb_{self.namespace}.json" + ) + else: + # Default behavior when workspace is empty + self._client_file_name = os.path.join( + working_dir, f"vdb_{self.namespace}.json" + ) self._max_batch_size = self.global_config["embedding_batch_num"] self._client = NanoVectorDB( diff --git a/lightrag/kg/neo4j_impl.py b/lightrag/kg/neo4j_impl.py index d4fbc59c..63a3300a 100644 --- a/lightrag/kg/neo4j_impl.py +++ b/lightrag/kg/neo4j_impl.py @@ -50,14 +50,25 @@ logging.getLogger("neo4j").setLevel(logging.ERROR) @final @dataclass class Neo4JStorage(BaseGraphStorage): - def __init__(self, namespace, global_config, embedding_func): + def __init__(self, namespace, global_config, embedding_func, workspace=None): + # Check NEO4J_WORKSPACE environment variable and override workspace if set + neo4j_workspace = os.environ.get("NEO4J_WORKSPACE") + if neo4j_workspace and neo4j_workspace.strip(): + workspace = neo4j_workspace + super().__init__( namespace=namespace, + workspace=workspace or "", global_config=global_config, embedding_func=embedding_func, ) self._driver = None + def _get_workspace_label(self) -> str: + """Get workspace label, return 'base' for compatibility when workspace is empty""" + workspace = getattr(self, "workspace", None) + return workspace if workspace else "base" + async def initialize(self): URI = os.environ.get("NEO4J_URI", config.get("neo4j", "uri", fallback=None)) USERNAME = os.environ.get( @@ -153,13 +164,14 @@ class Neo4JStorage(BaseGraphStorage): raise e if connected: - # Create index for base nodes on entity_id if it doesn't exist + # Create index for workspace nodes on entity_id if it doesn't exist + workspace_label = self._get_workspace_label() try: async with self._driver.session(database=database) as session: # Check if index exists first - check_query = """ + check_query = f""" CALL db.indexes() YIELD name, labelsOrTypes, properties - WHERE labelsOrTypes = ['base'] AND properties = ['entity_id'] + WHERE labelsOrTypes = ['{workspace_label}'] AND properties = ['entity_id'] RETURN count(*) > 0 AS exists """ try: @@ -172,16 +184,16 @@ class Neo4JStorage(BaseGraphStorage): if not index_exists: # Create index only if it doesn't exist result = await session.run( - "CREATE INDEX FOR (n:base) ON (n.entity_id)" + f"CREATE INDEX FOR (n:`{workspace_label}`) ON (n.entity_id)" ) await result.consume() logger.info( - f"Created index for base nodes on entity_id in {database}" + f"Created index for {workspace_label} nodes on entity_id in {database}" ) except Exception: # Fallback if db.indexes() is not supported in this Neo4j version result = await session.run( - "CREATE INDEX IF NOT EXISTS FOR (n:base) ON (n.entity_id)" + f"CREATE INDEX IF NOT EXISTS FOR (n:`{workspace_label}`) ON (n.entity_id)" ) await result.consume() except Exception as e: @@ -216,11 +228,12 @@ class Neo4JStorage(BaseGraphStorage): ValueError: If node_id is invalid Exception: If there is an error executing the query """ + workspace_label = self._get_workspace_label() async with self._driver.session( database=self._DATABASE, default_access_mode="READ" ) as session: try: - query = "MATCH (n:base {entity_id: $entity_id}) RETURN count(n) > 0 AS node_exists" + query = f"MATCH (n:`{workspace_label}` {{entity_id: $entity_id}}) RETURN count(n) > 0 AS node_exists" result = await session.run(query, entity_id=node_id) single_result = await result.single() await result.consume() # Ensure result is fully consumed @@ -245,12 +258,13 @@ class Neo4JStorage(BaseGraphStorage): ValueError: If either node_id is invalid Exception: If there is an error executing the query """ + workspace_label = self._get_workspace_label() async with self._driver.session( database=self._DATABASE, default_access_mode="READ" ) as session: try: query = ( - "MATCH (a:base {entity_id: $source_entity_id})-[r]-(b:base {entity_id: $target_entity_id}) " + f"MATCH (a:`{workspace_label}` {{entity_id: $source_entity_id}})-[r]-(b:`{workspace_label}` {{entity_id: $target_entity_id}}) " "RETURN COUNT(r) > 0 AS edgeExists" ) result = await session.run( @@ -282,11 +296,14 @@ class Neo4JStorage(BaseGraphStorage): ValueError: If node_id is invalid Exception: If there is an error executing the query """ + workspace_label = self._get_workspace_label() async with self._driver.session( database=self._DATABASE, default_access_mode="READ" ) as session: try: - query = "MATCH (n:base {entity_id: $entity_id}) RETURN n" + query = ( + f"MATCH (n:`{workspace_label}` {{entity_id: $entity_id}}) RETURN n" + ) result = await session.run(query, entity_id=node_id) try: records = await result.fetch( @@ -300,12 +317,12 @@ class Neo4JStorage(BaseGraphStorage): if records: node = records[0]["n"] node_dict = dict(node) - # Remove base label from labels list if it exists + # Remove workspace label from labels list if it exists if "labels" in node_dict: node_dict["labels"] = [ label for label in node_dict["labels"] - if label != "base" + if label != workspace_label ] # logger.debug(f"Neo4j query node {query} return: {node_dict}") return node_dict @@ -326,12 +343,13 @@ class Neo4JStorage(BaseGraphStorage): Returns: A dictionary mapping each node_id to its node data (or None if not found). """ + workspace_label = self._get_workspace_label() async with self._driver.session( database=self._DATABASE, default_access_mode="READ" ) as session: - query = """ + query = f""" UNWIND $node_ids AS id - MATCH (n:base {entity_id: id}) + MATCH (n:`{workspace_label}` {{entity_id: id}}) RETURN n.entity_id AS entity_id, n """ result = await session.run(query, node_ids=node_ids) @@ -340,10 +358,12 @@ class Neo4JStorage(BaseGraphStorage): entity_id = record["entity_id"] node = record["n"] node_dict = dict(node) - # Remove the 'base' label if present in a 'labels' property + # Remove the workspace label if present in a 'labels' property if "labels" in node_dict: node_dict["labels"] = [ - label for label in node_dict["labels"] if label != "base" + label + for label in node_dict["labels"] + if label != workspace_label ] nodes[entity_id] = node_dict await result.consume() # Make sure to consume the result fully @@ -364,12 +384,13 @@ class Neo4JStorage(BaseGraphStorage): ValueError: If node_id is invalid Exception: If there is an error executing the query """ + workspace_label = self._get_workspace_label() async with self._driver.session( database=self._DATABASE, default_access_mode="READ" ) as session: try: - query = """ - MATCH (n:base {entity_id: $entity_id}) + query = f""" + MATCH (n:`{workspace_label}` {{entity_id: $entity_id}}) OPTIONAL MATCH (n)-[r]-() RETURN COUNT(r) AS degree """ @@ -403,13 +424,14 @@ class Neo4JStorage(BaseGraphStorage): A dictionary mapping each node_id to its degree (number of relationships). If a node is not found, its degree will be set to 0. """ + workspace_label = self._get_workspace_label() async with self._driver.session( database=self._DATABASE, default_access_mode="READ" ) as session: - query = """ + query = f""" UNWIND $node_ids AS id - MATCH (n:base {entity_id: id}) - RETURN n.entity_id AS entity_id, count { (n)--() } AS degree; + MATCH (n:`{workspace_label}` {{entity_id: id}}) + RETURN n.entity_id AS entity_id, count {{ (n)--() }} AS degree; """ result = await session.run(query, node_ids=node_ids) degrees = {} @@ -489,12 +511,13 @@ class Neo4JStorage(BaseGraphStorage): ValueError: If either node_id is invalid Exception: If there is an error executing the query """ + workspace_label = self._get_workspace_label() try: async with self._driver.session( database=self._DATABASE, default_access_mode="READ" ) as session: - query = """ - MATCH (start:base {entity_id: $source_entity_id})-[r]-(end:base {entity_id: $target_entity_id}) + query = f""" + MATCH (start:`{workspace_label}` {{entity_id: $source_entity_id}})-[r]-(end:`{workspace_label}` {{entity_id: $target_entity_id}}) RETURN properties(r) as edge_properties """ result = await session.run( @@ -571,12 +594,13 @@ class Neo4JStorage(BaseGraphStorage): Returns: A dictionary mapping (src, tgt) tuples to their edge properties. """ + workspace_label = self._get_workspace_label() async with self._driver.session( database=self._DATABASE, default_access_mode="READ" ) as session: - query = """ + query = f""" UNWIND $pairs AS pair - MATCH (start:base {entity_id: pair.src})-[r:DIRECTED]-(end:base {entity_id: pair.tgt}) + MATCH (start:`{workspace_label}` {{entity_id: pair.src}})-[r:DIRECTED]-(end:`{workspace_label}` {{entity_id: pair.tgt}}) RETURN pair.src AS src_id, pair.tgt AS tgt_id, collect(properties(r)) AS edges """ result = await session.run(query, pairs=pairs) @@ -627,8 +651,9 @@ class Neo4JStorage(BaseGraphStorage): database=self._DATABASE, default_access_mode="READ" ) as session: try: - query = """MATCH (n:base {entity_id: $entity_id}) - OPTIONAL MATCH (n)-[r]-(connected:base) + workspace_label = self._get_workspace_label() + query = f"""MATCH (n:`{workspace_label}` {{entity_id: $entity_id}}) + OPTIONAL MATCH (n)-[r]-(connected:`{workspace_label}`) WHERE connected.entity_id IS NOT NULL RETURN n, r, connected""" results = await session.run(query, entity_id=source_node_id) @@ -689,10 +714,11 @@ class Neo4JStorage(BaseGraphStorage): database=self._DATABASE, default_access_mode="READ" ) as session: # Query to get both outgoing and incoming edges - query = """ + workspace_label = self._get_workspace_label() + query = f""" UNWIND $node_ids AS id - MATCH (n:base {entity_id: id}) - OPTIONAL MATCH (n)-[r]-(connected:base) + MATCH (n:`{workspace_label}` {{entity_id: id}}) + OPTIONAL MATCH (n)-[r]-(connected:`{workspace_label}`) RETURN id AS queried_id, n.entity_id AS node_entity_id, connected.entity_id AS connected_entity_id, startNode(r).entity_id AS start_entity_id @@ -727,12 +753,13 @@ class Neo4JStorage(BaseGraphStorage): return edges_dict async def get_nodes_by_chunk_ids(self, chunk_ids: list[str]) -> list[dict]: + workspace_label = self._get_workspace_label() async with self._driver.session( database=self._DATABASE, default_access_mode="READ" ) as session: - query = """ + query = f""" UNWIND $chunk_ids AS chunk_id - MATCH (n:base) + MATCH (n:`{workspace_label}`) WHERE n.source_id IS NOT NULL AND chunk_id IN split(n.source_id, $sep) RETURN DISTINCT n """ @@ -748,12 +775,13 @@ class Neo4JStorage(BaseGraphStorage): return nodes async def get_edges_by_chunk_ids(self, chunk_ids: list[str]) -> list[dict]: + workspace_label = self._get_workspace_label() async with self._driver.session( database=self._DATABASE, default_access_mode="READ" ) as session: - query = """ + query = f""" UNWIND $chunk_ids AS chunk_id - MATCH (a:base)-[r]-(b:base) + MATCH (a:`{workspace_label}`)-[r]-(b:`{workspace_label}`) WHERE r.source_id IS NOT NULL AND chunk_id IN split(r.source_id, $sep) RETURN DISTINCT a.entity_id AS source, b.entity_id AS target, properties(r) AS properties """ @@ -787,6 +815,7 @@ class Neo4JStorage(BaseGraphStorage): node_id: The unique identifier for the node (used as label) node_data: Dictionary of node properties """ + workspace_label = self._get_workspace_label() properties = node_data entity_type = properties["entity_type"] if "entity_id" not in properties: @@ -796,14 +825,11 @@ class Neo4JStorage(BaseGraphStorage): async with self._driver.session(database=self._DATABASE) as session: async def execute_upsert(tx: AsyncManagedTransaction): - query = ( - """ - MERGE (n:base {entity_id: $entity_id}) + query = f""" + MERGE (n:`{workspace_label}` {{entity_id: $entity_id}}) SET n += $properties - SET n:`%s` + SET n:`{entity_type}` """ - % entity_type - ) result = await tx.run( query, entity_id=node_id, properties=properties ) @@ -847,10 +873,11 @@ class Neo4JStorage(BaseGraphStorage): async with self._driver.session(database=self._DATABASE) as session: async def execute_upsert(tx: AsyncManagedTransaction): - query = """ - MATCH (source:base {entity_id: $source_entity_id}) + workspace_label = self._get_workspace_label() + query = f""" + MATCH (source:`{workspace_label}` {{entity_id: $source_entity_id}}) WITH source - MATCH (target:base {entity_id: $target_entity_id}) + MATCH (target:`{workspace_label}` {{entity_id: $target_entity_id}}) MERGE (source)-[r:DIRECTED]-(target) SET r += $properties RETURN r, source, target @@ -889,6 +916,7 @@ class Neo4JStorage(BaseGraphStorage): KnowledgeGraph object containing nodes and edges, with an is_truncated flag indicating whether the graph was truncated due to max_nodes limit """ + workspace_label = self._get_workspace_label() result = KnowledgeGraph() seen_nodes = set() seen_edges = set() @@ -899,7 +927,9 @@ class Neo4JStorage(BaseGraphStorage): try: if node_label == "*": # First check total node count to determine if graph is truncated - count_query = "MATCH (n) RETURN count(n) as total" + count_query = ( + f"MATCH (n:`{workspace_label}`) RETURN count(n) as total" + ) count_result = None try: count_result = await session.run(count_query) @@ -915,13 +945,13 @@ class Neo4JStorage(BaseGraphStorage): await count_result.consume() # Run main query to get nodes with highest degree - main_query = """ - MATCH (n) + main_query = f""" + MATCH (n:`{workspace_label}`) OPTIONAL MATCH (n)-[r]-() WITH n, COALESCE(count(r), 0) AS degree ORDER BY degree DESC LIMIT $max_nodes - WITH collect({node: n}) AS filtered_nodes + WITH collect({{node: n}}) AS filtered_nodes UNWIND filtered_nodes AS node_info WITH collect(node_info.node) AS kept_nodes, filtered_nodes OPTIONAL MATCH (a)-[r]-(b) @@ -943,20 +973,21 @@ class Neo4JStorage(BaseGraphStorage): else: # return await self._robust_fallback(node_label, max_depth, max_nodes) # First try without limit to check if we need to truncate - full_query = """ - MATCH (start) + full_query = f""" + MATCH (start:`{workspace_label}`) WHERE start.entity_id = $entity_id WITH start - CALL apoc.path.subgraphAll(start, { + CALL apoc.path.subgraphAll(start, {{ relationshipFilter: '', + labelFilter: '{workspace_label}', minLevel: 0, maxLevel: $max_depth, bfs: true - }) + }}) YIELD nodes, relationships WITH nodes, relationships, size(nodes) AS total_nodes UNWIND nodes AS node - WITH collect({node: node}) AS node_info, relationships, total_nodes + WITH collect({{node: node}}) AS node_info, relationships, total_nodes RETURN node_info, relationships, total_nodes """ @@ -994,20 +1025,21 @@ class Neo4JStorage(BaseGraphStorage): ) # Run limited query - limited_query = """ - MATCH (start) + limited_query = f""" + MATCH (start:`{workspace_label}`) WHERE start.entity_id = $entity_id WITH start - CALL apoc.path.subgraphAll(start, { + CALL apoc.path.subgraphAll(start, {{ relationshipFilter: '', + labelFilter: '{workspace_label}', minLevel: 0, maxLevel: $max_depth, limit: $max_nodes, bfs: true - }) + }}) YIELD nodes, relationships UNWIND nodes AS node - WITH collect({node: node}) AS node_info, relationships + WITH collect({{node: node}}) AS node_info, relationships RETURN node_info, relationships """ result_set = None @@ -1094,11 +1126,12 @@ class Neo4JStorage(BaseGraphStorage): visited_edge_pairs = set() # Get the starting node's data + workspace_label = self._get_workspace_label() async with self._driver.session( database=self._DATABASE, default_access_mode="READ" ) as session: - query = """ - MATCH (n:base {entity_id: $entity_id}) + query = f""" + MATCH (n:`{workspace_label}` {{entity_id: $entity_id}}) RETURN id(n) as node_id, n """ node_result = await session.run(query, entity_id=node_label) @@ -1156,8 +1189,9 @@ class Neo4JStorage(BaseGraphStorage): async with self._driver.session( database=self._DATABASE, default_access_mode="READ" ) as session: - query = """ - MATCH (a:base {entity_id: $entity_id})-[r]-(b) + workspace_label = self._get_workspace_label() + query = f""" + MATCH (a:`{workspace_label}` {{entity_id: $entity_id}})-[r]-(b) WITH r, b, id(r) as edge_id, id(b) as target_id RETURN r, b, edge_id, target_id """ @@ -1241,6 +1275,7 @@ class Neo4JStorage(BaseGraphStorage): Returns: ["Person", "Company", ...] # Alphabetically sorted label list """ + workspace_label = self._get_workspace_label() async with self._driver.session( database=self._DATABASE, default_access_mode="READ" ) as session: @@ -1248,8 +1283,8 @@ class Neo4JStorage(BaseGraphStorage): # query = "CALL db.labels() YIELD label RETURN label" # Method 2: Query compatible with older versions - query = """ - MATCH (n:base) + query = f""" + MATCH (n:`{workspace_label}`) WHERE n.entity_id IS NOT NULL RETURN DISTINCT n.entity_id AS label ORDER BY label @@ -1285,8 +1320,9 @@ class Neo4JStorage(BaseGraphStorage): """ async def _do_delete(tx: AsyncManagedTransaction): - query = """ - MATCH (n:base {entity_id: $entity_id}) + workspace_label = self._get_workspace_label() + query = f""" + MATCH (n:`{workspace_label}` {{entity_id: $entity_id}}) DETACH DELETE n """ result = await tx.run(query, entity_id=node_id) @@ -1342,8 +1378,9 @@ class Neo4JStorage(BaseGraphStorage): for source, target in edges: async def _do_delete_edge(tx: AsyncManagedTransaction): - query = """ - MATCH (source:base {entity_id: $source_entity_id})-[r]-(target:base {entity_id: $target_entity_id}) + workspace_label = self._get_workspace_label() + query = f""" + MATCH (source:`{workspace_label}` {{entity_id: $source_entity_id}})-[r]-(target:`{workspace_label}` {{entity_id: $target_entity_id}}) DELETE r """ result = await tx.run( @@ -1360,26 +1397,32 @@ class Neo4JStorage(BaseGraphStorage): raise async def drop(self) -> dict[str, str]: - """Drop all data from storage and clean up resources + """Drop all data from current workspace storage and clean up resources - This method will delete all nodes and relationships in the Neo4j database. + This method will delete all nodes and relationships in the current workspace only. Returns: dict[str, str]: Operation status and message - - On success: {"status": "success", "message": "data dropped"} + - On success: {"status": "success", "message": "workspace data dropped"} - On failure: {"status": "error", "message": ""} """ + workspace_label = self._get_workspace_label() try: async with self._driver.session(database=self._DATABASE) as session: - # Delete all nodes and relationships - query = "MATCH (n) DETACH DELETE n" + # Delete all nodes and relationships in current workspace only + query = f"MATCH (n:`{workspace_label}`) DETACH DELETE n" result = await session.run(query) await result.consume() # Ensure result is fully consumed logger.info( - f"Process {os.getpid()} drop Neo4j database {self._DATABASE}" + f"Process {os.getpid()} drop Neo4j workspace '{workspace_label}' in database {self._DATABASE}" ) - return {"status": "success", "message": "data dropped"} + return { + "status": "success", + "message": f"workspace '{workspace_label}' data dropped", + } except Exception as e: - logger.error(f"Error dropping Neo4j database {self._DATABASE}: {e}") + logger.error( + f"Error dropping Neo4j workspace '{workspace_label}' in database {self._DATABASE}: {e}" + ) return {"status": "error", "message": str(e)} diff --git a/lightrag/kg/networkx_impl.py b/lightrag/kg/networkx_impl.py index bb7233b4..faff6a96 100644 --- a/lightrag/kg/networkx_impl.py +++ b/lightrag/kg/networkx_impl.py @@ -46,9 +46,19 @@ class NetworkXStorage(BaseGraphStorage): nx.write_graphml(graph, file_name) def __post_init__(self): - self._graphml_xml_file = os.path.join( - self.global_config["working_dir"], f"graph_{self.namespace}.graphml" - ) + working_dir = self.global_config["working_dir"] + if self.workspace: + # Include workspace in the file path for data isolation + workspace_dir = os.path.join(working_dir, self.workspace) + os.makedirs(workspace_dir, exist_ok=True) + self._graphml_xml_file = os.path.join( + workspace_dir, f"graph_{self.namespace}.graphml" + ) + else: + # Default behavior when workspace is empty + self._graphml_xml_file = os.path.join( + working_dir, f"graph_{self.namespace}.graphml" + ) self._storage_lock = None self.storage_updated = None self._graph = None diff --git a/lightrag/kg/postgres_impl.py b/lightrag/kg/postgres_impl.py index d8447664..5750fd6e 100644 --- a/lightrag/kg/postgres_impl.py +++ b/lightrag/kg/postgres_impl.py @@ -1,6 +1,7 @@ import asyncio import json import os +import re import datetime from datetime import timezone from dataclasses import dataclass, field @@ -319,7 +320,7 @@ class PostgreSQLDB: # Get all old format data old_data_sql = """ SELECT id, mode, original_prompt, return_value, chunk_id, - create_time, update_time + workspace, create_time, update_time FROM LIGHTRAG_LLM_CACHE WHERE id NOT LIKE '%:%' """ @@ -364,7 +365,9 @@ class PostgreSQLDB: await self.execute( insert_sql, { - "workspace": self.workspace, + "workspace": record[ + "workspace" + ], # Use original record's workspace "id": new_key, "mode": record["mode"], "original_prompt": record["original_prompt"], @@ -384,7 +387,9 @@ class PostgreSQLDB: await self.execute( delete_sql, { - "workspace": self.workspace, + "workspace": record[ + "workspace" + ], # Use original record's workspace "mode": record["mode"], "id": record["id"], # Old id }, @@ -505,6 +510,29 @@ class PostgreSQLDB: f"PostgreSQL, Failed to create index on table {k}, Got: {e}" ) + # Create composite index for (workspace, id) columns in each table + try: + composite_index_name = f"idx_{k.lower()}_workspace_id" + check_composite_index_sql = f""" + SELECT 1 FROM pg_indexes + WHERE indexname = '{composite_index_name}' + AND tablename = '{k.lower()}' + """ + composite_index_exists = await self.query(check_composite_index_sql) + + if not composite_index_exists: + create_composite_index_sql = ( + f"CREATE INDEX {composite_index_name} ON {k}(workspace, id)" + ) + logger.info( + f"PostgreSQL, Creating composite index {composite_index_name} on table {k}" + ) + await self.execute(create_composite_index_sql) + except Exception as e: + logger.error( + f"PostgreSQL, Failed to create composite index on table {k}, Got: {e}" + ) + # After all tables are created, attempt to migrate timestamp fields try: await self._migrate_timestamp_columns() @@ -670,7 +698,7 @@ class ClientManager: ), "workspace": os.environ.get( "POSTGRES_WORKSPACE", - config.get("postgres", "workspace", fallback="default"), + config.get("postgres", "workspace", fallback=None), ), "max_connections": os.environ.get( "POSTGRES_MAX_CONNECTIONS", @@ -716,6 +744,18 @@ class PGKVStorage(BaseKVStorage): async def initialize(self): if self.db is None: self.db = await ClientManager.get_client() + # Implement workspace priority: PostgreSQLDB.workspace > self.workspace > "default" + if self.db.workspace: + # Use PostgreSQLDB's workspace (highest priority) + final_workspace = self.db.workspace + elif hasattr(self, "workspace") and self.workspace: + # Use storage class's workspace (medium priority) + final_workspace = self.workspace + self.db.workspace = final_workspace + else: + # Use "default" for compatibility (lowest priority) + final_workspace = "default" + self.db.workspace = final_workspace async def finalize(self): if self.db is not None: @@ -1047,6 +1087,18 @@ class PGVectorStorage(BaseVectorStorage): async def initialize(self): if self.db is None: self.db = await ClientManager.get_client() + # Implement workspace priority: PostgreSQLDB.workspace > self.workspace > "default" + if self.db.workspace: + # Use PostgreSQLDB's workspace (highest priority) + final_workspace = self.db.workspace + elif hasattr(self, "workspace") and self.workspace: + # Use storage class's workspace (medium priority) + final_workspace = self.workspace + self.db.workspace = final_workspace + else: + # Use "default" for compatibility (lowest priority) + final_workspace = "default" + self.db.workspace = final_workspace async def finalize(self): if self.db is not None: @@ -1328,6 +1380,18 @@ class PGDocStatusStorage(DocStatusStorage): async def initialize(self): if self.db is None: self.db = await ClientManager.get_client() + # Implement workspace priority: PostgreSQLDB.workspace > self.workspace > "default" + if self.db.workspace: + # Use PostgreSQLDB's workspace (highest priority) + final_workspace = self.db.workspace + elif hasattr(self, "workspace") and self.workspace: + # Use storage class's workspace (medium priority) + final_workspace = self.workspace + self.db.workspace = final_workspace + else: + # Use "default" for compatibility (lowest priority) + final_workspace = "default" + self.db.workspace = final_workspace async def finalize(self): if self.db is not None: @@ -1606,9 +1670,34 @@ class PGGraphQueryException(Exception): @dataclass class PGGraphStorage(BaseGraphStorage): def __post_init__(self): - self.graph_name = self.namespace or os.environ.get("AGE_GRAPH_NAME", "lightrag") + # Graph name will be dynamically generated in initialize() based on workspace self.db: PostgreSQLDB | None = None + def _get_workspace_graph_name(self) -> str: + """ + Generate graph name based on workspace and namespace for data isolation. + Rules: + - If workspace is empty: graph_name = namespace + - If workspace has value: graph_name = workspace_namespace + + Args: + None + + Returns: + str: The graph name for the current workspace + """ + workspace = getattr(self, "workspace", None) + namespace = self.namespace or os.environ.get("AGE_GRAPH_NAME", "lightrag") + + if workspace and workspace.strip(): + # Ensure names comply with PostgreSQL identifier specifications + safe_workspace = re.sub(r"[^a-zA-Z0-9_]", "_", workspace.strip()) + safe_namespace = re.sub(r"[^a-zA-Z0-9_]", "_", namespace) + return f"{safe_workspace}_{safe_namespace}" + else: + # When workspace is empty, use namespace directly + return re.sub(r"[^a-zA-Z0-9_]", "_", namespace) + @staticmethod def _normalize_node_id(node_id: str) -> str: """ @@ -1629,6 +1718,27 @@ class PGGraphStorage(BaseGraphStorage): async def initialize(self): if self.db is None: self.db = await ClientManager.get_client() + # Implement workspace priority: PostgreSQLDB.workspace > self.workspace > None + if self.db.workspace: + # Use PostgreSQLDB's workspace (highest priority) + final_workspace = self.db.workspace + elif hasattr(self, "workspace") and self.workspace: + # Use storage class's workspace (medium priority) + final_workspace = self.workspace + self.db.workspace = final_workspace + else: + # Use None for compatibility (lowest priority) + final_workspace = None + self.db.workspace = final_workspace + + # Dynamically generate graph name based on workspace + self.workspace = self.db.workspace + self.graph_name = self._get_workspace_graph_name() + + # Log the graph initialization for debugging + logger.info( + f"PostgreSQL Graph initialized: workspace='{self.workspace}', graph_name='{self.graph_name}'" + ) # Execute each statement separately and ignore errors queries = [ @@ -2833,7 +2943,10 @@ class PGGraphStorage(BaseGraphStorage): $$) AS (result agtype)""" await self._query(drop_query, readonly=False) - return {"status": "success", "message": "graph data dropped"} + return { + "status": "success", + "message": f"workspace '{self.workspace}' graph data dropped", + } except Exception as e: logger.error(f"Error dropping graph: {e}") return {"status": "error", "message": str(e)} diff --git a/lightrag/kg/qdrant_impl.py b/lightrag/kg/qdrant_impl.py index dada278a..9cdeff7a 100644 --- a/lightrag/kg/qdrant_impl.py +++ b/lightrag/kg/qdrant_impl.py @@ -50,6 +50,18 @@ def compute_mdhash_id_for_qdrant( @final @dataclass class QdrantVectorDBStorage(BaseVectorStorage): + def __init__( + self, namespace, global_config, embedding_func, workspace=None, meta_fields=None + ): + super().__init__( + namespace=namespace, + workspace=workspace or "", + global_config=global_config, + embedding_func=embedding_func, + meta_fields=meta_fields or set(), + ) + self.__post_init__() + @staticmethod def create_collection_if_not_exist( client: QdrantClient, collection_name: str, **kwargs @@ -59,6 +71,29 @@ class QdrantVectorDBStorage(BaseVectorStorage): client.create_collection(collection_name, **kwargs) def __post_init__(self): + # Check for QDRANT_WORKSPACE environment variable first (higher priority) + # This allows administrators to force a specific workspace for all Qdrant storage instances + qdrant_workspace = os.environ.get("QDRANT_WORKSPACE") + if qdrant_workspace and qdrant_workspace.strip(): + # Use environment variable value, overriding the passed workspace parameter + effective_workspace = qdrant_workspace.strip() + logger.info( + f"Using QDRANT_WORKSPACE environment variable: '{effective_workspace}' (overriding passed workspace: '{self.workspace}')" + ) + else: + # Use the workspace parameter passed during initialization + effective_workspace = self.workspace + if effective_workspace: + logger.debug( + f"Using passed workspace parameter: '{effective_workspace}'" + ) + + # Build namespace with workspace prefix for data isolation + if effective_workspace: + self.namespace = f"{effective_workspace}_{self.namespace}" + logger.debug(f"Final namespace with workspace prefix: '{self.namespace}'") + # When workspace is empty, keep the original namespace unchanged + kwargs = self.global_config.get("vector_db_storage_cls_kwargs", {}) cosine_threshold = kwargs.get("cosine_better_than_threshold") if cosine_threshold is None: diff --git a/lightrag/kg/redis_impl.py b/lightrag/kg/redis_impl.py index dba228ca..06e51384 100644 --- a/lightrag/kg/redis_impl.py +++ b/lightrag/kg/redis_impl.py @@ -71,6 +71,29 @@ class RedisConnectionManager: @dataclass class RedisKVStorage(BaseKVStorage): def __post_init__(self): + # Check for REDIS_WORKSPACE environment variable first (higher priority) + # This allows administrators to force a specific workspace for all Redis storage instances + redis_workspace = os.environ.get("REDIS_WORKSPACE") + if redis_workspace and redis_workspace.strip(): + # Use environment variable value, overriding the passed workspace parameter + effective_workspace = redis_workspace.strip() + logger.info( + f"Using REDIS_WORKSPACE environment variable: '{effective_workspace}' (overriding passed workspace: '{self.workspace}')" + ) + else: + # Use the workspace parameter passed during initialization + effective_workspace = self.workspace + if effective_workspace: + logger.debug( + f"Using passed workspace parameter: '{effective_workspace}'" + ) + + # Build namespace with workspace prefix for data isolation + if effective_workspace: + self.namespace = f"{effective_workspace}_{self.namespace}" + logger.debug(f"Final namespace with workspace prefix: '{self.namespace}'") + # When workspace is empty, keep the original namespace unchanged + redis_url = os.environ.get( "REDIS_URI", config.get("redis", "uri", fallback="redis://localhost:6379") ) @@ -461,6 +484,29 @@ class RedisDocStatusStorage(DocStatusStorage): """Redis implementation of document status storage""" def __post_init__(self): + # Check for REDIS_WORKSPACE environment variable first (higher priority) + # This allows administrators to force a specific workspace for all Redis storage instances + redis_workspace = os.environ.get("REDIS_WORKSPACE") + if redis_workspace and redis_workspace.strip(): + # Use environment variable value, overriding the passed workspace parameter + effective_workspace = redis_workspace.strip() + logger.info( + f"Using REDIS_WORKSPACE environment variable: '{effective_workspace}' (overriding passed workspace: '{self.workspace}')" + ) + else: + # Use the workspace parameter passed during initialization + effective_workspace = self.workspace + if effective_workspace: + logger.debug( + f"Using passed workspace parameter: '{effective_workspace}'" + ) + + # Build namespace with workspace prefix for data isolation + if effective_workspace: + self.namespace = f"{effective_workspace}_{self.namespace}" + logger.debug(f"Final namespace with workspace prefix: '{self.namespace}'") + # When workspace is empty, keep the original namespace unchanged + redis_url = os.environ.get( "REDIS_URI", config.get("redis", "uri", fallback="redis://localhost:6379") ) diff --git a/lightrag/lightrag.py b/lightrag/lightrag.py index 2ab9f89a..5d96aeba 100644 --- a/lightrag/lightrag.py +++ b/lightrag/lightrag.py @@ -51,7 +51,7 @@ from .base import ( StoragesStatus, DeletionResult, ) -from .namespace import NameSpace, make_namespace +from .namespace import NameSpace from .operate import ( chunking_by_token_size, extract_entities, @@ -97,9 +97,7 @@ class LightRAG: # Directory # --- - working_dir: str = field( - default=f"./lightrag_cache_{datetime.now().strftime('%Y-%m-%d-%H:%M:%S')}" - ) + working_dir: str = field(default="./rag_storage") """Directory where cache and temporary files are stored.""" # Storage @@ -117,6 +115,12 @@ class LightRAG: doc_status_storage: str = field(default="JsonDocStatusStorage") """Storage type for tracking document processing statuses.""" + # Workspace + # --- + + workspace: str = field(default_factory=lambda: os.getenv("WORKSPACE", "")) + """Workspace for data isolation. Defaults to empty string if WORKSPACE environment variable is not set.""" + # Logging (Deprecated, use setup_logger in utils.py instead) # --- log_level: int | None = field(default=None) @@ -242,10 +246,6 @@ class LightRAG: vector_db_storage_cls_kwargs: dict[str, Any] = field(default_factory=dict) """Additional parameters for vector database storage.""" - # TODO:deprecated, remove in the future, use WORKSPACE instead - namespace_prefix: str = field(default="") - """Prefix for namespacing stored data across different environments.""" - enable_llm_cache: bool = field(default=True) """Enables caching for LLM responses to avoid redundant computations.""" @@ -382,61 +382,53 @@ class LightRAG: self.doc_status_storage_cls = self._get_storage_class(self.doc_status_storage) self.llm_response_cache: BaseKVStorage = self.key_string_value_json_storage_cls( # type: ignore - namespace=make_namespace( - self.namespace_prefix, NameSpace.KV_STORE_LLM_RESPONSE_CACHE - ), - global_config=asdict( - self - ), # Add global_config to ensure cache works properly + namespace=NameSpace.KV_STORE_LLM_RESPONSE_CACHE, + workspace=self.workspace, + global_config=global_config, embedding_func=self.embedding_func, ) self.full_docs: BaseKVStorage = self.key_string_value_json_storage_cls( # type: ignore - namespace=make_namespace( - self.namespace_prefix, NameSpace.KV_STORE_FULL_DOCS - ), + namespace=NameSpace.KV_STORE_FULL_DOCS, + workspace=self.workspace, embedding_func=self.embedding_func, ) self.text_chunks: BaseKVStorage = self.key_string_value_json_storage_cls( # type: ignore - namespace=make_namespace( - self.namespace_prefix, NameSpace.KV_STORE_TEXT_CHUNKS - ), + namespace=NameSpace.KV_STORE_TEXT_CHUNKS, + workspace=self.workspace, embedding_func=self.embedding_func, ) self.chunk_entity_relation_graph: BaseGraphStorage = self.graph_storage_cls( # type: ignore - namespace=make_namespace( - self.namespace_prefix, NameSpace.GRAPH_STORE_CHUNK_ENTITY_RELATION - ), + namespace=NameSpace.GRAPH_STORE_CHUNK_ENTITY_RELATION, + workspace=self.workspace, embedding_func=self.embedding_func, ) self.entities_vdb: BaseVectorStorage = self.vector_db_storage_cls( # type: ignore - namespace=make_namespace( - self.namespace_prefix, NameSpace.VECTOR_STORE_ENTITIES - ), + namespace=NameSpace.VECTOR_STORE_ENTITIES, + workspace=self.workspace, embedding_func=self.embedding_func, meta_fields={"entity_name", "source_id", "content", "file_path"}, ) self.relationships_vdb: BaseVectorStorage = self.vector_db_storage_cls( # type: ignore - namespace=make_namespace( - self.namespace_prefix, NameSpace.VECTOR_STORE_RELATIONSHIPS - ), + namespace=NameSpace.VECTOR_STORE_RELATIONSHIPS, + workspace=self.workspace, embedding_func=self.embedding_func, meta_fields={"src_id", "tgt_id", "source_id", "content", "file_path"}, ) self.chunks_vdb: BaseVectorStorage = self.vector_db_storage_cls( # type: ignore - namespace=make_namespace( - self.namespace_prefix, NameSpace.VECTOR_STORE_CHUNKS - ), + namespace=NameSpace.VECTOR_STORE_CHUNKS, + workspace=self.workspace, embedding_func=self.embedding_func, meta_fields={"full_doc_id", "content", "file_path"}, ) # Initialize document status storage self.doc_status: DocStatusStorage = self.doc_status_storage_cls( - namespace=make_namespace(self.namespace_prefix, NameSpace.DOC_STATUS), + namespace=NameSpace.DOC_STATUS, + workspace=self.workspace, global_config=global_config, embedding_func=None, ) @@ -965,6 +957,9 @@ class LightRAG: ) } + if not chunks: + logger.warning("No document chunks to process") + # Process document in two stages # Stage 1: Process text chunks and docs (parallel execution) doc_status_task = asyncio.create_task( diff --git a/lightrag/namespace.py b/lightrag/namespace.py index 77e04c9e..657d65ac 100644 --- a/lightrag/namespace.py +++ b/lightrag/namespace.py @@ -17,10 +17,6 @@ class NameSpace: DOC_STATUS = "doc_status" -def make_namespace(prefix: str, base_namespace: str): - return prefix + base_namespace - - def is_namespace(namespace: str, base_namespace: str | Iterable[str]): if isinstance(base_namespace, str): return namespace.endswith(base_namespace) diff --git a/lightrag_webui/src/api/lightrag.ts b/lightrag_webui/src/api/lightrag.ts index 8fa25d43..24b299aa 100644 --- a/lightrag_webui/src/api/lightrag.ts +++ b/lightrag_webui/src/api/lightrag.ts @@ -40,6 +40,8 @@ export type LightragStatus = { doc_status_storage: string graph_storage: string vector_storage: string + workspace?: string + max_graph_nodes?: string } update_status?: Record core_version?: string diff --git a/lightrag_webui/src/components/status/StatusCard.tsx b/lightrag_webui/src/components/status/StatusCard.tsx index c9e64db9..afdd554f 100644 --- a/lightrag_webui/src/components/status/StatusCard.tsx +++ b/lightrag_webui/src/components/status/StatusCard.tsx @@ -56,6 +56,10 @@ const StatusCard = ({ status }: { status: LightragStatus | null }) => { {status.configuration.graph_storage} {t('graphPanel.statusCard.vectorStorage')}: {status.configuration.vector_storage} + {t('graphPanel.statusCard.workspace')}: + {status.configuration.workspace || '-'} + {t('graphPanel.statusCard.maxGraphNodes')}: + {status.configuration.max_graph_nodes || '-'} diff --git a/lightrag_webui/src/locales/ar.json b/lightrag_webui/src/locales/ar.json index 456fac32..7751c05c 100644 --- a/lightrag_webui/src/locales/ar.json +++ b/lightrag_webui/src/locales/ar.json @@ -263,7 +263,9 @@ "kvStorage": "تخزين المفتاح-القيمة", "docStatusStorage": "تخزين حالة المستند", "graphStorage": "تخزين الرسم البياني", - "vectorStorage": "تخزين المتجهات" + "vectorStorage": "تخزين المتجهات", + "workspace": "مساحة العمل", + "maxGraphNodes": "الحد الأقصى لعقد الرسم البياني" }, "propertiesView": { "editProperty": "تعديل {{property}}", diff --git a/lightrag_webui/src/locales/en.json b/lightrag_webui/src/locales/en.json index ee64c1d8..726ae5b9 100644 --- a/lightrag_webui/src/locales/en.json +++ b/lightrag_webui/src/locales/en.json @@ -263,7 +263,9 @@ "kvStorage": "KV Storage", "docStatusStorage": "Doc Status Storage", "graphStorage": "Graph Storage", - "vectorStorage": "Vector Storage" + "vectorStorage": "Vector Storage", + "workspace": "Workspace", + "maxGraphNodes": "Max Graph Nodes" }, "propertiesView": { "editProperty": "Edit {{property}}", diff --git a/lightrag_webui/src/locales/fr.json b/lightrag_webui/src/locales/fr.json index 6ca00f55..96a85fac 100644 --- a/lightrag_webui/src/locales/fr.json +++ b/lightrag_webui/src/locales/fr.json @@ -263,7 +263,9 @@ "kvStorage": "Stockage clé-valeur", "docStatusStorage": "Stockage de l'état des documents", "graphStorage": "Stockage du graphe", - "vectorStorage": "Stockage vectoriel" + "vectorStorage": "Stockage vectoriel", + "workspace": "Espace de travail", + "maxGraphNodes": "Nombre maximum de nœuds du graphe" }, "propertiesView": { "editProperty": "Modifier {{property}}", diff --git a/lightrag_webui/src/locales/zh.json b/lightrag_webui/src/locales/zh.json index 4ec466e2..fa72ba1f 100644 --- a/lightrag_webui/src/locales/zh.json +++ b/lightrag_webui/src/locales/zh.json @@ -263,7 +263,9 @@ "kvStorage": "KV存储", "docStatusStorage": "文档状态存储", "graphStorage": "图存储", - "vectorStorage": "向量存储" + "vectorStorage": "向量存储", + "workspace": "工作空间", + "maxGraphNodes": "最大图节点数" }, "propertiesView": { "editProperty": "编辑{{property}}", diff --git a/lightrag_webui/src/locales/zh_TW.json b/lightrag_webui/src/locales/zh_TW.json index 18578e92..40480fd5 100644 --- a/lightrag_webui/src/locales/zh_TW.json +++ b/lightrag_webui/src/locales/zh_TW.json @@ -263,7 +263,9 @@ "kvStorage": "KV 儲存", "docStatusStorage": "文件狀態儲存", "graphStorage": "圖形儲存", - "vectorStorage": "向量儲存" + "vectorStorage": "向量儲存", + "workspace": "工作空間", + "maxGraphNodes": "最大圖形節點數" }, "propertiesView": { "editProperty": "編輯{{property}}", diff --git a/pyproject.toml b/pyproject.toml index b87df3bc..2bb1f288 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ authors = [ description = "LightRAG: Simple and Fast Retrieval-Augmented Generation" readme = "README.md" license = {text = "MIT"} -requires-python = ">=3.9" +requires-python = ">=3.10" classifiers = [ "Development Status :: 4 - Beta", "Programming Language :: Python :: 3", @@ -91,3 +91,6 @@ version = {attr = "lightrag.__version__"} [tool.setuptools.package-data] lightrag = ["api/webui/**/*"] + +[tool.ruff] +target-version = "py310" diff --git a/reproduce/Step_3.py b/reproduce/Step_3.py index facb913e..f3aae83e 100644 --- a/reproduce/Step_3.py +++ b/reproduce/Step_3.py @@ -28,9 +28,10 @@ def run_queries_and_save_to_json( ): loop = always_get_an_event_loop() - with open(output_file, "a", encoding="utf-8") as result_file, open( - error_file, "a", encoding="utf-8" - ) as err_file: + with ( + open(output_file, "a", encoding="utf-8") as result_file, + open(error_file, "a", encoding="utf-8") as err_file, + ): result_file.write("[\n") first_entry = True diff --git a/reproduce/Step_3_openai_compatible.py b/reproduce/Step_3_openai_compatible.py index 885220fa..56159ee1 100644 --- a/reproduce/Step_3_openai_compatible.py +++ b/reproduce/Step_3_openai_compatible.py @@ -59,9 +59,10 @@ def run_queries_and_save_to_json( ): loop = always_get_an_event_loop() - with open(output_file, "a", encoding="utf-8") as result_file, open( - error_file, "a", encoding="utf-8" - ) as err_file: + with ( + open(output_file, "a", encoding="utf-8") as result_file, + open(error_file, "a", encoding="utf-8") as err_file, + ): result_file.write("[\n") first_entry = True