diff --git a/env.example b/env.example index 66d209ad..86b4481f 100644 --- a/env.example +++ b/env.example @@ -151,9 +151,9 @@ QDRANT_URL=http://localhost:16333 ### Redis REDIS_URI=redis://localhost:6379 -# For jwt auth -AUTH_USERNAME=admin # login name -AUTH_PASSWORD=admin123 # password -TOKEN_SECRET=your-key # JWT key -TOKEN_EXPIRE_HOURS=4 # expire duration +### For JWTt Auth +AUTH_USERNAME=admin # login name +AUTH_PASSWORD=admin123 # password +TOKEN_SECRET=your-key-for-LightRAG-API-Server # JWT key +TOKEN_EXPIRE_HOURS=4 # expire duration WHITELIST_PATHS=/login,/health # white list diff --git a/lightrag/api/auth.py b/lightrag/api/auth.py index 4d905de8..78a1da1a 100644 --- a/lightrag/api/auth.py +++ b/lightrag/api/auth.py @@ -6,8 +6,10 @@ from pydantic import BaseModel class TokenPayload(BaseModel): - sub: str - exp: datetime + sub: str # Username + exp: datetime # Expiration time + role: str = "user" # User role, default is regular user + metadata: dict = {} # Additional metadata class AuthHandler: @@ -15,13 +17,60 @@ class AuthHandler: self.secret = os.getenv("TOKEN_SECRET", "4f85ds4f56dsf46") self.algorithm = "HS256" self.expire_hours = int(os.getenv("TOKEN_EXPIRE_HOURS", 4)) + self.guest_expire_hours = int( + os.getenv("GUEST_TOKEN_EXPIRE_HOURS", 2) + ) # Guest token default expiration time + + def create_token( + self, + username: str, + role: str = "user", + custom_expire_hours: int = None, + metadata: dict = None, + ) -> str: + """ + Create JWT token + + Args: + username: Username + role: User role, default is "user", guest is "guest" + custom_expire_hours: Custom expiration time (hours), if None use default value + metadata: Additional metadata + + Returns: + str: Encoded JWT token + """ + # Choose default expiration time based on role + if custom_expire_hours is None: + if role == "guest": + expire_hours = self.guest_expire_hours + else: + expire_hours = self.expire_hours + else: + expire_hours = custom_expire_hours + + expire = datetime.utcnow() + timedelta(hours=expire_hours) + + # Create payload + payload = TokenPayload( + sub=username, exp=expire, role=role, metadata=metadata or {} + ) - def create_token(self, username: str) -> str: - expire = datetime.utcnow() + timedelta(hours=self.expire_hours) - payload = TokenPayload(sub=username, exp=expire) return jwt.encode(payload.dict(), self.secret, algorithm=self.algorithm) - def validate_token(self, token: str) -> str: + def validate_token(self, token: str) -> dict: + """ + Validate JWT token + + Args: + token: JWT token + + Returns: + dict: Dictionary containing user information + + Raises: + HTTPException: If token is invalid or expired + """ try: payload = jwt.decode(token, self.secret, algorithms=[self.algorithm]) expire_timestamp = payload["exp"] @@ -31,7 +80,14 @@ class AuthHandler: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Token expired" ) - return payload["sub"] + + # Return complete payload instead of just username + return { + "username": payload["sub"], + "role": payload.get("role", "user"), + "metadata": payload.get("metadata", {}), + "exp": expire_time, + } except jwt.PyJWTError: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token" diff --git a/lightrag/api/lightrag_server.py b/lightrag/api/lightrag_server.py index ca4425e5..4d4896fc 100644 --- a/lightrag/api/lightrag_server.py +++ b/lightrag/api/lightrag_server.py @@ -10,6 +10,7 @@ import logging.config import uvicorn import pipmaster as pm from fastapi.staticfiles import StaticFiles +from fastapi.responses import RedirectResponse from pathlib import Path import configparser from ascii_colors import ASCIIColors @@ -341,25 +342,62 @@ def create_app(args): ollama_api = OllamaAPI(rag, top_k=args.top_k) app.include_router(ollama_api.router, prefix="/api") - @app.post("/login") + @app.get("/") + async def redirect_to_webui(): + """Redirect root path to /webui""" + return RedirectResponse(url="/webui") + + @app.get("/auth-status", dependencies=[Depends(optional_api_key)]) + async def get_auth_status(): + """Get authentication status and guest token if auth is not configured""" + username = os.getenv("AUTH_USERNAME") + password = os.getenv("AUTH_PASSWORD") + + if not (username and password): + # Authentication not configured, return guest token + guest_token = auth_handler.create_token( + username="guest", role="guest", metadata={"auth_mode": "disabled"} + ) + return { + "auth_configured": False, + "access_token": guest_token, + "token_type": "bearer", + "auth_mode": "disabled", + "message": "Authentication is disabled. Using guest access.", + } + + return {"auth_configured": True, "auth_mode": "enabled"} + + @app.post("/login", dependencies=[Depends(optional_api_key)]) async def login(form_data: OAuth2PasswordRequestForm = Depends()): username = os.getenv("AUTH_USERNAME") password = os.getenv("AUTH_PASSWORD") if not (username and password): - raise HTTPException( - status_code=status.HTTP_501_NOT_IMPLEMENTED, - detail="Authentication not configured", + # Authentication not configured, return guest token + guest_token = auth_handler.create_token( + username="guest", role="guest", metadata={"auth_mode": "disabled"} ) + return { + "access_token": guest_token, + "token_type": "bearer", + "auth_mode": "disabled", + "message": "Authentication is disabled. Using guest access.", + } if form_data.username != username or form_data.password != password: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect credentials" ) + # Regular user login + user_token = auth_handler.create_token( + username=username, role="user", metadata={"auth_mode": "enabled"} + ) return { - "access_token": auth_handler.create_token(username), + "access_token": user_token, "token_type": "bearer", + "auth_mode": "enabled", } @app.get("/health", dependencies=[Depends(optional_api_key)]) diff --git a/lightrag/api/utils_api.py b/lightrag/api/utils_api.py index 88a0132c..adf855cc 100644 --- a/lightrag/api/utils_api.py +++ b/lightrag/api/utils_api.py @@ -9,7 +9,7 @@ import sys import logging from ascii_colors import ASCIIColors from lightrag.api import __api_version__ -from fastapi import HTTPException, Security, Depends, Request +from fastapi import HTTPException, Security, Depends, Request, status from dotenv import load_dotenv from fastapi.security import APIKeyHeader, OAuth2PasswordBearer from starlette.status import HTTP_403_FORBIDDEN @@ -35,7 +35,8 @@ ollama_server_infos = OllamaServerInfos() def get_auth_dependency(): - whitelist = os.getenv("WHITELIST_PATHS", "").split(",") + # Set default whitelist paths + whitelist = os.getenv("WHITELIST_PATHS", "/login,/health").split(",") async def dependency( request: Request, @@ -44,10 +45,43 @@ def get_auth_dependency(): if request.url.path in whitelist: return - if not (os.getenv("AUTH_USERNAME") and os.getenv("AUTH_PASSWORD")): + # Check if authentication is configured + auth_configured = bool( + os.getenv("AUTH_USERNAME") and os.getenv("AUTH_PASSWORD") + ) + + # If authentication is not configured, accept any token including guest tokens + if not auth_configured: + if token: # If token is provided, still validate it + try: + # Validate token but don't raise exception + token_info = auth_handler.validate_token(token) + # Check if it's a guest token + if token_info.get("role") != "guest": + # Non-guest tokens are not valid when auth is not configured + pass + except Exception as e: + # Ignore validation errors but log them + print(f"Token validation error (ignored): {str(e)}") return - auth_handler.validate_token(token) + # If authentication is configured, validate the token and reject guest tokens + if not token: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail="Token required" + ) + + token_info = auth_handler.validate_token(token) + + # Reject guest tokens when authentication is configured + if token_info.get("role") == "guest": + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Authentication required. Guest access not allowed when authentication is configured.", + ) + + # At this point, we have a valid non-guest token + return return dependency diff --git a/lightrag/api/webui/assets/index-BV5s8k-a.css b/lightrag/api/webui/assets/index-BV5s8k-a.css deleted file mode 100644 index 8dca5fe7..00000000 --- a/lightrag/api/webui/assets/index-BV5s8k-a.css +++ /dev/null @@ -1 +0,0 @@ -/*! tailwindcss v4.0.8 | MIT License | https://tailwindcss.com */@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-100:oklch(.936 .032 17.717);--color-red-400:oklch(.704 .191 22.216);--color-red-500:oklch(.637 .237 25.331);--color-red-600:oklch(.577 .245 27.325);--color-red-700:oklch(.505 .213 27.518);--color-red-950:oklch(.258 .092 26.042);--color-yellow-400:oklch(.852 .199 91.936);--color-yellow-600:oklch(.681 .162 75.834);--color-green-500:oklch(.723 .219 149.579);--color-green-600:oklch(.627 .194 149.214);--color-emerald-400:oklch(.765 .177 163.223);--color-teal-600:oklch(.6 .118 184.704);--color-sky-300:oklch(.828 .111 230.318);--color-blue-600:oklch(.546 .245 262.881);--color-gray-100:oklch(.967 .003 264.542);--color-gray-400:oklch(.707 .022 261.325);--color-zinc-50:oklch(.985 0 0);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-lg:32rem;--container-xl:36rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-widest:.1em;--leading-relaxed:1.625;--radius-xs:.125rem;--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-lg:16px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-font-feature-settings:var(--font-sans--font-feature-settings);--default-font-variation-settings:var(--font-sans--font-variation-settings);--default-mono-font-family:var(--font-mono);--default-mono-font-feature-settings:var(--font-mono--font-feature-settings);--default-mono-font-variation-settings:var(--font-mono--font-variation-settings)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}body{line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1;color:color-mix(in oklab,currentColor 50%,transparent)}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:color-mix(in oklab,var(--ring)50%,transparent)}body{background-color:var(--background);color:var(--foreground)}*{scrollbar-color:initial;scrollbar-width:initial}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing)*0)}.top-0{top:calc(var(--spacing)*0)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing)*2)}.top-4{top:calc(var(--spacing)*4)}.top-12{top:calc(var(--spacing)*12)}.top-\[50\%\]{top:50%}.right-0{right:calc(var(--spacing)*0)}.right-2{right:calc(var(--spacing)*2)}.right-4{right:calc(var(--spacing)*4)}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-2{bottom:calc(var(--spacing)*2)}.bottom-4{bottom:calc(var(--spacing)*4)}.left-0{left:calc(var(--spacing)*0)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.left-\[50\%\]{left:50%}.left-\[calc\(2rem\+2\.5rem\)\]{left:4.5rem}.z-10{z-index:10}.z-50{z-index:50}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.\!m-0{margin:calc(var(--spacing)*0)!important}.m-0{margin:calc(var(--spacing)*0)}.-mx-1{margin-inline:calc(var(--spacing)*-1)}.mx-1{margin-inline:calc(var(--spacing)*1)}.my-1{margin-block:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-4{margin-top:calc(var(--spacing)*4)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-2{margin-right:calc(var(--spacing)*2)}.mr-4{margin-right:calc(var(--spacing)*4)}.mr-6{margin-right:calc(var(--spacing)*6)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\!inline{display:inline!important}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.aspect-square{aspect-ratio:1}.\!size-full{width:100%!important;height:100%!important}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-7{width:calc(var(--spacing)*7);height:calc(var(--spacing)*7)}.size-8{width:calc(var(--spacing)*8);height:calc(var(--spacing)*8)}.size-10{width:calc(var(--spacing)*10);height:calc(var(--spacing)*10)}.size-full{width:100%;height:100%}.h-1\/2{height:50%}.h-2\.5{height:calc(var(--spacing)*2.5)}.h-3{height:calc(var(--spacing)*3)}.h-3\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.h-24{height:calc(var(--spacing)*24)}.h-52{height:calc(var(--spacing)*52)}.h-\[1px\]{height:1px}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-fit{height:fit-content}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-8{max-height:calc(var(--spacing)*8)}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-96{max-height:calc(var(--spacing)*96)}.max-h-\[60vh\]{max-height:60vh}.max-h-\[300px\]{max-height:300px}.max-h-full{max-height:100%}.min-h-0{min-height:calc(var(--spacing)*0)}.w-0{width:calc(var(--spacing)*0)}.w-2\.5{width:calc(var(--spacing)*2.5)}.w-3{width:calc(var(--spacing)*3)}.w-3\.5{width:calc(var(--spacing)*3.5)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-16{width:calc(var(--spacing)*16)}.w-24{width:calc(var(--spacing)*24)}.w-56{width:calc(var(--spacing)*56)}.w-\[1px\]{width:1px}.w-auto{width:auto}.w-full{width:100%}.w-screen{width:100vw}.max-w-80{max-width:calc(var(--spacing)*80)}.max-w-\[80\%\]{max-width:80%}.max-w-lg{max-width:var(--container-lg)}.max-w-none{max-width:none}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-24{min-width:calc(var(--spacing)*24)}.min-w-\[8rem\]{min-width:8rem}.min-w-\[180px\]{min-width:180px}.min-w-\[300px\]{min-width:300px}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.flex-1{flex:1}.flex-auto{flex:auto}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.caption-bottom{caption-side:bottom}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-\[-50\%\]{--tw-translate-x:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-20{--tw-translate-y:calc(var(--spacing)*-20);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-0{--tw-translate-y:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-\[-50\%\]{--tw-translate-y:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)}.scale-125{--tw-scale-x:125%;--tw-scale-y:125%;--tw-scale-z:125%;scale:var(--tw-scale-x)var(--tw-scale-y)}.transform{transform:var(--tw-rotate-x)var(--tw-rotate-y)var(--tw-rotate-z)var(--tw-skew-x)var(--tw-skew-y)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-help{cursor:help}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.\[appearance\:textfield\]{-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.place-items-center{place-items:center}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\.5{gap:calc(var(--spacing)*2.5)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.gap-px{gap:1px}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}.self-center{align-self:center}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.\!rounded-none{border-radius:0!important}.rounded{border-radius:.25rem}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.rounded-xs{border-radius:var(--radius-xs)}.rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.rounded-tr-none{border-top-right-radius:0}.rounded-br-none{border-bottom-right-radius:0}.border,.border-1{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-4{border-style:var(--tw-border-style);border-width:4px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.\!border-none{--tw-border-style:none;border-style:none!important}.border-dashed{--tw-border-style:dashed;border-style:dashed}.\!border-input{border-color:var(--input)!important}.border-border\/40{border-color:color-mix(in oklab,var(--border)40%,transparent)}.border-destructive\/50{border-color:color-mix(in oklab,var(--destructive)50%,transparent)}.border-input{border-color:var(--input)}.border-muted-foreground\/25{border-color:color-mix(in oklab,var(--muted-foreground)25%,transparent)}.border-muted-foreground\/50{border-color:color-mix(in oklab,var(--muted-foreground)50%,transparent)}.border-primary{border-color:var(--primary)}.border-transparent{border-color:#0000}.border-t-transparent{border-top-color:#0000}.border-l-transparent{border-left-color:#0000}.\!bg-background{background-color:var(--background)!important}.\!bg-emerald-400{background-color:var(--color-emerald-400)!important}.bg-background{background-color:var(--background)}.bg-background\/60{background-color:color-mix(in oklab,var(--background)60%,transparent)}.bg-background\/80{background-color:color-mix(in oklab,var(--background)80%,transparent)}.bg-background\/90{background-color:color-mix(in oklab,var(--background)90%,transparent)}.bg-background\/95{background-color:color-mix(in oklab,var(--background)95%,transparent)}.bg-black\/10{background-color:color-mix(in oklab,var(--color-black)10%,transparent)}.bg-black\/80{background-color:color-mix(in oklab,var(--color-black)80%,transparent)}.bg-border{background-color:var(--border)}.bg-card{background-color:var(--card)}.bg-destructive{background-color:var(--destructive)}.bg-foreground\/10{background-color:color-mix(in oklab,var(--foreground)10%,transparent)}.bg-green-500{background-color:var(--color-green-500)}.bg-muted{background-color:var(--muted)}.bg-muted\/50{background-color:color-mix(in oklab,var(--muted)50%,transparent)}.bg-popover{background-color:var(--popover)}.bg-primary{background-color:var(--primary)}.bg-primary-foreground\/60{background-color:color-mix(in oklab,var(--primary-foreground)60%,transparent)}.bg-primary\/5{background-color:color-mix(in oklab,var(--primary)5%,transparent)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-700{background-color:var(--color-red-700)}.bg-secondary{background-color:var(--secondary)}.bg-transparent{background-color:#0000}.object-cover{object-fit:cover}.\!p-0{padding:calc(var(--spacing)*0)!important}.\!p-2{padding:calc(var(--spacing)*2)!important}.p-0{padding:calc(var(--spacing)*0)}.p-1{padding:calc(var(--spacing)*1)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.p-16{padding:calc(var(--spacing)*16)}.p-\[1px\]{padding:1px}.px-1{padding-inline:calc(var(--spacing)*1)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.px-8{padding-inline:calc(var(--spacing)*8)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-6{padding-block:calc(var(--spacing)*6)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-4{padding-top:calc(var(--spacing)*4)}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-2{padding-right:calc(var(--spacing)*2)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-12{padding-bottom:calc(var(--spacing)*12)}.pl-1{padding-left:calc(var(--spacing)*1)}.pl-8{padding-left:calc(var(--spacing)*8)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.text-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.\!text-zinc-50{color:var(--color-zinc-50)!important}.text-blue-600{color:var(--color-blue-600)}.text-card-foreground{color:var(--card-foreground)}.text-current{color:currentColor}.text-destructive{color:var(--destructive)}.text-destructive-foreground{color:var(--destructive-foreground)}.text-emerald-400{color:var(--color-emerald-400)}.text-foreground{color:var(--foreground)}.text-foreground\/80{color:color-mix(in oklab,var(--foreground)80%,transparent)}.text-gray-400{color:var(--color-gray-400)}.text-green-600{color:var(--color-green-600)}.text-muted-foreground{color:var(--muted-foreground)}.text-muted-foreground\/70{color:color-mix(in oklab,var(--muted-foreground)70%,transparent)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-primary\/60{color:color-mix(in oklab,var(--primary)60%,transparent)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-sky-300{color:var(--color-sky-300)}.text-teal-600{color:var(--color-teal-600)}.text-teal-600\/90{color:color-mix(in oklab,var(--color-teal-600)90%,transparent)}.text-white{color:var(--color-white)}.text-yellow-400\/90{color:color-mix(in oklab,var(--color-yellow-400)90%,transparent)}.text-yellow-600{color:var(--color-yellow-600)}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-20{opacity:.2}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_8px_rgba\(0\,0\,0\,0\.2\)\]{--tw-shadow:0 0 8px var(--tw-shadow-color,#0003);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_12px_rgba\(34\,197\,94\,0\.4\)\]{--tw-shadow:0 0 12px var(--tw-shadow-color,#22c55e66);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_12px_rgba\(239\,68\,68\,0\.4\)\]{--tw-shadow:0 0 12px var(--tw-shadow-color,#ef444466);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-offset-background{--tw-ring-offset-color:var(--background)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.backdrop-blur-lg{--tw-backdrop-blur:blur(var(--blur-lg));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.duration-2000{--tw-duration:2s;transition-duration:2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.animate-in{--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial;animation-name:enter;animation-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.duration-200{animation-duration:.2s}.duration-300{animation-duration:.3s}.duration-500{animation-duration:.5s}.duration-2000{animation-duration:2s}.ease-in-out{animation-timing-function:cubic-bezier(.4,0,.2,1)}.fade-in-0{--tw-enter-opacity:0}.zoom-in-95{--tw-enter-scale:.95}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.peer-disabled\:opacity-70:is(:where(.peer):disabled~*){opacity:.7}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--foreground)}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}@media (hover:hover){.hover\:w-fit:hover{width:fit-content}.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:bg-background\/60:hover{background-color:color-mix(in oklab,var(--background)60%,transparent)}.hover\:bg-destructive\/80:hover{background-color:color-mix(in oklab,var(--destructive)80%,transparent)}.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab,var(--destructive)90%,transparent)}.hover\:bg-muted\/25:hover{background-color:color-mix(in oklab,var(--muted)25%,transparent)}.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab,var(--muted)50%,transparent)}.hover\:bg-primary\/5:hover{background-color:color-mix(in oklab,var(--primary)5%,transparent)}.hover\:bg-primary\/20:hover{background-color:color-mix(in oklab,var(--primary)20%,transparent)}.hover\:bg-primary\/80:hover{background-color:color-mix(in oklab,var(--primary)80%,transparent)}.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--primary)90%,transparent)}.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab,var(--secondary)80%,transparent)}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}}.focus\:bg-accent:focus{background-color:var(--accent)}.focus\:text-accent-foreground:focus{color:var(--accent-foreground)}.focus\:ring-0:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-ring:focus{--tw-ring-color:var(--ring)}.focus\:ring-offset-0:focus{--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:outline-0:focus{outline-style:var(--tw-outline-style);outline-width:0}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:relative:focus-visible{position:relative}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentColor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--ring)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.active\:right-0:active{right:calc(var(--spacing)*0)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[disabled\=true\]\:pointer-events-none[data-disabled=true]{pointer-events:none}.data-\[disabled\=true\]\:opacity-50[data-disabled=true]{opacity:.5}.data-\[selected\=\'true\'\]\:bg-accent[data-selected=true]{background-color:var(--accent)}.data-\[selected\=true\]\:text-accent-foreground[data-selected=true]{color:var(--accent-foreground)}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y:calc(var(--spacing)*1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=bottom\]\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y:-.5rem}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=left\]\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x:.5rem}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x:calc(var(--spacing)*1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=right\]\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x:-.5rem}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=top\]\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y:.5rem}.data-\[state\=active\]\:visible[data-state=active]{visibility:visible}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:var(--background)}.data-\[state\=active\]\:text-foreground[data-state=active]{color:var(--foreground)}.data-\[state\=active\]\:shadow-sm[data-state=active]{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:var(--primary)}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:var(--primary-foreground)}.data-\[state\=closed\]\:animate-out[data-state=closed]{--tw-exit-opacity:initial;--tw-exit-scale:initial;--tw-exit-rotate:initial;--tw-exit-translate-x:initial;--tw-exit-translate-y:initial;animation-name:exit;animation-duration:.15s}.data-\[state\=closed\]\:fade-out-0[data-state=closed]{--tw-exit-opacity:0}.data-\[state\=closed\]\:slide-out-to-top-\[48\%\][data-state=closed]{--tw-exit-translate-y:-48%}.data-\[state\=closed\]\:zoom-out-95[data-state=closed]{--tw-exit-scale:.95}.data-\[state\=inactive\]\:invisible[data-state=inactive]{visibility:hidden}.data-\[state\=open\]\:bg-accent[data-state=open]{background-color:var(--accent)}.data-\[state\=open\]\:text-muted-foreground[data-state=open]{color:var(--muted-foreground)}.data-\[state\=open\]\:animate-in[data-state=open]{--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial;animation-name:enter;animation-duration:.15s}.data-\[state\=open\]\:fade-in-0[data-state=open]{--tw-enter-opacity:0}.data-\[state\=open\]\:slide-in-from-top-\[48\%\][data-state=open]{--tw-enter-translate-y:-48%}.data-\[state\=open\]\:zoom-in-95[data-state=open]{--tw-enter-scale:.95}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:var(--muted)}@supports ((-webkit-backdrop-filter:var(--tw)) or (backdrop-filter:var(--tw))){.supports-\[backdrop-filter\]\:bg-background\/60{background-color:color-mix(in oklab,var(--background)60%,transparent)}}@media (width>=40rem){.sm\:mt-0{margin-top:calc(var(--spacing)*0)}.sm\:max-w-xl{max-width:var(--container-xl)}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}:where(.sm\:space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:var(--radius)}.sm\:px-5{padding-inline:calc(var(--spacing)*5)}.sm\:text-left{text-align:left}}@media (width>=48rem){.md\:inline-block{display:inline-block}.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.dark\:border-destructive:is(.dark *){border-color:var(--destructive)}.dark\:bg-gray-100\/20:is(.dark *){background-color:color-mix(in oklab,var(--color-gray-100)20%,transparent)}.dark\:bg-red-950:is(.dark *){background-color:var(--color-red-950)}.dark\:text-red-400:is(.dark *){color:var(--color-red-400)}.\[\&_\[cmdk-group-heading\]\]\:px-2 [cmdk-group-heading]{padding-inline:calc(var(--spacing)*2)}.\[\&_\[cmdk-group-heading\]\]\:py-1\.5 [cmdk-group-heading]{padding-block:calc(var(--spacing)*1.5)}.\[\&_\[cmdk-group-heading\]\]\:text-xs [cmdk-group-heading]{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\[\&_\[cmdk-group-heading\]\]\:font-medium [cmdk-group-heading]{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.\[\&_\[cmdk-group-heading\]\]\:text-muted-foreground [cmdk-group-heading]{color:var(--muted-foreground)}.\[\&_\[cmdk-group\]\]\:px-2 [cmdk-group]{padding-inline:calc(var(--spacing)*2)}.\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0 [cmdk-group]:not([hidden])~[cmdk-group]{padding-top:calc(var(--spacing)*0)}.\[\&_\[cmdk-input-wrapper\]_svg\]\:h-5 [cmdk-input-wrapper] svg{height:calc(var(--spacing)*5)}.\[\&_\[cmdk-input-wrapper\]_svg\]\:w-5 [cmdk-input-wrapper] svg{width:calc(var(--spacing)*5)}.\[\&_\[cmdk-input\]\]\:h-12 [cmdk-input]{height:calc(var(--spacing)*12)}.\[\&_\[cmdk-item\]\]\:px-2 [cmdk-item]{padding-inline:calc(var(--spacing)*2)}.\[\&_\[cmdk-item\]\]\:py-3 [cmdk-item]{padding-block:calc(var(--spacing)*3)}.\[\&_\[cmdk-item\]_svg\]\:h-5 [cmdk-item] svg{height:calc(var(--spacing)*5)}.\[\&_\[cmdk-item\]_svg\]\:w-5 [cmdk-item] svg{width:calc(var(--spacing)*5)}.\[\&_p\]\:leading-relaxed p{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&\:\:-webkit-inner-spin-button\]\:appearance-none::-webkit-inner-spin-button{-webkit-appearance:none;-moz-appearance:none;appearance:none}.\[\&\:\:-webkit-inner-spin-button\]\:opacity-100::-webkit-inner-spin-button{opacity:1}.\[\&\:\:-webkit-outer-spin-button\]\:appearance-none::-webkit-outer-spin-button{-webkit-appearance:none;-moz-appearance:none;appearance:none}.\[\&\:\:-webkit-outer-spin-button\]\:opacity-100::-webkit-outer-spin-button{opacity:1}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:calc(var(--spacing)*0)}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y:2px;translate:var(--tw-translate-x)var(--tw-translate-y)}.\[\&\>span\]\:line-clamp-1>span{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\[\&\>svg\]\:absolute>svg{position:absolute}.\[\&\>svg\]\:top-4>svg{top:calc(var(--spacing)*4)}.\[\&\>svg\]\:left-4>svg{left:calc(var(--spacing)*4)}.\[\&\>svg\]\:text-destructive>svg{color:var(--destructive)}.\[\&\>svg\]\:text-foreground>svg{color:var(--foreground)}.\[\&\>svg\+div\]\:translate-y-\[-3px\]>svg+div{--tw-translate-y:-3px;translate:var(--tw-translate-x)var(--tw-translate-y)}.\[\&\>svg\~\*\]\:pl-7>svg~*{padding-left:calc(var(--spacing)*7)}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}}:root{--background:#fff;--foreground:#09090b;--card:#fff;--card-foreground:#09090b;--popover:#fff;--popover-foreground:#09090b;--primary:#18181b;--primary-foreground:#fafafa;--secondary:#f4f4f5;--secondary-foreground:#18181b;--muted:#f4f4f5;--muted-foreground:#71717a;--accent:#f4f4f5;--accent-foreground:#18181b;--destructive:#ef4444;--destructive-foreground:#fafafa;--border:#e4e4e7;--input:#e4e4e7;--ring:#09090b;--chart-1:#e76e50;--chart-2:#2a9d90;--chart-3:#274754;--chart-4:#e8c468;--chart-5:#f4a462;--radius:.6rem;--sidebar-background:#fafafa;--sidebar-foreground:#3f3f46;--sidebar-primary:#18181b;--sidebar-primary-foreground:#fafafa;--sidebar-accent:#f4f4f5;--sidebar-accent-foreground:#18181b;--sidebar-border:#e5e7eb;--sidebar-ring:#3b82f6}.dark{--background:#09090b;--foreground:#fafafa;--card:#09090b;--card-foreground:#fafafa;--popover:#09090b;--popover-foreground:#fafafa;--primary:#fafafa;--primary-foreground:#18181b;--secondary:#27272a;--secondary-foreground:#fafafa;--muted:#27272a;--muted-foreground:#a1a1aa;--accent:#27272a;--accent-foreground:#fafafa;--destructive:#7f1d1d;--destructive-foreground:#fafafa;--border:#27272a;--input:#27272a;--ring:#d4d4d8;--chart-1:#2662d9;--chart-2:#2eb88a;--chart-3:#e88c30;--chart-4:#af57db;--chart-5:#e23670;--sidebar-background:#18181b;--sidebar-foreground:#f4f4f5;--sidebar-primary:#1d4ed8;--sidebar-primary-foreground:#fff;--sidebar-accent:#27272a;--sidebar-accent-foreground:#f4f4f5;--sidebar-border:#27272a;--sidebar-ring:#3b82f6}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-thumb{background-color:#ccc;border-radius:5px}::-webkit-scrollbar-track{background-color:#f2f2f2}.dark ::-webkit-scrollbar-thumb{background-color:#e6e6e6}.dark ::-webkit-scrollbar-track{background-color:#000}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0))}}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false;initial-value:rotateX(0)}@property --tw-rotate-y{syntax:"*";inherits:false;initial-value:rotateY(0)}@property --tw-rotate-z{syntax:"*";inherits:false;initial-value:rotateZ(0)}@property --tw-skew-x{syntax:"*";inherits:false;initial-value:skewX(0)}@property --tw-skew-y{syntax:"*";inherits:false;initial-value:skewY(0)}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}:root{--sigma-background-color:#fff;--sigma-controls-background-color:#fff;--sigma-controls-background-color-hover:rgba(0,0,0,.2);--sigma-controls-border-color:rgba(0,0,0,.2);--sigma-controls-color:#000;--sigma-controls-zindex:100;--sigma-controls-margin:5px;--sigma-controls-size:30px}div.react-sigma{height:100%;width:100%;position:relative;background:var(--sigma-background-color)}div.sigma-container{height:100%;width:100%}.react-sigma-controls{position:absolute;z-index:var(--sigma-controls-zindex);border:2px solid var(--sigma-controls-border-color);border-radius:4px;color:var(--sigma-controls-color);background-color:var(--sigma-controls-background-color)}.react-sigma-controls.bottom-right{bottom:var(--sigma-controls-margin);right:var(--sigma-controls-margin)}.react-sigma-controls.bottom-left{bottom:var(--sigma-controls-margin);left:var(--sigma-controls-margin)}.react-sigma-controls.top-right{top:var(--sigma-controls-margin);right:var(--sigma-controls-margin)}.react-sigma-controls.top-left{top:var(--sigma-controls-margin);left:var(--sigma-controls-margin)}.react-sigma-controls:first-child{border-top-left-radius:2px;border-top-right-radius:2px}.react-sigma-controls:last-child{border-bottom-left-radius:2px;border-bottom-right-radius:2px}.react-sigma-control{width:var(--sigma-controls-size);height:var(--sigma-controls-size);line-height:var(--sigma-controls-size);background-color:var(--sigma-controls-background-color);border-bottom:1px solid var(--sigma-controls-border-color)}.react-sigma-control:last-child{border-bottom:none}.react-sigma-control>*{box-sizing:border-box}.react-sigma-control>button{display:block;border:none;margin:0;padding:0;width:var(--sigma-controls-size);height:var(--sigma-controls-size);line-height:var(--sigma-controls-size);background-position:center;background-size:50%;background-repeat:no-repeat;background-color:var(--sigma-controls-background-color);clip:rect(0,0,0,0)}.react-sigma-control>button:hover{background-color:var(--sigma-controls-background-color-hover)}.react-sigma-search{background-color:var(--sigma-controls-background-color)}.react-sigma-search label{visibility:hidden}.react-sigma-search input{color:var(--sigma-controls-color);background-color:var(--sigma-controls-background-color);font-size:1em;width:100%;margin:0;border:none;padding:var(--sigma-controls-margin);box-sizing:border-box}:root{--sigma-grey-color:#ccc}.react-sigma .option.hoverable{cursor:pointer!important}.react-sigma .text-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.react-sigma .react-select__clear-indicator{cursor:pointer!important}.react-sigma .text-muted{color:var(--sigma-grey-color)}.react-sigma .text-italic{font-style:italic}.react-sigma .text-center{text-align:center}.react-sigma .graph-search{min-width:250px}.react-sigma .graph-search .option{padding:2px 8px}.react-sigma .graph-search .dropdown-indicator{font-size:1.25em;padding:4px}.react-sigma .graph-search .option.selected{background-color:var(--sigma-grey-color)}.react-sigma .node .render{position:relative;display:inline-block;width:1em;height:1em;border-radius:1em;background-color:var(--sigma-grey-color);margin-right:8px}.react-sigma .node{display:flex;flex-direction:row;align-items:center}.react-sigma .node .render{flex-grow:0;flex-shrink:0;margin-right:0 .25em}.react-sigma .node .label{flex-grow:1;flex-shrink:1}.react-sigma .edge{display:flex;flex-direction:column;align-items:flex-start;flex-grow:0;flex-shrink:0;flex-wrap:nowrap}.react-sigma .edge .node{font-size:.7em}.react-sigma .edge .body{display:flex;flex-direction:row;flex-grow:1;flex-shrink:1;min-height:.6em}.react-sigma .edge .body .render{display:flex;flex-direction:column;margin:0 2px}.react-sigma .edge .body .render .dash,.react-sigma .edge .body .render .dotted{display:inline-block;width:0;margin:0 2px;border:2px solid #ccc;flex-grow:1;flex-shrink:1}.react-sigma .edge .body .render .dotted{border-style:dotted}.react-sigma .edge .body .render .arrow{width:0;height:0;border-left:.3em solid transparent;border-right:.3em solid transparent;border-top:.6em solid red;flex-shrink:0;flex-grow:0;border-left-width:.3em;border-right-width:.3em}.react-sigma .edge .body .label{flex-grow:1;flex-shrink:1;text-align:center} diff --git a/lightrag/api/webui/assets/index-CSrxfS-k.js b/lightrag/api/webui/assets/index-CSrxfS-k.js new file mode 100644 index 00000000..2427c50a --- /dev/null +++ b/lightrag/api/webui/assets/index-CSrxfS-k.js @@ -0,0 +1,1178 @@ +var u9=Object.defineProperty;var c9=(e,t,n)=>t in e?u9(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Da=(e,t,n)=>c9(e,typeof t!="symbol"?t+"":t,n);function d9(e,t){for(var n=0;nr[a]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))r(a);new MutationObserver(a=>{for(const o of a)if(o.type==="childList")for(const s of o.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&r(s)}).observe(document,{childList:!0,subtree:!0});function n(a){const o={};return a.integrity&&(o.integrity=a.integrity),a.referrerPolicy&&(o.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?o.credentials="include":a.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function r(a){if(a.ep)return;a.ep=!0;const o=n(a);fetch(a.href,o)}})();var cf=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function un(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function f9(e){if(e.__esModule)return e;var t=e.default;if(typeof t=="function"){var n=function r(){return this instanceof r?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};n.prototype=t.prototype}else n={};return Object.defineProperty(n,"__esModule",{value:!0}),Object.keys(e).forEach(function(r){var a=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(n,r,a.get?a:{enumerable:!0,get:function(){return e[r]}})}),n}var $h={exports:{}},Zl={};/** + * @license React + * react-jsx-runtime.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Y_;function p9(){if(Y_)return Zl;Y_=1;var e=Symbol.for("react.transitional.element"),t=Symbol.for("react.fragment");function n(r,a,o){var s=null;if(o!==void 0&&(s=""+o),a.key!==void 0&&(s=""+a.key),"key"in a){o={};for(var u in a)u!=="key"&&(o[u]=a[u])}else o=a;return a=o.ref,{$$typeof:e,type:r,key:s,ref:a!==void 0?a:null,props:o}}return Zl.Fragment=t,Zl.jsx=n,Zl.jsxs=n,Zl}var K_;function g9(){return K_||(K_=1,$h.exports=p9()),$h.exports}var w=g9(),qh={exports:{}},it={};/** + * @license React + * react.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var X_;function h9(){if(X_)return it;X_=1;var e=Symbol.for("react.transitional.element"),t=Symbol.for("react.portal"),n=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),a=Symbol.for("react.profiler"),o=Symbol.for("react.consumer"),s=Symbol.for("react.context"),u=Symbol.for("react.forward_ref"),c=Symbol.for("react.suspense"),d=Symbol.for("react.memo"),p=Symbol.for("react.lazy"),g=Symbol.iterator;function m(I){return I===null||typeof I!="object"?null:(I=g&&I[g]||I["@@iterator"],typeof I=="function"?I:null)}var b={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},y=Object.assign,S={};function k(I,V,B){this.props=I,this.context=V,this.refs=S,this.updater=B||b}k.prototype.isReactComponent={},k.prototype.setState=function(I,V){if(typeof I!="object"&&typeof I!="function"&&I!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,I,V,"setState")},k.prototype.forceUpdate=function(I){this.updater.enqueueForceUpdate(this,I,"forceUpdate")};function R(){}R.prototype=k.prototype;function x(I,V,B){this.props=I,this.context=V,this.refs=S,this.updater=B||b}var A=x.prototype=new R;A.constructor=x,y(A,k.prototype),A.isPureReactComponent=!0;var C=Array.isArray,N={H:null,A:null,T:null,S:null},_=Object.prototype.hasOwnProperty;function O(I,V,B,M,K,J){return B=J.ref,{$$typeof:e,type:I,key:V,ref:B!==void 0?B:null,props:J}}function F(I,V){return O(I.type,V,void 0,void 0,void 0,I.props)}function D(I){return typeof I=="object"&&I!==null&&I.$$typeof===e}function L(I){var V={"=":"=0",":":"=2"};return"$"+I.replace(/[=:]/g,function(B){return V[B]})}var G=/\/+/g;function $(I,V){return typeof I=="object"&&I!==null&&I.key!=null?L(""+I.key):V.toString(36)}function U(){}function W(I){switch(I.status){case"fulfilled":return I.value;case"rejected":throw I.reason;default:switch(typeof I.status=="string"?I.then(U,U):(I.status="pending",I.then(function(V){I.status==="pending"&&(I.status="fulfilled",I.value=V)},function(V){I.status==="pending"&&(I.status="rejected",I.reason=V)})),I.status){case"fulfilled":return I.value;case"rejected":throw I.reason}}throw I}function Z(I,V,B,M,K){var J=typeof I;(J==="undefined"||J==="boolean")&&(I=null);var le=!1;if(I===null)le=!0;else switch(J){case"bigint":case"string":case"number":le=!0;break;case"object":switch(I.$$typeof){case e:case t:le=!0;break;case p:return le=I._init,Z(le(I._payload),V,B,M,K)}}if(le)return K=K(I),le=M===""?"."+$(I,0):M,C(K)?(B="",le!=null&&(B=le.replace(G,"$&/")+"/"),Z(K,V,B,"",function(pe){return pe})):K!=null&&(D(K)&&(K=F(K,B+(K.key==null||I&&I.key===K.key?"":(""+K.key).replace(G,"$&/")+"/")+le)),V.push(K)),1;le=0;var oe=M===""?".":M+":";if(C(I))for(var Q=0;Q>>1,I=j[Y];if(0>>1;Ya(M,z))Ka(J,M)?(j[Y]=J,j[K]=z,Y=K):(j[Y]=M,j[B]=z,Y=B);else if(Ka(J,z))j[Y]=J,j[K]=z,Y=K;else break e}}return H}function a(j,H){var z=j.sortIndex-H.sortIndex;return z!==0?z:j.id-H.id}if(e.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var o=performance;e.unstable_now=function(){return o.now()}}else{var s=Date,u=s.now();e.unstable_now=function(){return s.now()-u}}var c=[],d=[],p=1,g=null,m=3,b=!1,y=!1,S=!1,k=typeof setTimeout=="function"?setTimeout:null,R=typeof clearTimeout=="function"?clearTimeout:null,x=typeof setImmediate<"u"?setImmediate:null;function A(j){for(var H=n(d);H!==null;){if(H.callback===null)r(d);else if(H.startTime<=j)r(d),H.sortIndex=H.expirationTime,t(c,H);else break;H=n(d)}}function C(j){if(S=!1,A(j),!y)if(n(c)!==null)y=!0,W();else{var H=n(d);H!==null&&Z(C,H.startTime-j)}}var N=!1,_=-1,O=5,F=-1;function D(){return!(e.unstable_now()-Fj&&D());){var Y=g.callback;if(typeof Y=="function"){g.callback=null,m=g.priorityLevel;var I=Y(g.expirationTime<=j);if(j=e.unstable_now(),typeof I=="function"){g.callback=I,A(j),H=!0;break t}g===n(c)&&r(c),A(j)}else r(c);g=n(c)}if(g!==null)H=!0;else{var V=n(d);V!==null&&Z(C,V.startTime-j),H=!1}}break e}finally{g=null,m=z,b=!1}H=void 0}}finally{H?G():N=!1}}}var G;if(typeof x=="function")G=function(){x(L)};else if(typeof MessageChannel<"u"){var $=new MessageChannel,U=$.port2;$.port1.onmessage=L,G=function(){U.postMessage(null)}}else G=function(){k(L,0)};function W(){N||(N=!0,G())}function Z(j,H){_=k(function(){j(e.unstable_now())},H)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(j){j.callback=null},e.unstable_continueExecution=function(){y||b||(y=!0,W())},e.unstable_forceFrameRate=function(j){0>j||125Y?(j.sortIndex=z,t(d,j),n(c)===null&&j===n(d)&&(S?(R(_),_=-1):S=!0,Z(C,z-Y))):(j.sortIndex=I,t(c,j),y||b||(y=!0,W())),j},e.unstable_shouldYield=D,e.unstable_wrapCallback=function(j){var H=m;return function(){var z=m;m=H;try{return j.apply(this,arguments)}finally{m=z}}}}(Yh)),Yh}var J_;function y9(){return J_||(J_=1,Wh.exports=b9()),Wh.exports}var Kh={exports:{}},wn={};/** + * @license React + * react-dom.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var eC;function v9(){if(eC)return wn;eC=1;var e=Hf();function t(c){var d="https://react.dev/errors/"+c;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}return e(),Kh.exports=v9(),Kh.exports}/** + * @license React + * react-dom-client.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var nC;function S9(){if(nC)return Ql;nC=1;var e=y9(),t=Hf(),n=Uz();function r(i){var l="https://react.dev/errors/"+i;if(1)":-1v||X[h]!==ae[v]){var ye=` +`+X[h].replace(" at new "," at ");return i.displayName&&ye.includes("")&&(ye=ye.replace("",i.displayName)),ye}while(1<=h&&0<=v);break}}}finally{W=!1,Error.prepareStackTrace=f}return(f=i?i.displayName||i.name:"")?U(f):""}function j(i){switch(i.tag){case 26:case 27:case 5:return U(i.type);case 16:return U("Lazy");case 13:return U("Suspense");case 19:return U("SuspenseList");case 0:case 15:return i=Z(i.type,!1),i;case 11:return i=Z(i.type.render,!1),i;case 1:return i=Z(i.type,!0),i;default:return""}}function H(i){try{var l="";do l+=j(i),i=i.return;while(i);return l}catch(f){return` +Error generating stack: `+f.message+` +`+f.stack}}function z(i){var l=i,f=i;if(i.alternate)for(;l.return;)l=l.return;else{i=l;do l=i,l.flags&4098&&(f=l.return),i=l.return;while(i)}return l.tag===3?f:null}function Y(i){if(i.tag===13){var l=i.memoizedState;if(l===null&&(i=i.alternate,i!==null&&(l=i.memoizedState)),l!==null)return l.dehydrated}return null}function I(i){if(z(i)!==i)throw Error(r(188))}function V(i){var l=i.alternate;if(!l){if(l=z(i),l===null)throw Error(r(188));return l!==i?null:i}for(var f=i,h=l;;){var v=f.return;if(v===null)break;var T=v.alternate;if(T===null){if(h=v.return,h!==null){f=h;continue}break}if(v.child===T.child){for(T=v.child;T;){if(T===f)return I(v),i;if(T===h)return I(v),l;T=T.sibling}throw Error(r(188))}if(f.return!==h.return)f=v,h=T;else{for(var P=!1,q=v.child;q;){if(q===f){P=!0,f=v,h=T;break}if(q===h){P=!0,h=v,f=T;break}q=q.sibling}if(!P){for(q=T.child;q;){if(q===f){P=!0,f=T,h=v;break}if(q===h){P=!0,h=T,f=v;break}q=q.sibling}if(!P)throw Error(r(189))}}if(f.alternate!==h)throw Error(r(190))}if(f.tag!==3)throw Error(r(188));return f.stateNode.current===f?i:l}function B(i){var l=i.tag;if(l===5||l===26||l===27||l===6)return i;for(i=i.child;i!==null;){if(l=B(i),l!==null)return l;i=i.sibling}return null}var M=Array.isArray,K=n.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,J={pending:!1,data:null,method:null,action:null},le=[],oe=-1;function Q(i){return{current:i}}function pe(i){0>oe||(i.current=le[oe],le[oe]=null,oe--)}function re(i,l){oe++,le[oe]=i.current,i.current=l}var Ee=Q(null),we=Q(null),De=Q(null),_e=Q(null);function Se(i,l){switch(re(De,l),re(we,i),re(Ee,null),i=l.nodeType,i){case 9:case 11:l=(l=l.documentElement)&&(l=l.namespaceURI)?x_(l):0;break;default:if(i=i===8?l.parentNode:l,l=i.tagName,i=i.namespaceURI)i=x_(i),l=k_(i,l);else switch(l){case"svg":l=1;break;case"math":l=2;break;default:l=0}}pe(Ee),re(Ee,l)}function ee(){pe(Ee),pe(we),pe(De)}function fe(i){i.memoizedState!==null&&re(_e,i);var l=Ee.current,f=k_(l,i.type);l!==f&&(re(we,i),re(Ee,f))}function Te(i){we.current===i&&(pe(Ee),pe(we)),_e.current===i&&(pe(_e),Vl._currentValue=J)}var be=Object.prototype.hasOwnProperty,xe=e.unstable_scheduleCallback,se=e.unstable_cancelCallback,ze=e.unstable_shouldYield,Be=e.unstable_requestPaint,me=e.unstable_now,Ne=e.unstable_getCurrentPriorityLevel,te=e.unstable_ImmediatePriority,ce=e.unstable_UserBlockingPriority,Ce=e.unstable_NormalPriority,Fe=e.unstable_LowPriority,We=e.unstable_IdlePriority,yt=e.log,kt=e.unstable_setDisableYieldValue,ht=null,et=null;function Tt(i){if(et&&typeof et.onCommitFiberRoot=="function")try{et.onCommitFiberRoot(ht,i,void 0,(i.current.flags&128)===128)}catch{}}function ot(i){if(typeof yt=="function"&&kt(i),et&&typeof et.setStrictMode=="function")try{et.setStrictMode(ht,i)}catch{}}var St=Math.clz32?Math.clz32:Bt,Ht=Math.log,fn=Math.LN2;function Bt(i){return i>>>=0,i===0?32:31-(Ht(i)/fn|0)|0}var or=128,qr=4194304;function Jt(i){var l=i&42;if(l!==0)return l;switch(i&-i){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 i&4194176;case 4194304:case 8388608:case 16777216:case 33554432:return i&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return i}}function pa(i,l){var f=i.pendingLanes;if(f===0)return 0;var h=0,v=i.suspendedLanes,T=i.pingedLanes,P=i.warmLanes;i=i.finishedLanes!==0;var q=f&134217727;return q!==0?(f=q&~v,f!==0?h=Jt(f):(T&=q,T!==0?h=Jt(T):i||(P=q&~P,P!==0&&(h=Jt(P))))):(q=f&~v,q!==0?h=Jt(q):T!==0?h=Jt(T):i||(P=f&~P,P!==0&&(h=Jt(P)))),h===0?0:l!==0&&l!==h&&!(l&v)&&(v=h&-h,P=l&-l,v>=P||v===32&&(P&4194176)!==0)?l:h}function Xe(i,l){return(i.pendingLanes&~(i.suspendedLanes&~i.pingedLanes)&l)===0}function mt(i,l){switch(i){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 Ct(){var i=or;return or<<=1,!(or&4194176)&&(or=128),i}function Dn(){var i=qr;return qr<<=1,!(qr&62914560)&&(qr=4194304),i}function _n(i){for(var l=[],f=0;31>f;f++)l.push(i);return l}function In(i,l){i.pendingLanes|=l,l!==268435456&&(i.suspendedLanes=0,i.pingedLanes=0,i.warmLanes=0)}function ga(i,l,f,h,v,T){var P=i.pendingLanes;i.pendingLanes=f,i.suspendedLanes=0,i.pingedLanes=0,i.warmLanes=0,i.expiredLanes&=f,i.entangledLanes&=f,i.errorRecoveryDisabledLanes&=f,i.shellSuspendCounter=0;var q=i.entanglements,X=i.expirationTimes,ae=i.hiddenUpdates;for(f=P&~f;0"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),n$=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]*$"),kA={},TA={};function r$(i){return be.call(TA,i)?!0:be.call(kA,i)?!1:n$.test(i)?TA[i]=!0:(kA[i]=!0,!1)}function ic(i,l,f){if(r$(l))if(f===null)i.removeAttribute(l);else{switch(typeof f){case"undefined":case"function":case"symbol":i.removeAttribute(l);return;case"boolean":var h=l.toLowerCase().slice(0,5);if(h!=="data-"&&h!=="aria-"){i.removeAttribute(l);return}}i.setAttribute(l,""+f)}}function sc(i,l,f){if(f===null)i.removeAttribute(l);else{switch(typeof f){case"undefined":case"function":case"symbol":case"boolean":i.removeAttribute(l);return}i.setAttribute(l,""+f)}}function ma(i,l,f,h){if(h===null)i.removeAttribute(f);else{switch(typeof h){case"undefined":case"function":case"symbol":case"boolean":i.removeAttribute(f);return}i.setAttributeNS(l,f,""+h)}}function ir(i){switch(typeof i){case"bigint":case"boolean":case"number":case"string":case"undefined":return i;case"object":return i;default:return""}}function AA(i){var l=i.type;return(i=i.nodeName)&&i.toLowerCase()==="input"&&(l==="checkbox"||l==="radio")}function a$(i){var l=AA(i)?"checked":"value",f=Object.getOwnPropertyDescriptor(i.constructor.prototype,l),h=""+i[l];if(!i.hasOwnProperty(l)&&typeof f<"u"&&typeof f.get=="function"&&typeof f.set=="function"){var v=f.get,T=f.set;return Object.defineProperty(i,l,{configurable:!0,get:function(){return v.call(this)},set:function(P){h=""+P,T.call(this,P)}}),Object.defineProperty(i,l,{enumerable:f.enumerable}),{getValue:function(){return h},setValue:function(P){h=""+P},stopTracking:function(){i._valueTracker=null,delete i[l]}}}}function lc(i){i._valueTracker||(i._valueTracker=a$(i))}function RA(i){if(!i)return!1;var l=i._valueTracker;if(!l)return!0;var f=l.getValue(),h="";return i&&(h=AA(i)?i.checked?"true":"false":i.value),i=h,i!==f?(l.setValue(i),!0):!1}function uc(i){if(i=i||(typeof document<"u"?document:void 0),typeof i>"u")return null;try{return i.activeElement||i.body}catch{return i.body}}var o$=/[\n"\\]/g;function sr(i){return i.replace(o$,function(l){return"\\"+l.charCodeAt(0).toString(16)+" "})}function Gp(i,l,f,h,v,T,P,q){i.name="",P!=null&&typeof P!="function"&&typeof P!="symbol"&&typeof P!="boolean"?i.type=P:i.removeAttribute("type"),l!=null?P==="number"?(l===0&&i.value===""||i.value!=l)&&(i.value=""+ir(l)):i.value!==""+ir(l)&&(i.value=""+ir(l)):P!=="submit"&&P!=="reset"||i.removeAttribute("value"),l!=null?Hp(i,P,ir(l)):f!=null?Hp(i,P,ir(f)):h!=null&&i.removeAttribute("value"),v==null&&T!=null&&(i.defaultChecked=!!T),v!=null&&(i.checked=v&&typeof v!="function"&&typeof v!="symbol"),q!=null&&typeof q!="function"&&typeof q!="symbol"&&typeof q!="boolean"?i.name=""+ir(q):i.removeAttribute("name")}function _A(i,l,f,h,v,T,P,q){if(T!=null&&typeof T!="function"&&typeof T!="symbol"&&typeof T!="boolean"&&(i.type=T),l!=null||f!=null){if(!(T!=="submit"&&T!=="reset"||l!=null))return;f=f!=null?""+ir(f):"",l=l!=null?""+ir(l):f,q||l===i.value||(i.value=l),i.defaultValue=l}h=h??v,h=typeof h!="function"&&typeof h!="symbol"&&!!h,i.checked=q?i.checked:!!h,i.defaultChecked=!!h,P!=null&&typeof P!="function"&&typeof P!="symbol"&&typeof P!="boolean"&&(i.name=P)}function Hp(i,l,f){l==="number"&&uc(i.ownerDocument)===i||i.defaultValue===""+f||(i.defaultValue=""+f)}function Oi(i,l,f,h){if(i=i.options,l){l={};for(var v=0;v=cl),jA=" ",GA=!1;function HA(i,l){switch(i){case"keyup":return I$.indexOf(l.keyCode)!==-1;case"keydown":return l.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function $A(i){return i=i.detail,typeof i=="object"&&"data"in i?i.data:null}var Mi=!1;function M$(i,l){switch(i){case"compositionend":return $A(l);case"keypress":return l.which!==32?null:(GA=!0,jA);case"textInput":return i=l.data,i===jA&&GA?null:i;default:return null}}function F$(i,l){if(Mi)return i==="compositionend"||!eg&&HA(i,l)?(i=MA(),dc=Kp=Xa=null,Mi=!1,i):null;switch(i){case"paste":return null;case"keypress":if(!(l.ctrlKey||l.altKey||l.metaKey)||l.ctrlKey&&l.altKey){if(l.char&&1=l)return{node:f,offset:l-i};i=h}e:{for(;f;){if(f.nextSibling){f=f.nextSibling;break e}f=f.parentNode}f=void 0}f=QA(f)}}function e1(i,l){return i&&l?i===l?!0:i&&i.nodeType===3?!1:l&&l.nodeType===3?e1(i,l.parentNode):"contains"in i?i.contains(l):i.compareDocumentPosition?!!(i.compareDocumentPosition(l)&16):!1:!1}function t1(i){i=i!=null&&i.ownerDocument!=null&&i.ownerDocument.defaultView!=null?i.ownerDocument.defaultView:window;for(var l=uc(i.document);l instanceof i.HTMLIFrameElement;){try{var f=typeof l.contentWindow.location.href=="string"}catch{f=!1}if(f)i=l.contentWindow;else break;l=uc(i.document)}return l}function rg(i){var l=i&&i.nodeName&&i.nodeName.toLowerCase();return l&&(l==="input"&&(i.type==="text"||i.type==="search"||i.type==="tel"||i.type==="url"||i.type==="password")||l==="textarea"||i.contentEditable==="true")}function $$(i,l){var f=t1(l);l=i.focusedElem;var h=i.selectionRange;if(f!==l&&l&&l.ownerDocument&&e1(l.ownerDocument.documentElement,l)){if(h!==null&&rg(l)){if(i=h.start,f=h.end,f===void 0&&(f=i),"selectionStart"in l)l.selectionStart=i,l.selectionEnd=Math.min(f,l.value.length);else if(f=(i=l.ownerDocument||document)&&i.defaultView||window,f.getSelection){f=f.getSelection();var v=l.textContent.length,T=Math.min(h.start,v);h=h.end===void 0?T:Math.min(h.end,v),!f.extend&&T>h&&(v=h,h=T,T=v),v=JA(l,T);var P=JA(l,h);v&&P&&(f.rangeCount!==1||f.anchorNode!==v.node||f.anchorOffset!==v.offset||f.focusNode!==P.node||f.focusOffset!==P.offset)&&(i=i.createRange(),i.setStart(v.node,v.offset),f.removeAllRanges(),T>h?(f.addRange(i),f.extend(P.node,P.offset)):(i.setEnd(P.node,P.offset),f.addRange(i)))}}for(i=[],f=l;f=f.parentNode;)f.nodeType===1&&i.push({element:f,left:f.scrollLeft,top:f.scrollTop});for(typeof l.focus=="function"&&l.focus(),l=0;l=document.documentMode,Fi=null,ag=null,gl=null,og=!1;function n1(i,l,f){var h=f.window===f?f.document:f.nodeType===9?f:f.ownerDocument;og||Fi==null||Fi!==uc(h)||(h=Fi,"selectionStart"in h&&rg(h)?h={start:h.selectionStart,end:h.selectionEnd}:(h=(h.ownerDocument&&h.ownerDocument.defaultView||window).getSelection(),h={anchorNode:h.anchorNode,anchorOffset:h.anchorOffset,focusNode:h.focusNode,focusOffset:h.focusOffset}),gl&&pl(gl,h)||(gl=h,h=Qc(ag,"onSelect"),0>=P,v-=P,ba=1<<32-St(l)+v|f<Je?(sn=Ye,Ye=null):sn=Ye.sibling;var wt=de(ie,Ye,ue[Je],ke);if(wt===null){Ye===null&&(Ye=sn);break}i&&Ye&&wt.alternate===null&&l(ie,Ye),ne=T(wt,ne,Je),lt===null?je=wt:lt.sibling=wt,lt=wt,Ye=sn}if(Je===ue.length)return f(ie,Ye),Et&&Ho(ie,Je),je;if(Ye===null){for(;JeJe?(sn=Ye,Ye=null):sn=Ye.sibling;var bo=de(ie,Ye,wt.value,ke);if(bo===null){Ye===null&&(Ye=sn);break}i&&Ye&&bo.alternate===null&&l(ie,Ye),ne=T(bo,ne,Je),lt===null?je=bo:lt.sibling=bo,lt=bo,Ye=sn}if(wt.done)return f(ie,Ye),Et&&Ho(ie,Je),je;if(Ye===null){for(;!wt.done;Je++,wt=ue.next())wt=Ae(ie,wt.value,ke),wt!==null&&(ne=T(wt,ne,Je),lt===null?je=wt:lt.sibling=wt,lt=wt);return Et&&Ho(ie,Je),je}for(Ye=h(Ye);!wt.done;Je++,wt=ue.next())wt=he(Ye,ie,Je,wt.value,ke),wt!==null&&(i&&wt.alternate!==null&&Ye.delete(wt.key===null?Je:wt.key),ne=T(wt,ne,Je),lt===null?je=wt:lt.sibling=wt,lt=wt);return i&&Ye.forEach(function(l9){return l(ie,l9)}),Et&&Ho(ie,Je),je}function Vt(ie,ne,ue,ke){if(typeof ue=="object"&&ue!==null&&ue.type===c&&ue.key===null&&(ue=ue.props.children),typeof ue=="object"&&ue!==null){switch(ue.$$typeof){case s:e:{for(var je=ue.key;ne!==null;){if(ne.key===je){if(je=ue.type,je===c){if(ne.tag===7){f(ie,ne.sibling),ke=v(ne,ue.props.children),ke.return=ie,ie=ke;break e}}else if(ne.elementType===je||typeof je=="object"&&je!==null&&je.$$typeof===x&&v1(je)===ne.type){f(ie,ne.sibling),ke=v(ne,ue.props),El(ke,ue),ke.return=ie,ie=ke;break e}f(ie,ne);break}else l(ie,ne);ne=ne.sibling}ue.type===c?(ke=ei(ue.props.children,ie.mode,ke,ue.key),ke.return=ie,ie=ke):(ke=Gc(ue.type,ue.key,ue.props,null,ie.mode,ke),El(ke,ue),ke.return=ie,ie=ke)}return P(ie);case u:e:{for(je=ue.key;ne!==null;){if(ne.key===je)if(ne.tag===4&&ne.stateNode.containerInfo===ue.containerInfo&&ne.stateNode.implementation===ue.implementation){f(ie,ne.sibling),ke=v(ne,ue.children||[]),ke.return=ie,ie=ke;break e}else{f(ie,ne);break}else l(ie,ne);ne=ne.sibling}ke=sh(ue,ie.mode,ke),ke.return=ie,ie=ke}return P(ie);case x:return je=ue._init,ue=je(ue._payload),Vt(ie,ne,ue,ke)}if(M(ue))return qe(ie,ne,ue,ke);if(_(ue)){if(je=_(ue),typeof je!="function")throw Error(r(150));return ue=je.call(ue),nt(ie,ne,ue,ke)}if(typeof ue.then=="function")return Vt(ie,ne,xc(ue),ke);if(ue.$$typeof===b)return Vt(ie,ne,Bc(ie,ue),ke);kc(ie,ue)}return typeof ue=="string"&&ue!==""||typeof ue=="number"||typeof ue=="bigint"?(ue=""+ue,ne!==null&&ne.tag===6?(f(ie,ne.sibling),ke=v(ne,ue),ke.return=ie,ie=ke):(f(ie,ne),ke=ih(ue,ie.mode,ke),ke.return=ie,ie=ke),P(ie)):f(ie,ne)}return function(ie,ne,ue,ke){try{Sl=0;var je=Vt(ie,ne,ue,ke);return Gi=null,je}catch(Ye){if(Ye===yl)throw Ye;var lt=hr(29,Ye,null,ie.mode);return lt.lanes=ke,lt.return=ie,lt}finally{}}}var qo=S1(!0),E1=S1(!1),Hi=Q(null),Tc=Q(0);function w1(i,l){i=Ca,re(Tc,i),re(Hi,l),Ca=i|l.baseLanes}function pg(){re(Tc,Ca),re(Hi,Hi.current)}function gg(){Ca=Tc.current,pe(Hi),pe(Tc)}var fr=Q(null),Wr=null;function Qa(i){var l=i.alternate;re(en,en.current&1),re(fr,i),Wr===null&&(l===null||Hi.current!==null||l.memoizedState!==null)&&(Wr=i)}function x1(i){if(i.tag===22){if(re(en,en.current),re(fr,i),Wr===null){var l=i.alternate;l!==null&&l.memoizedState!==null&&(Wr=i)}}else Ja()}function Ja(){re(en,en.current),re(fr,fr.current)}function va(i){pe(fr),Wr===i&&(Wr=null),pe(en)}var en=Q(0);function Ac(i){for(var l=i;l!==null;){if(l.tag===13){var f=l.memoizedState;if(f!==null&&(f=f.dehydrated,f===null||f.data==="$?"||f.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===i)break;for(;l.sibling===null;){if(l.return===null||l.return===i)return null;l=l.return}l.sibling.return=l.return,l=l.sibling}return null}var K$=typeof AbortController<"u"?AbortController:function(){var i=[],l=this.signal={aborted:!1,addEventListener:function(f,h){i.push(h)}};this.abort=function(){l.aborted=!0,i.forEach(function(f){return f()})}},X$=e.unstable_scheduleCallback,Z$=e.unstable_NormalPriority,tn={$$typeof:b,Consumer:null,Provider:null,_currentValue:null,_currentValue2:null,_threadCount:0};function hg(){return{controller:new K$,data:new Map,refCount:0}}function wl(i){i.refCount--,i.refCount===0&&X$(Z$,function(){i.controller.abort()})}var xl=null,mg=0,$i=0,qi=null;function Q$(i,l){if(xl===null){var f=xl=[];mg=0,$i=wh(),qi={status:"pending",value:void 0,then:function(h){f.push(h)}}}return mg++,l.then(k1,k1),l}function k1(){if(--mg===0&&xl!==null){qi!==null&&(qi.status="fulfilled");var i=xl;xl=null,$i=0,qi=null;for(var l=0;lT?T:8;var P=D.T,q={};D.T=q,Ig(i,!1,l,f);try{var X=v(),ae=D.S;if(ae!==null&&ae(q,X),X!==null&&typeof X=="object"&&typeof X.then=="function"){var ye=J$(X,h);Al(i,l,ye,Qn(i))}else Al(i,l,h,Qn(i))}catch(Ae){Al(i,l,{then:function(){},status:"rejected",reason:Ae},Qn())}finally{K.p=T,D.T=P}}function a6(){}function Og(i,l,f,h){if(i.tag!==5)throw Error(r(476));var v=tR(i).queue;eR(i,v,l,J,f===null?a6:function(){return nR(i),f(h)})}function tR(i){var l=i.memoizedState;if(l!==null)return l;l={memoizedState:J,baseState:J,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Sa,lastRenderedState:J},next:null};var f={};return l.next={memoizedState:f,baseState:f,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Sa,lastRenderedState:f},next:null},i.memoizedState=l,i=i.alternate,i!==null&&(i.memoizedState=l),l}function nR(i){var l=tR(i).next.queue;Al(i,l,{},Qn())}function Dg(){return En(Vl)}function rR(){return Xt().memoizedState}function aR(){return Xt().memoizedState}function o6(i){for(var l=i.return;l!==null;){switch(l.tag){case 24:case 3:var f=Qn();i=ao(f);var h=oo(l,i,f);h!==null&&(Nn(h,l,f),Cl(h,l,f)),l={cache:hg()},i.payload=l;return}l=l.return}}function i6(i,l,f){var h=Qn();f={lane:h,revertLane:0,action:f,hasEagerState:!1,eagerState:null,next:null},Mc(i)?iR(l,f):(f=lg(i,l,f,h),f!==null&&(Nn(f,i,h),sR(f,l,h)))}function oR(i,l,f){var h=Qn();Al(i,l,f,h)}function Al(i,l,f,h){var v={lane:h,revertLane:0,action:f,hasEagerState:!1,eagerState:null,next:null};if(Mc(i))iR(l,v);else{var T=i.alternate;if(i.lanes===0&&(T===null||T.lanes===0)&&(T=l.lastRenderedReducer,T!==null))try{var P=l.lastRenderedState,q=T(P,f);if(v.hasEagerState=!0,v.eagerState=q,Yn(q,P))return yc(i,l,v,0),It===null&&bc(),!1}catch{}finally{}if(f=lg(i,l,v,h),f!==null)return Nn(f,i,h),sR(f,l,h),!0}return!1}function Ig(i,l,f,h){if(h={lane:2,revertLane:wh(),action:h,hasEagerState:!1,eagerState:null,next:null},Mc(i)){if(l)throw Error(r(479))}else l=lg(i,f,h,2),l!==null&&Nn(l,i,2)}function Mc(i){var l=i.alternate;return i===st||l!==null&&l===st}function iR(i,l){Vi=_c=!0;var f=i.pending;f===null?l.next=l:(l.next=f.next,f.next=l),i.pending=l}function sR(i,l,f){if(f&4194176){var h=l.lanes;h&=i.pendingLanes,f|=h,l.lanes=f,_r(i,f)}}var Yr={readContext:En,use:Oc,useCallback:Wt,useContext:Wt,useEffect:Wt,useImperativeHandle:Wt,useLayoutEffect:Wt,useInsertionEffect:Wt,useMemo:Wt,useReducer:Wt,useRef:Wt,useState:Wt,useDebugValue:Wt,useDeferredValue:Wt,useTransition:Wt,useSyncExternalStore:Wt,useId:Wt};Yr.useCacheRefresh=Wt,Yr.useMemoCache=Wt,Yr.useHostTransitionStatus=Wt,Yr.useFormState=Wt,Yr.useActionState=Wt,Yr.useOptimistic=Wt;var Yo={readContext:En,use:Oc,useCallback:function(i,l){return Pn().memoizedState=[i,l===void 0?null:l],i},useContext:En,useEffect:V1,useImperativeHandle:function(i,l,f){f=f!=null?f.concat([i]):null,Ic(4194308,4,K1.bind(null,l,i),f)},useLayoutEffect:function(i,l){return Ic(4194308,4,i,l)},useInsertionEffect:function(i,l){Ic(4,2,i,l)},useMemo:function(i,l){var f=Pn();l=l===void 0?null:l;var h=i();if(Wo){ot(!0);try{i()}finally{ot(!1)}}return f.memoizedState=[h,l],h},useReducer:function(i,l,f){var h=Pn();if(f!==void 0){var v=f(l);if(Wo){ot(!0);try{f(l)}finally{ot(!1)}}}else v=l;return h.memoizedState=h.baseState=v,i={pending:null,lanes:0,dispatch:null,lastRenderedReducer:i,lastRenderedState:v},h.queue=i,i=i.dispatch=i6.bind(null,st,i),[h.memoizedState,i]},useRef:function(i){var l=Pn();return i={current:i},l.memoizedState=i},useState:function(i){i=Ag(i);var l=i.queue,f=oR.bind(null,st,l);return l.dispatch=f,[i.memoizedState,f]},useDebugValue:Cg,useDeferredValue:function(i,l){var f=Pn();return Ng(f,i,l)},useTransition:function(){var i=Ag(!1);return i=eR.bind(null,st,i.queue,!0,!1),Pn().memoizedState=i,[!1,i]},useSyncExternalStore:function(i,l,f){var h=st,v=Pn();if(Et){if(f===void 0)throw Error(r(407));f=f()}else{if(f=l(),It===null)throw Error(r(349));bt&60||N1(h,l,f)}v.memoizedState=f;var T={value:f,getSnapshot:l};return v.queue=T,V1(D1.bind(null,h,T,i),[i]),h.flags|=2048,Yi(9,O1.bind(null,h,T,f,l),{destroy:void 0},null),f},useId:function(){var i=Pn(),l=It.identifierPrefix;if(Et){var f=ya,h=ba;f=(h&~(1<<32-St(h)-1)).toString(32)+f,l=":"+l+"R"+f,f=Cc++,0 title"))),hn(T,h,f),T[Sn]=i,rn(T),h=T;break e;case"link":var P=L_("link","href",v).get(h+(f.href||""));if(P){for(var q=0;q<\/script>",i=i.removeChild(i.firstChild);break;case"select":i=typeof h.is=="string"?v.createElement("select",{is:h.is}):v.createElement("select"),h.multiple?i.multiple=!0:h.size&&(i.size=h.size);break;default:i=typeof h.is=="string"?v.createElement(f,{is:h.is}):v.createElement(f)}}i[Sn]=l,i[Mn]=h;e:for(v=l.child;v!==null;){if(v.tag===5||v.tag===6)i.appendChild(v.stateNode);else if(v.tag!==4&&v.tag!==27&&v.child!==null){v.child.return=v,v=v.child;continue}if(v===l)break e;for(;v.sibling===null;){if(v.return===null||v.return===l)break e;v=v.return}v.sibling.return=v.return,v=v.sibling}l.stateNode=i;e:switch(hn(i,f,h),f){case"button":case"input":case"select":case"textarea":i=!!h.autoFocus;break e;case"img":i=!0;break e;default:i=!1}i&&Ra(l)}}return Ut(l),l.flags&=-16777217,null;case 6:if(i&&l.stateNode!=null)i.memoizedProps!==h&&Ra(l);else{if(typeof h!="string"&&l.stateNode===null)throw Error(r(166));if(i=De.current,hl(l)){if(i=l.stateNode,f=l.memoizedProps,h=null,v=Cn,v!==null)switch(v.tag){case 27:case 5:h=v.memoizedProps}i[Sn]=l,i=!!(i.nodeValue===f||h!==null&&h.suppressHydrationWarning===!0||w_(i.nodeValue,f)),i||$o(l)}else i=ed(i).createTextNode(h),i[Sn]=l,l.stateNode=i}return Ut(l),null;case 13:if(h=l.memoizedState,i===null||i.memoizedState!==null&&i.memoizedState.dehydrated!==null){if(v=hl(l),h!==null&&h.dehydrated!==null){if(i===null){if(!v)throw Error(r(318));if(v=l.memoizedState,v=v!==null?v.dehydrated:null,!v)throw Error(r(317));v[Sn]=l}else ml(),!(l.flags&128)&&(l.memoizedState=null),l.flags|=4;Ut(l),v=!1}else Nr!==null&&(hh(Nr),Nr=null),v=!0;if(!v)return l.flags&256?(va(l),l):(va(l),null)}if(va(l),l.flags&128)return l.lanes=f,l;if(f=h!==null,i=i!==null&&i.memoizedState!==null,f){h=l.child,v=null,h.alternate!==null&&h.alternate.memoizedState!==null&&h.alternate.memoizedState.cachePool!==null&&(v=h.alternate.memoizedState.cachePool.pool);var T=null;h.memoizedState!==null&&h.memoizedState.cachePool!==null&&(T=h.memoizedState.cachePool.pool),T!==v&&(h.flags|=2048)}return f!==i&&f&&(l.child.flags|=8192),Hc(l,l.updateQueue),Ut(l),null;case 4:return ee(),i===null&&Ah(l.stateNode.containerInfo),Ut(l),null;case 10:return xa(l.type),Ut(l),null;case 19:if(pe(en),v=l.memoizedState,v===null)return Ut(l),null;if(h=(l.flags&128)!==0,T=v.rendering,T===null)if(h)Fl(v,!1);else{if(qt!==0||i!==null&&i.flags&128)for(i=l.child;i!==null;){if(T=Ac(i),T!==null){for(l.flags|=128,Fl(v,!1),i=T.updateQueue,l.updateQueue=i,Hc(l,i),l.subtreeFlags=0,i=f,f=l.child;f!==null;)XR(f,i),f=f.sibling;return re(en,en.current&1|2),l.child}i=i.sibling}v.tail!==null&&me()>$c&&(l.flags|=128,h=!0,Fl(v,!1),l.lanes=4194304)}else{if(!h)if(i=Ac(T),i!==null){if(l.flags|=128,h=!0,i=i.updateQueue,l.updateQueue=i,Hc(l,i),Fl(v,!0),v.tail===null&&v.tailMode==="hidden"&&!T.alternate&&!Et)return Ut(l),null}else 2*me()-v.renderingStartTime>$c&&f!==536870912&&(l.flags|=128,h=!0,Fl(v,!1),l.lanes=4194304);v.isBackwards?(T.sibling=l.child,l.child=T):(i=v.last,i!==null?i.sibling=T:l.child=T,v.last=T)}return v.tail!==null?(l=v.tail,v.rendering=l,v.tail=l.sibling,v.renderingStartTime=me(),l.sibling=null,i=en.current,re(en,h?i&1|2:i&1),l):(Ut(l),null);case 22:case 23:return va(l),gg(),h=l.memoizedState!==null,i!==null?i.memoizedState!==null!==h&&(l.flags|=8192):h&&(l.flags|=8192),h?f&536870912&&!(l.flags&128)&&(Ut(l),l.subtreeFlags&6&&(l.flags|=8192)):Ut(l),f=l.updateQueue,f!==null&&Hc(l,f.retryQueue),f=null,i!==null&&i.memoizedState!==null&&i.memoizedState.cachePool!==null&&(f=i.memoizedState.cachePool.pool),h=null,l.memoizedState!==null&&l.memoizedState.cachePool!==null&&(h=l.memoizedState.cachePool.pool),h!==f&&(l.flags|=2048),i!==null&&pe(Vo),null;case 24:return f=null,i!==null&&(f=i.memoizedState.cache),l.memoizedState.cache!==f&&(l.flags|=2048),xa(tn),Ut(l),null;case 25:return null}throw Error(r(156,l.tag))}function p6(i,l){switch(cg(l),l.tag){case 1:return i=l.flags,i&65536?(l.flags=i&-65537|128,l):null;case 3:return xa(tn),ee(),i=l.flags,i&65536&&!(i&128)?(l.flags=i&-65537|128,l):null;case 26:case 27:case 5:return Te(l),null;case 13:if(va(l),i=l.memoizedState,i!==null&&i.dehydrated!==null){if(l.alternate===null)throw Error(r(340));ml()}return i=l.flags,i&65536?(l.flags=i&-65537|128,l):null;case 19:return pe(en),null;case 4:return ee(),null;case 10:return xa(l.type),null;case 22:case 23:return va(l),gg(),i!==null&&pe(Vo),i=l.flags,i&65536?(l.flags=i&-65537|128,l):null;case 24:return xa(tn),null;case 25:return null;default:return null}}function JR(i,l){switch(cg(l),l.tag){case 3:xa(tn),ee();break;case 26:case 27:case 5:Te(l);break;case 4:ee();break;case 13:va(l);break;case 19:pe(en);break;case 10:xa(l.type);break;case 22:case 23:va(l),gg(),i!==null&&pe(Vo);break;case 24:xa(tn)}}var g6={getCacheForType:function(i){var l=En(tn),f=l.data.get(i);return f===void 0&&(f=i(),l.data.set(i,f)),f}},h6=typeof WeakMap=="function"?WeakMap:Map,jt=0,It=null,ct=null,bt=0,Lt=0,Zn=null,_a=!1,Qi=!1,lh=!1,Ca=0,qt=0,co=0,ti=0,uh=0,mr=0,Ji=0,Pl=null,Kr=null,ch=!1,dh=0,$c=1/0,qc=null,fo=null,Vc=!1,ni=null,zl=0,fh=0,ph=null,Bl=0,gh=null;function Qn(){if(jt&2&&bt!==0)return bt&-bt;if(D.T!==null){var i=$i;return i!==0?i:wh()}return SA()}function e_(){mr===0&&(mr=!(bt&536870912)||Et?Ct():536870912);var i=fr.current;return i!==null&&(i.flags|=32),mr}function Nn(i,l,f){(i===It&&Lt===2||i.cancelPendingCommit!==null)&&(es(i,0),Na(i,bt,mr,!1)),In(i,f),(!(jt&2)||i!==It)&&(i===It&&(!(jt&2)&&(ti|=f),qt===4&&Na(i,bt,mr,!1)),Xr(i))}function t_(i,l,f){if(jt&6)throw Error(r(327));var h=!f&&(l&60)===0&&(l&i.expiredLanes)===0||Xe(i,l),v=h?y6(i,l):yh(i,l,!0),T=h;do{if(v===0){Qi&&!h&&Na(i,l,0,!1);break}else if(v===6)Na(i,l,0,!_a);else{if(f=i.current.alternate,T&&!m6(f)){v=yh(i,l,!1),T=!1;continue}if(v===2){if(T=l,i.errorRecoveryDisabledLanes&T)var P=0;else P=i.pendingLanes&-536870913,P=P!==0?P:P&536870912?536870912:0;if(P!==0){l=P;e:{var q=i;v=Pl;var X=q.current.memoizedState.isDehydrated;if(X&&(es(q,P).flags|=256),P=yh(q,P,!1),P!==2){if(lh&&!X){q.errorRecoveryDisabledLanes|=T,ti|=T,v=4;break e}T=Kr,Kr=v,T!==null&&hh(T)}v=P}if(T=!1,v!==2)continue}}if(v===1){es(i,0),Na(i,l,0,!0);break}e:{switch(h=i,v){case 0:case 1:throw Error(r(345));case 4:if((l&4194176)===l){Na(h,l,mr,!_a);break e}break;case 2:Kr=null;break;case 3:case 5:break;default:throw Error(r(329))}if(h.finishedWork=f,h.finishedLanes=l,(l&62914560)===l&&(T=dh+300-me(),10f?32:f,D.T=null,ni===null)var T=!1;else{f=ph,ph=null;var P=ni,q=zl;if(ni=null,zl=0,jt&6)throw Error(r(331));var X=jt;if(jt|=4,YR(P.current),qR(P,P.current,q,f),jt=X,Ul(0,!1),et&&typeof et.onPostCommitFiberRoot=="function")try{et.onPostCommitFiberRoot(ht,P)}catch{}T=!0}return T}finally{K.p=v,D.T=h,c_(i,l)}}return!1}function d_(i,l,f){l=ur(f,l),l=Fg(i.stateNode,l,2),i=oo(i,l,2),i!==null&&(In(i,2),Xr(i))}function Nt(i,l,f){if(i.tag===3)d_(i,i,f);else for(;l!==null;){if(l.tag===3){d_(l,i,f);break}else if(l.tag===1){var h=l.stateNode;if(typeof l.type.getDerivedStateFromError=="function"||typeof h.componentDidCatch=="function"&&(fo===null||!fo.has(h))){i=ur(f,i),f=gR(2),h=oo(l,f,2),h!==null&&(hR(f,h,l,i),In(h,2),Xr(h));break}}l=l.return}}function vh(i,l,f){var h=i.pingCache;if(h===null){h=i.pingCache=new h6;var v=new Set;h.set(l,v)}else v=h.get(l),v===void 0&&(v=new Set,h.set(l,v));v.has(f)||(lh=!0,v.add(f),i=E6.bind(null,i,l,f),l.then(i,i))}function E6(i,l,f){var h=i.pingCache;h!==null&&h.delete(l),i.pingedLanes|=i.suspendedLanes&f,i.warmLanes&=~f,It===i&&(bt&f)===f&&(qt===4||qt===3&&(bt&62914560)===bt&&300>me()-dh?!(jt&2)&&es(i,0):uh|=f,Ji===bt&&(Ji=0)),Xr(i)}function f_(i,l){l===0&&(l=Dn()),i=Za(i,l),i!==null&&(In(i,l),Xr(i))}function w6(i){var l=i.memoizedState,f=0;l!==null&&(f=l.retryLane),f_(i,f)}function x6(i,l){var f=0;switch(i.tag){case 13:var h=i.stateNode,v=i.memoizedState;v!==null&&(f=v.retryLane);break;case 19:h=i.stateNode;break;case 22:h=i.stateNode._retryCache;break;default:throw Error(r(314))}h!==null&&h.delete(l),f_(i,f)}function k6(i,l){return xe(i,l)}var Kc=null,rs=null,Sh=!1,Xc=!1,Eh=!1,ri=0;function Xr(i){i!==rs&&i.next===null&&(rs===null?Kc=rs=i:rs=rs.next=i),Xc=!0,Sh||(Sh=!0,A6(T6))}function Ul(i,l){if(!Eh&&Xc){Eh=!0;do for(var f=!1,h=Kc;h!==null;){if(i!==0){var v=h.pendingLanes;if(v===0)var T=0;else{var P=h.suspendedLanes,q=h.pingedLanes;T=(1<<31-St(42|i)+1)-1,T&=v&~(P&~q),T=T&201326677?T&201326677|1:T?T|2:0}T!==0&&(f=!0,h_(h,T))}else T=bt,T=pa(h,h===It?T:0),!(T&3)||Xe(h,T)||(f=!0,h_(h,T));h=h.next}while(f);Eh=!1}}function T6(){Xc=Sh=!1;var i=0;ri!==0&&(L6()&&(i=ri),ri=0);for(var l=me(),f=null,h=Kc;h!==null;){var v=h.next,T=p_(h,l);T===0?(h.next=null,f===null?Kc=v:f.next=v,v===null&&(rs=f)):(f=h,(i!==0||T&3)&&(Xc=!0)),h=v}Ul(i)}function p_(i,l){for(var f=i.suspendedLanes,h=i.pingedLanes,v=i.expirationTimes,T=i.pendingLanes&-62914561;0"u"?null:document;function N_(i,l,f){var h=os;if(h&&typeof l=="string"&&l){var v=sr(l);v='link[rel="'+i+'"][href="'+v+'"]',typeof f=="string"&&(v+='[crossorigin="'+f+'"]'),C_.has(v)||(C_.add(v),i={rel:i,crossOrigin:f,href:l},h.querySelector(v)===null&&(l=h.createElement("link"),hn(l,"link",i),rn(l),h.head.appendChild(l)))}}function G6(i){Oa.D(i),N_("dns-prefetch",i,null)}function H6(i,l){Oa.C(i,l),N_("preconnect",i,l)}function $6(i,l,f){Oa.L(i,l,f);var h=os;if(h&&i&&l){var v='link[rel="preload"][as="'+sr(l)+'"]';l==="image"&&f&&f.imageSrcSet?(v+='[imagesrcset="'+sr(f.imageSrcSet)+'"]',typeof f.imageSizes=="string"&&(v+='[imagesizes="'+sr(f.imageSizes)+'"]')):v+='[href="'+sr(i)+'"]';var T=v;switch(l){case"style":T=is(i);break;case"script":T=ss(i)}br.has(T)||(i=L({rel:"preload",href:l==="image"&&f&&f.imageSrcSet?void 0:i,as:l},f),br.set(T,i),h.querySelector(v)!==null||l==="style"&&h.querySelector(Hl(T))||l==="script"&&h.querySelector($l(T))||(l=h.createElement("link"),hn(l,"link",i),rn(l),h.head.appendChild(l)))}}function q6(i,l){Oa.m(i,l);var f=os;if(f&&i){var h=l&&typeof l.as=="string"?l.as:"script",v='link[rel="modulepreload"][as="'+sr(h)+'"][href="'+sr(i)+'"]',T=v;switch(h){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":T=ss(i)}if(!br.has(T)&&(i=L({rel:"modulepreload",href:i},l),br.set(T,i),f.querySelector(v)===null)){switch(h){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(f.querySelector($l(T)))return}h=f.createElement("link"),hn(h,"link",i),rn(h),f.head.appendChild(h)}}}function V6(i,l,f){Oa.S(i,l,f);var h=os;if(h&&i){var v=Ci(h).hoistableStyles,T=is(i);l=l||"default";var P=v.get(T);if(!P){var q={loading:0,preload:null};if(P=h.querySelector(Hl(T)))q.loading=5;else{i=L({rel:"stylesheet",href:i,"data-precedence":l},f),(f=br.get(T))&&Mh(i,f);var X=P=h.createElement("link");rn(X),hn(X,"link",i),X._p=new Promise(function(ae,ye){X.onload=ae,X.onerror=ye}),X.addEventListener("load",function(){q.loading|=1}),X.addEventListener("error",function(){q.loading|=2}),q.loading|=4,nd(P,l,h)}P={type:"stylesheet",instance:P,count:1,state:q},v.set(T,P)}}}function W6(i,l){Oa.X(i,l);var f=os;if(f&&i){var h=Ci(f).hoistableScripts,v=ss(i),T=h.get(v);T||(T=f.querySelector($l(v)),T||(i=L({src:i,async:!0},l),(l=br.get(v))&&Fh(i,l),T=f.createElement("script"),rn(T),hn(T,"link",i),f.head.appendChild(T)),T={type:"script",instance:T,count:1,state:null},h.set(v,T))}}function Y6(i,l){Oa.M(i,l);var f=os;if(f&&i){var h=Ci(f).hoistableScripts,v=ss(i),T=h.get(v);T||(T=f.querySelector($l(v)),T||(i=L({src:i,async:!0,type:"module"},l),(l=br.get(v))&&Fh(i,l),T=f.createElement("script"),rn(T),hn(T,"link",i),f.head.appendChild(T)),T={type:"script",instance:T,count:1,state:null},h.set(v,T))}}function O_(i,l,f,h){var v=(v=De.current)?td(v):null;if(!v)throw Error(r(446));switch(i){case"meta":case"title":return null;case"style":return typeof f.precedence=="string"&&typeof f.href=="string"?(l=is(f.href),f=Ci(v).hoistableStyles,h=f.get(l),h||(h={type:"style",instance:null,count:0,state:null},f.set(l,h)),h):{type:"void",instance:null,count:0,state:null};case"link":if(f.rel==="stylesheet"&&typeof f.href=="string"&&typeof f.precedence=="string"){i=is(f.href);var T=Ci(v).hoistableStyles,P=T.get(i);if(P||(v=v.ownerDocument||v,P={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},T.set(i,P),(T=v.querySelector(Hl(i)))&&!T._p&&(P.instance=T,P.state.loading=5),br.has(i)||(f={rel:"preload",as:"style",href:f.href,crossOrigin:f.crossOrigin,integrity:f.integrity,media:f.media,hrefLang:f.hrefLang,referrerPolicy:f.referrerPolicy},br.set(i,f),T||K6(v,i,f,P.state))),l&&h===null)throw Error(r(528,""));return P}if(l&&h!==null)throw Error(r(529,""));return null;case"script":return l=f.async,f=f.src,typeof f=="string"&&l&&typeof l!="function"&&typeof l!="symbol"?(l=ss(f),f=Ci(v).hoistableScripts,h=f.get(l),h||(h={type:"script",instance:null,count:0,state:null},f.set(l,h)),h):{type:"void",instance:null,count:0,state:null};default:throw Error(r(444,i))}}function is(i){return'href="'+sr(i)+'"'}function Hl(i){return'link[rel="stylesheet"]['+i+"]"}function D_(i){return L({},i,{"data-precedence":i.precedence,precedence:null})}function K6(i,l,f,h){i.querySelector('link[rel="preload"][as="style"]['+l+"]")?h.loading=1:(l=i.createElement("link"),h.preload=l,l.addEventListener("load",function(){return h.loading|=1}),l.addEventListener("error",function(){return h.loading|=2}),hn(l,"link",f),rn(l),i.head.appendChild(l))}function ss(i){return'[src="'+sr(i)+'"]'}function $l(i){return"script[async]"+i}function I_(i,l,f){if(l.count++,l.instance===null)switch(l.type){case"style":var h=i.querySelector('style[data-href~="'+sr(f.href)+'"]');if(h)return l.instance=h,rn(h),h;var v=L({},f,{"data-href":f.href,"data-precedence":f.precedence,href:null,precedence:null});return h=(i.ownerDocument||i).createElement("style"),rn(h),hn(h,"style",v),nd(h,f.precedence,i),l.instance=h;case"stylesheet":v=is(f.href);var T=i.querySelector(Hl(v));if(T)return l.state.loading|=4,l.instance=T,rn(T),T;h=D_(f),(v=br.get(v))&&Mh(h,v),T=(i.ownerDocument||i).createElement("link"),rn(T);var P=T;return P._p=new Promise(function(q,X){P.onload=q,P.onerror=X}),hn(T,"link",h),l.state.loading|=4,nd(T,f.precedence,i),l.instance=T;case"script":return T=ss(f.src),(v=i.querySelector($l(T)))?(l.instance=v,rn(v),v):(h=f,(v=br.get(T))&&(h=L({},f),Fh(h,v)),i=i.ownerDocument||i,v=i.createElement("script"),rn(v),hn(v,"link",h),i.head.appendChild(v),l.instance=v);case"void":return null;default:throw Error(r(443,l.type))}else l.type==="stylesheet"&&!(l.state.loading&4)&&(h=l.instance,l.state.loading|=4,nd(h,f.precedence,i));return l.instance}function nd(i,l,f){for(var h=f.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),v=h.length?h[h.length-1]:null,T=v,P=0;P title"):null)}function X6(i,l,f){if(f===1||l.itemProp!=null)return!1;switch(i){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 i=l.disabled,typeof l.precedence=="string"&&i==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 F_(i){return!(i.type==="stylesheet"&&!(i.state.loading&3))}var ql=null;function Z6(){}function Q6(i,l,f){if(ql===null)throw Error(r(475));var h=ql;if(l.type==="stylesheet"&&(typeof f.media!="string"||matchMedia(f.media).matches!==!1)&&!(l.state.loading&4)){if(l.instance===null){var v=is(f.href),T=i.querySelector(Hl(v));if(T){i=T._p,i!==null&&typeof i=="object"&&typeof i.then=="function"&&(h.count++,h=ad.bind(h),i.then(h,h)),l.state.loading|=4,l.instance=T,rn(T);return}T=i.ownerDocument||i,f=D_(f),(v=br.get(v))&&Mh(f,v),T=T.createElement("link"),rn(T);var P=T;P._p=new Promise(function(q,X){P.onload=q,P.onerror=X}),hn(T,"link",f),l.instance=T}h.stylesheets===null&&(h.stylesheets=new Map),h.stylesheets.set(l,i),(i=l.state.preload)&&!(l.state.loading&3)&&(h.count++,l=ad.bind(h),i.addEventListener("load",l),i.addEventListener("error",l))}}function J6(){if(ql===null)throw Error(r(475));var i=ql;return i.stylesheets&&i.count===0&&Ph(i,i.stylesheets),0"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}return e(),Vh.exports=S9(),Vh.exports}var w9=E9(),Jl={},aC;function x9(){if(aC)return Jl;aC=1,Object.defineProperty(Jl,"__esModule",{value:!0}),Jl.parse=s,Jl.serialize=d;const e=/^[\u0021-\u003A\u003C\u003E-\u007E]+$/,t=/^[\u0021-\u003A\u003C-\u007E]*$/,n=/^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i,r=/^[\u0020-\u003A\u003D-\u007E]*$/,a=Object.prototype.toString,o=(()=>{const m=function(){};return m.prototype=Object.create(null),m})();function s(m,b){const y=new o,S=m.length;if(S<2)return y;const k=(b==null?void 0:b.decode)||p;let R=0;do{const x=m.indexOf("=",R);if(x===-1)break;const A=m.indexOf(";",R),C=A===-1?S:A;if(x>C){R=m.lastIndexOf(";",x-1)+1;continue}const N=u(m,R,x),_=c(m,x,N),O=m.slice(N,_);if(y[O]===void 0){let F=u(m,x+1,C),D=c(m,C,F);const L=k(m.slice(F,D));y[O]=L}R=C+1}while(Ry;){const S=m.charCodeAt(--b);if(S!==32&&S!==9)return b+1}return y}function d(m,b,y){const S=(y==null?void 0:y.encode)||encodeURIComponent;if(!e.test(m))throw new TypeError(`argument name is invalid: ${m}`);const k=S(b);if(!t.test(k))throw new TypeError(`argument val is invalid: ${b}`);let R=m+"="+k;if(!y)return R;if(y.maxAge!==void 0){if(!Number.isInteger(y.maxAge))throw new TypeError(`option maxAge is invalid: ${y.maxAge}`);R+="; Max-Age="+y.maxAge}if(y.domain){if(!n.test(y.domain))throw new TypeError(`option domain is invalid: ${y.domain}`);R+="; Domain="+y.domain}if(y.path){if(!r.test(y.path))throw new TypeError(`option path is invalid: ${y.path}`);R+="; Path="+y.path}if(y.expires){if(!g(y.expires)||!Number.isFinite(y.expires.valueOf()))throw new TypeError(`option expires is invalid: ${y.expires}`);R+="; Expires="+y.expires.toUTCString()}if(y.httpOnly&&(R+="; HttpOnly"),y.secure&&(R+="; Secure"),y.partitioned&&(R+="; Partitioned"),y.priority)switch(typeof y.priority=="string"?y.priority.toLowerCase():void 0){case"low":R+="; Priority=Low";break;case"medium":R+="; Priority=Medium";break;case"high":R+="; Priority=High";break;default:throw new TypeError(`option priority is invalid: ${y.priority}`)}if(y.sameSite)switch(typeof y.sameSite=="string"?y.sameSite.toLowerCase():y.sameSite){case!0:case"strict":R+="; SameSite=Strict";break;case"lax":R+="; SameSite=Lax";break;case"none":R+="; SameSite=None";break;default:throw new TypeError(`option sameSite is invalid: ${y.sameSite}`)}return R}function p(m){if(m.indexOf("%")===-1)return m;try{return decodeURIComponent(m)}catch{return m}}function g(m){return a.call(m)==="[object Date]"}return Jl}x9();/** + * react-router v7.3.0 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */var oC="popstate";function k9(e={}){function t(a,o){let{pathname:s="/",search:u="",hash:c=""}=wi(a.location.hash.substring(1));return!s.startsWith("/")&&!s.startsWith(".")&&(s="/"+s),rk("",{pathname:s,search:u,hash:c},o.state&&o.state.usr||null,o.state&&o.state.key||"default")}function n(a,o){let s=a.document.querySelector("base"),u="";if(s&&s.getAttribute("href")){let c=a.location.href,d=c.indexOf("#");u=d===-1?c:c.slice(0,d)}return u+"#"+(typeof o=="string"?o:wu(o))}function r(a,o){wr(a.pathname.charAt(0)==="/",`relative pathnames are not supported in hash history.push(${JSON.stringify(o)})`)}return A9(t,n,r,e)}function zt(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function wr(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function T9(){return Math.random().toString(36).substring(2,10)}function iC(e,t){return{usr:e.state,key:e.key,idx:t}}function rk(e,t,n=null,r){return{pathname:typeof e=="string"?e:e.pathname,search:"",hash:"",...typeof t=="string"?wi(t):t,state:n,key:t&&t.key||r||T9()}}function wu({pathname:e="/",search:t="",hash:n=""}){return t&&t!=="?"&&(e+=t.charAt(0)==="?"?t:"?"+t),n&&n!=="#"&&(e+=n.charAt(0)==="#"?n:"#"+n),e}function wi(e){let t={};if(e){let n=e.indexOf("#");n>=0&&(t.hash=e.substring(n),e=e.substring(0,n));let r=e.indexOf("?");r>=0&&(t.search=e.substring(r),e=e.substring(0,r)),e&&(t.pathname=e)}return t}function A9(e,t,n,r={}){let{window:a=document.defaultView,v5Compat:o=!1}=r,s=a.history,u="POP",c=null,d=p();d==null&&(d=0,s.replaceState({...s.state,idx:d},""));function p(){return(s.state||{idx:null}).idx}function g(){u="POP";let k=p(),R=k==null?null:k-d;d=k,c&&c({action:u,location:S.location,delta:R})}function m(k,R){u="PUSH";let x=rk(S.location,k,R);n&&n(x,k),d=p()+1;let A=iC(x,d),C=S.createHref(x);try{s.pushState(A,"",C)}catch(N){if(N instanceof DOMException&&N.name==="DataCloneError")throw N;a.location.assign(C)}o&&c&&c({action:u,location:S.location,delta:1})}function b(k,R){u="REPLACE";let x=rk(S.location,k,R);n&&n(x,k),d=p();let A=iC(x,d),C=S.createHref(x);s.replaceState(A,"",C),o&&c&&c({action:u,location:S.location,delta:0})}function y(k){let R=a.location.origin!=="null"?a.location.origin:a.location.href,x=typeof k=="string"?k:wu(k);return x=x.replace(/ $/,"%20"),zt(R,`No window.location.(origin|href) available to create URL for href: ${x}`),new URL(x,R)}let S={get action(){return u},get location(){return e(a,s)},listen(k){if(c)throw new Error("A history only accepts one active listener");return a.addEventListener(oC,g),c=k,()=>{a.removeEventListener(oC,g),c=null}},createHref(k){return t(a,k)},createURL:y,encodeLocation(k){let R=y(k);return{pathname:R.pathname,search:R.search,hash:R.hash}},push:m,replace:b,go(k){return s.go(k)}};return S}function jz(e,t,n="/"){return R9(e,t,n,!1)}function R9(e,t,n,r){let a=typeof t=="string"?wi(t):t,o=Ga(a.pathname||"/",n);if(o==null)return null;let s=Gz(e);_9(s);let u=null;for(let c=0;u==null&&c{let c={relativePath:u===void 0?o.path||"":u,caseSensitive:o.caseSensitive===!0,childrenIndex:s,route:o};c.relativePath.startsWith("/")&&(zt(c.relativePath.startsWith(r),`Absolute route path "${c.relativePath}" nested under path "${r}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),c.relativePath=c.relativePath.slice(r.length));let d=Ua([r,c.relativePath]),p=n.concat(c);o.children&&o.children.length>0&&(zt(o.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${d}".`),Gz(o.children,t,p,d)),!(o.path==null&&!o.index)&&t.push({path:d,score:M9(d,o.index),routesMeta:p})};return e.forEach((o,s)=>{var u;if(o.path===""||!((u=o.path)!=null&&u.includes("?")))a(o,s);else for(let c of Hz(o.path))a(o,s,c)}),t}function Hz(e){let t=e.split("/");if(t.length===0)return[];let[n,...r]=t,a=n.endsWith("?"),o=n.replace(/\?$/,"");if(r.length===0)return a?[o,""]:[o];let s=Hz(r.join("/")),u=[];return u.push(...s.map(c=>c===""?o:[o,c].join("/"))),a&&u.push(...s),u.map(c=>e.startsWith("/")&&c===""?"/":c)}function _9(e){e.sort((t,n)=>t.score!==n.score?n.score-t.score:F9(t.routesMeta.map(r=>r.childrenIndex),n.routesMeta.map(r=>r.childrenIndex)))}var C9=/^:[\w-]+$/,N9=3,O9=2,D9=1,I9=10,L9=-2,sC=e=>e==="*";function M9(e,t){let n=e.split("/"),r=n.length;return n.some(sC)&&(r+=L9),t&&(r+=O9),n.filter(a=>!sC(a)).reduce((a,o)=>a+(C9.test(o)?N9:o===""?D9:I9),r)}function F9(e,t){return e.length===t.length&&e.slice(0,-1).every((r,a)=>r===t[a])?e[e.length-1]-t[t.length-1]:0}function P9(e,t,n=!1){let{routesMeta:r}=e,a={},o="/",s=[];for(let u=0;u{if(p==="*"){let y=u[m]||"";s=o.slice(0,o.length-y.length).replace(/(.)\/+$/,"$1")}const b=u[m];return g&&!b?d[p]=void 0:d[p]=(b||"").replace(/%2F/g,"/"),d},{}),pathname:o,pathnameBase:s,pattern:e}}function z9(e,t=!1,n=!0){wr(e==="*"||!e.endsWith("*")||e.endsWith("/*"),`Route path "${e}" will be treated as if it were "${e.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${e.replace(/\*$/,"/*")}".`);let r=[],a="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(s,u,c)=>(r.push({paramName:u,isOptional:c!=null}),c?"/?([^\\/]+)?":"/([^\\/]+)"));return e.endsWith("*")?(r.push({paramName:"*"}),a+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?a+="\\/*$":e!==""&&e!=="/"&&(a+="(?:(?=\\/|$))"),[new RegExp(a,t?void 0:"i"),r]}function B9(e){try{return e.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return wr(!1,`The URL path "${e}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${t}).`),e}}function Ga(e,t){if(t==="/")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith("/")?t.length-1:t.length,r=e.charAt(n);return r&&r!=="/"?null:e.slice(n)||"/"}function U9(e,t="/"){let{pathname:n,search:r="",hash:a=""}=typeof e=="string"?wi(e):e;return{pathname:n?n.startsWith("/")?n:j9(n,t):t,search:$9(r),hash:q9(a)}}function j9(e,t){let n=t.replace(/\/+$/,"").split("/");return e.split("/").forEach(a=>{a===".."?n.length>1&&n.pop():a!=="."&&n.push(a)}),n.length>1?n.join("/"):"/"}function Xh(e,t,n,r){return`Cannot include a '${e}' character in a manually specified \`to.${t}\` field [${JSON.stringify(r)}]. Please separate it out to the \`to.${n}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function G9(e){return e.filter((t,n)=>n===0||t.route.path&&t.route.path.length>0)}function S0(e){let t=G9(e);return t.map((n,r)=>r===t.length-1?n.pathname:n.pathnameBase)}function E0(e,t,n,r=!1){let a;typeof e=="string"?a=wi(e):(a={...e},zt(!a.pathname||!a.pathname.includes("?"),Xh("?","pathname","search",a)),zt(!a.pathname||!a.pathname.includes("#"),Xh("#","pathname","hash",a)),zt(!a.search||!a.search.includes("#"),Xh("#","search","hash",a)));let o=e===""||a.pathname==="",s=o?"/":a.pathname,u;if(s==null)u=n;else{let g=t.length-1;if(!r&&s.startsWith("..")){let m=s.split("/");for(;m[0]==="..";)m.shift(),g-=1;a.pathname=m.join("/")}u=g>=0?t[g]:"/"}let c=U9(a,u),d=s&&s!=="/"&&s.endsWith("/"),p=(o||s===".")&&n.endsWith("/");return!c.pathname.endsWith("/")&&(d||p)&&(c.pathname+="/"),c}var Ua=e=>e.join("/").replace(/\/\/+/g,"/"),H9=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),$9=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,q9=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e;function V9(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}var $z=["POST","PUT","PATCH","DELETE"];new Set($z);var W9=["GET",...$z];new Set(W9);var Bs=E.createContext(null);Bs.displayName="DataRouter";var $f=E.createContext(null);$f.displayName="DataRouterState";var qz=E.createContext({isTransitioning:!1});qz.displayName="ViewTransition";var Y9=E.createContext(new Map);Y9.displayName="Fetchers";var K9=E.createContext(null);K9.displayName="Await";var Gr=E.createContext(null);Gr.displayName="Navigation";var Bu=E.createContext(null);Bu.displayName="Location";var sa=E.createContext({outlet:null,matches:[],isDataRoute:!1});sa.displayName="Route";var w0=E.createContext(null);w0.displayName="RouteError";function X9(e,{relative:t}={}){zt(Us(),"useHref() may be used only in the context of a component.");let{basename:n,navigator:r}=E.useContext(Gr),{hash:a,pathname:o,search:s}=Uu(e,{relative:t}),u=o;return n!=="/"&&(u=o==="/"?n:Ua([n,o])),r.createHref({pathname:u,search:s,hash:a})}function Us(){return E.useContext(Bu)!=null}function Io(){return zt(Us(),"useLocation() may be used only in the context of a component."),E.useContext(Bu).location}var Vz="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function Wz(e){E.useContext(Gr).static||E.useLayoutEffect(e)}function qf(){let{isDataRoute:e}=E.useContext(sa);return e?uq():Z9()}function Z9(){zt(Us(),"useNavigate() may be used only in the context of a component.");let e=E.useContext(Bs),{basename:t,navigator:n}=E.useContext(Gr),{matches:r}=E.useContext(sa),{pathname:a}=Io(),o=JSON.stringify(S0(r)),s=E.useRef(!1);return Wz(()=>{s.current=!0}),E.useCallback((c,d={})=>{if(wr(s.current,Vz),!s.current)return;if(typeof c=="number"){n.go(c);return}let p=E0(c,JSON.parse(o),a,d.relative==="path");e==null&&t!=="/"&&(p.pathname=p.pathname==="/"?t:Ua([t,p.pathname])),(d.replace?n.replace:n.push)(p,d.state,d)},[t,n,o,a,e])}E.createContext(null);function Uu(e,{relative:t}={}){let{matches:n}=E.useContext(sa),{pathname:r}=Io(),a=JSON.stringify(S0(n));return E.useMemo(()=>E0(e,JSON.parse(a),r,t==="path"),[e,a,r,t])}function Q9(e,t){return Yz(e,t)}function Yz(e,t,n,r){var x;zt(Us(),"useRoutes() may be used only in the context of a component.");let{navigator:a,static:o}=E.useContext(Gr),{matches:s}=E.useContext(sa),u=s[s.length-1],c=u?u.params:{},d=u?u.pathname:"/",p=u?u.pathnameBase:"/",g=u&&u.route;{let A=g&&g.path||"";Kz(d,!g||A.endsWith("*")||A.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${d}" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. + +Please change the parent to .`)}let m=Io(),b;if(t){let A=typeof t=="string"?wi(t):t;zt(p==="/"||((x=A.pathname)==null?void 0:x.startsWith(p)),`When overriding the location using \`\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${p}" but pathname "${A.pathname}" was given in the \`location\` prop.`),b=A}else b=m;let y=b.pathname||"/",S=y;if(p!=="/"){let A=p.replace(/^\//,"").split("/");S="/"+y.replace(/^\//,"").split("/").slice(A.length).join("/")}let k=!o&&n&&n.matches&&n.matches.length>0?n.matches:jz(e,{pathname:S});wr(g||k!=null,`No routes matched location "${b.pathname}${b.search}${b.hash}" `),wr(k==null||k[k.length-1].route.element!==void 0||k[k.length-1].route.Component!==void 0||k[k.length-1].route.lazy!==void 0,`Matched leaf route at location "${b.pathname}${b.search}${b.hash}" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.`);let R=rq(k&&k.map(A=>Object.assign({},A,{params:Object.assign({},c,A.params),pathname:Ua([p,a.encodeLocation?a.encodeLocation(A.pathname).pathname:A.pathname]),pathnameBase:A.pathnameBase==="/"?p:Ua([p,a.encodeLocation?a.encodeLocation(A.pathnameBase).pathname:A.pathnameBase])})),s,n,r);return t&&R?E.createElement(Bu.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",...b},navigationType:"POP"}},R):R}function J9(){let e=lq(),t=V9(e)?`${e.status} ${e.statusText}`:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,r="rgba(200,200,200, 0.5)",a={padding:"0.5rem",backgroundColor:r},o={padding:"2px 4px",backgroundColor:r},s=null;return console.error("Error handled by React Router default ErrorBoundary:",e),s=E.createElement(E.Fragment,null,E.createElement("p",null,"💿 Hey developer 👋"),E.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",E.createElement("code",{style:o},"ErrorBoundary")," or"," ",E.createElement("code",{style:o},"errorElement")," prop on your route.")),E.createElement(E.Fragment,null,E.createElement("h2",null,"Unexpected Application Error!"),E.createElement("h3",{style:{fontStyle:"italic"}},t),n?E.createElement("pre",{style:a},n):null,s)}var eq=E.createElement(J9,null),tq=class extends E.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||t.revalidation!=="idle"&&e.revalidation==="idle"?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error!==void 0?e.error:t.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){console.error("React Router caught the following error during render",e,t)}render(){return this.state.error!==void 0?E.createElement(sa.Provider,{value:this.props.routeContext},E.createElement(w0.Provider,{value:this.state.error,children:this.props.component})):this.props.children}};function nq({routeContext:e,match:t,children:n}){let r=E.useContext(Bs);return r&&r.static&&r.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=t.route.id),E.createElement(sa.Provider,{value:e},n)}function rq(e,t=[],n=null,r=null){if(e==null){if(!n)return null;if(n.errors)e=n.matches;else if(t.length===0&&!n.initialized&&n.matches.length>0)e=n.matches;else return null}let a=e,o=n==null?void 0:n.errors;if(o!=null){let c=a.findIndex(d=>d.route.id&&(o==null?void 0:o[d.route.id])!==void 0);zt(c>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(o).join(",")}`),a=a.slice(0,Math.min(a.length,c+1))}let s=!1,u=-1;if(n)for(let c=0;c=0?a=a.slice(0,u+1):a=[a[0]];break}}}return a.reduceRight((c,d,p)=>{let g,m=!1,b=null,y=null;n&&(g=o&&d.route.id?o[d.route.id]:void 0,b=d.route.errorElement||eq,s&&(u<0&&p===0?(Kz("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),m=!0,y=null):u===p&&(m=!0,y=d.route.hydrateFallbackElement||null)));let S=t.concat(a.slice(0,p+1)),k=()=>{let R;return g?R=b:m?R=y:d.route.Component?R=E.createElement(d.route.Component,null):d.route.element?R=d.route.element:R=c,E.createElement(nq,{match:d,routeContext:{outlet:c,matches:S,isDataRoute:n!=null},children:R})};return n&&(d.route.ErrorBoundary||d.route.errorElement||p===0)?E.createElement(tq,{location:n.location,revalidation:n.revalidation,component:b,error:g,children:k(),routeContext:{outlet:null,matches:S,isDataRoute:!0}}):k()},null)}function x0(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function aq(e){let t=E.useContext(Bs);return zt(t,x0(e)),t}function oq(e){let t=E.useContext($f);return zt(t,x0(e)),t}function iq(e){let t=E.useContext(sa);return zt(t,x0(e)),t}function k0(e){let t=iq(e),n=t.matches[t.matches.length-1];return zt(n.route.id,`${e} can only be used on routes that contain a unique "id"`),n.route.id}function sq(){return k0("useRouteId")}function lq(){var r;let e=E.useContext(w0),t=oq("useRouteError"),n=k0("useRouteError");return e!==void 0?e:(r=t.errors)==null?void 0:r[n]}function uq(){let{router:e}=aq("useNavigate"),t=k0("useNavigate"),n=E.useRef(!1);return Wz(()=>{n.current=!0}),E.useCallback(async(a,o={})=>{wr(n.current,Vz),n.current&&(typeof a=="number"?e.navigate(a):await e.navigate(a,{fromRouteId:t,...o}))},[e,t])}var lC={};function Kz(e,t,n){!t&&!lC[e]&&(lC[e]=!0,wr(!1,n))}E.memo(cq);function cq({routes:e,future:t,state:n}){return Yz(e,void 0,n,t)}function dq({to:e,replace:t,state:n,relative:r}){zt(Us()," may be used only in the context of a component.");let{static:a}=E.useContext(Gr);wr(!a," must not be used on the initial render in a . This is a no-op, but you should modify your code so the is only ever rendered in response to some user interaction or state change.");let{matches:o}=E.useContext(sa),{pathname:s}=Io(),u=qf(),c=E0(e,S0(o),s,r==="path"),d=JSON.stringify(c);return E.useEffect(()=>{u(JSON.parse(d),{replace:t,state:n,relative:r})},[u,d,r,t,n]),null}function ak(e){zt(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function fq({basename:e="/",children:t=null,location:n,navigationType:r="POP",navigator:a,static:o=!1}){zt(!Us(),"You cannot render a inside another . You should never have more than one in your app.");let s=e.replace(/^\/*/,"/"),u=E.useMemo(()=>({basename:s,navigator:a,static:o,future:{}}),[s,a,o]);typeof n=="string"&&(n=wi(n));let{pathname:c="/",search:d="",hash:p="",state:g=null,key:m="default"}=n,b=E.useMemo(()=>{let y=Ga(c,s);return y==null?null:{location:{pathname:y,search:d,hash:p,state:g,key:m},navigationType:r}},[s,c,d,p,g,m,r]);return wr(b!=null,` is not able to match the URL "${c}${d}${p}" because it does not start with the basename, so the won't render anything.`),b==null?null:E.createElement(Gr.Provider,{value:u},E.createElement(Bu.Provider,{children:t,value:b}))}function pq({children:e,location:t}){return Q9(ok(e),t)}function ok(e,t=[]){let n=[];return E.Children.forEach(e,(r,a)=>{if(!E.isValidElement(r))return;let o=[...t,a];if(r.type===E.Fragment){n.push.apply(n,ok(r.props.children,o));return}zt(r.type===ak,`[${typeof r.type=="string"?r.type:r.type.name}] is not a component. All component children of must be a or `),zt(!r.props.index||!r.props.children,"An index route cannot have child routes.");let s={id:r.props.id||o.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,loader:r.props.loader,action:r.props.action,hydrateFallbackElement:r.props.hydrateFallbackElement,HydrateFallback:r.props.HydrateFallback,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.hasErrorBoundary===!0||r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(s.children=ok(r.props.children,o)),n.push(s)}),n}var $d="get",qd="application/x-www-form-urlencoded";function Vf(e){return e!=null&&typeof e.tagName=="string"}function gq(e){return Vf(e)&&e.tagName.toLowerCase()==="button"}function hq(e){return Vf(e)&&e.tagName.toLowerCase()==="form"}function mq(e){return Vf(e)&&e.tagName.toLowerCase()==="input"}function bq(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function yq(e,t){return e.button===0&&(!t||t==="_self")&&!bq(e)}var pd=null;function vq(){if(pd===null)try{new FormData(document.createElement("form"),0),pd=!1}catch{pd=!0}return pd}var Sq=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Zh(e){return e!=null&&!Sq.has(e)?(wr(!1,`"${e}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${qd}"`),null):e}function Eq(e,t){let n,r,a,o,s;if(hq(e)){let u=e.getAttribute("action");r=u?Ga(u,t):null,n=e.getAttribute("method")||$d,a=Zh(e.getAttribute("enctype"))||qd,o=new FormData(e)}else if(gq(e)||mq(e)&&(e.type==="submit"||e.type==="image")){let u=e.form;if(u==null)throw new Error('Cannot submit a diff --git a/lightrag_webui/src/components/LanguageToggle.tsx b/lightrag_webui/src/components/LanguageToggle.tsx new file mode 100644 index 00000000..0eab780e --- /dev/null +++ b/lightrag_webui/src/components/LanguageToggle.tsx @@ -0,0 +1,49 @@ +import Button from '@/components/ui/Button' +import { useCallback } from 'react' +import { controlButtonVariant } from '@/lib/constants' +import { useTranslation } from 'react-i18next' +import { useSettingsStore } from '@/stores/settings' + +/** + * Component that toggles the language between English and Chinese. + */ +export default function LanguageToggle() { + const { i18n } = useTranslation() + const currentLanguage = i18n.language + const setLanguage = useSettingsStore.use.setLanguage() + + const setEnglish = useCallback(() => { + i18n.changeLanguage('en') + setLanguage('en') + }, [i18n, setLanguage]) + + const setChinese = useCallback(() => { + i18n.changeLanguage('zh') + setLanguage('zh') + }, [i18n, setLanguage]) + + if (currentLanguage === 'zh') { + return ( + + ) + } + return ( + + ) +} diff --git a/lightrag_webui/src/components/graph/FocusOnNode.tsx b/lightrag_webui/src/components/graph/FocusOnNode.tsx index 70af7525..3f3cf027 100644 --- a/lightrag_webui/src/components/graph/FocusOnNode.tsx +++ b/lightrag_webui/src/components/graph/FocusOnNode.tsx @@ -13,23 +13,37 @@ const FocusOnNode = ({ node, move }: { node: string | null; move?: boolean }) => * When the selected item changes, highlighted the node and center the camera on it. */ useEffect(() => { + const graph = sigma.getGraph(); + if (move) { - if (node) { - sigma.getGraph().setNodeAttribute(node, 'highlighted', true) - gotoNode(node) + if (node && graph.hasNode(node)) { + try { + graph.setNodeAttribute(node, 'highlighted', true); + gotoNode(node); + } catch (error) { + console.error('Error focusing on node:', error); + } } else { // If no node is selected but move is true, reset to default view - sigma.setCustomBBox(null) - sigma.getCamera().animate({ x: 0.5, y: 0.5, ratio: 1 }, { duration: 0 }) + sigma.setCustomBBox(null); + sigma.getCamera().animate({ x: 0.5, y: 0.5, ratio: 1 }, { duration: 0 }); + } + useGraphStore.getState().setMoveToSelectedNode(false); + } else if (node && graph.hasNode(node)) { + try { + graph.setNodeAttribute(node, 'highlighted', true); + } catch (error) { + console.error('Error highlighting node:', error); } - useGraphStore.getState().setMoveToSelectedNode(false) - } else if (node) { - sigma.getGraph().setNodeAttribute(node, 'highlighted', true) } return () => { - if (node) { - sigma.getGraph().setNodeAttribute(node, 'highlighted', false) + if (node && graph.hasNode(node)) { + try { + graph.setNodeAttribute(node, 'highlighted', false); + } catch (error) { + console.error('Error cleaning up node highlight:', error); + } } } }, [node, move, sigma, gotoNode]) diff --git a/lightrag_webui/src/components/graph/GraphControl.tsx b/lightrag_webui/src/components/graph/GraphControl.tsx index 7d014316..baa98bfe 100644 --- a/lightrag_webui/src/components/graph/GraphControl.tsx +++ b/lightrag_webui/src/components/graph/GraphControl.tsx @@ -1,5 +1,5 @@ -import { useLoadGraph, useRegisterEvents, useSetSettings, useSigma } from '@react-sigma/core' -import Graph from 'graphology' +import { useRegisterEvents, useSetSettings, useSigma } from '@react-sigma/core' +import { AbstractGraph } from 'graphology-types' // import { useLayoutCircular } from '@react-sigma/layout-circular' import { useLayoutForceAtlas2 } from '@react-sigma/layout-forceatlas2' import { useEffect } from 'react' @@ -25,7 +25,6 @@ const GraphControl = ({ disableHoverEffect }: { disableHoverEffect?: boolean }) const sigma = useSigma() const registerEvents = useRegisterEvents() const setSettings = useSetSettings() - const loadGraph = useLoadGraph() const maxIterations = useSettingsStore.use.graphLayoutMaxIterations() const { assign: assignLayout } = useLayoutForceAtlas2({ @@ -45,14 +44,42 @@ const GraphControl = ({ disableHoverEffect }: { disableHoverEffect?: boolean }) /** * When component mount or maxIterations changes - * => load the graph and apply layout + * => ensure graph reference and apply layout */ useEffect(() => { - if (sigmaGraph) { - loadGraph(sigmaGraph as unknown as Graph) - assignLayout() + if (sigmaGraph && sigma) { + // Ensure sigma binding to sigmaGraph + try { + if (typeof sigma.setGraph === 'function') { + sigma.setGraph(sigmaGraph as unknown as AbstractGraph); + console.log('Binding graph to sigma instance'); + } else { + (sigma as any).graph = sigmaGraph; + console.warn('Simgma missing setGraph function, set graph property directly'); + } + } catch (error) { + console.error('Error setting graph on sigma instance:', error); + } + + assignLayout(); + console.log('Initial layout applied to graph'); } - }, [assignLayout, loadGraph, sigmaGraph, maxIterations]) + }, [sigma, sigmaGraph, assignLayout, maxIterations]) + + /** + * Ensure the sigma instance is set in the store + * This provides a backup in case the instance wasn't set in GraphViewer + */ + useEffect(() => { + if (sigma) { + // Double-check that the store has the sigma instance + const currentInstance = useGraphStore.getState().sigmaInstance; + if (!currentInstance) { + console.log('Setting sigma instance from GraphControl'); + useGraphStore.getState().setSigmaInstance(sigma); + } + } + }, [sigma]); /** * When component mount @@ -138,14 +165,18 @@ const GraphControl = ({ disableHoverEffect }: { disableHoverEffect?: boolean }) const _focusedNode = focusedNode || selectedNode const _focusedEdge = focusedEdge || selectedEdge - if (_focusedNode) { - if (node === _focusedNode || graph.neighbors(_focusedNode).includes(node)) { - newData.highlighted = true - if (node === selectedNode) { - newData.borderColor = Constants.nodeBorderColorSelected + if (_focusedNode && graph.hasNode(_focusedNode)) { + try { + if (node === _focusedNode || graph.neighbors(_focusedNode).includes(node)) { + newData.highlighted = true + if (node === selectedNode) { + newData.borderColor = Constants.nodeBorderColorSelected + } } + } catch (error) { + console.error('Error in nodeReducer:', error); } - } else if (_focusedEdge) { + } else if (_focusedEdge && graph.hasEdge(_focusedEdge)) { if (graph.extremities(_focusedEdge).includes(node)) { newData.highlighted = true newData.size = 3 @@ -173,21 +204,28 @@ const GraphControl = ({ disableHoverEffect }: { disableHoverEffect?: boolean }) if (!disableHoverEffect) { const _focusedNode = focusedNode || selectedNode - if (_focusedNode) { - if (hideUnselectedEdges) { - if (!graph.extremities(edge).includes(_focusedNode)) { - newData.hidden = true - } - } else { - if (graph.extremities(edge).includes(_focusedNode)) { - newData.color = Constants.edgeColorHighlighted + if (_focusedNode && graph.hasNode(_focusedNode)) { + try { + if (hideUnselectedEdges) { + if (!graph.extremities(edge).includes(_focusedNode)) { + newData.hidden = true + } + } else { + if (graph.extremities(edge).includes(_focusedNode)) { + newData.color = Constants.edgeColorHighlighted + } } + } catch (error) { + console.error('Error in edgeReducer:', error); } } else { - if (focusedEdge || selectedEdge) { - if (edge === selectedEdge) { + const _selectedEdge = selectedEdge && graph.hasEdge(selectedEdge) ? selectedEdge : null; + const _focusedEdge = focusedEdge && graph.hasEdge(focusedEdge) ? focusedEdge : null; + + if (_selectedEdge || _focusedEdge) { + if (edge === _selectedEdge) { newData.color = Constants.edgeColorSelected - } else if (edge === focusedEdge) { + } else if (edge === _focusedEdge) { newData.color = Constants.edgeColorHighlighted } else if (hideUnselectedEdges) { newData.hidden = true diff --git a/lightrag_webui/src/components/graph/GraphLabels.tsx b/lightrag_webui/src/components/graph/GraphLabels.tsx index bd2c8ea0..606a2d60 100644 --- a/lightrag_webui/src/components/graph/GraphLabels.tsx +++ b/lightrag_webui/src/components/graph/GraphLabels.tsx @@ -2,14 +2,17 @@ import { useCallback, useEffect, useRef } from 'react' import { AsyncSelect } from '@/components/ui/AsyncSelect' import { useSettingsStore } from '@/stores/settings' import { useGraphStore } from '@/stores/graph' -import { labelListLimit } from '@/lib/constants' +import { labelListLimit, controlButtonVariant } from '@/lib/constants' import MiniSearch from 'minisearch' import { useTranslation } from 'react-i18next' +import { RefreshCw } from 'lucide-react' +import Button from '@/components/ui/Button' const GraphLabels = () => { const { t } = useTranslation() const label = useSettingsStore.use.queryLabel() const allDatabaseLabels = useGraphStore.use.allDatabaseLabels() + const rawGraph = useGraphStore.use.rawGraph() const labelsLoadedRef = useRef(false) // Track if a fetch is in progress to prevent multiple simultaneous fetches @@ -83,52 +86,70 @@ const GraphLabels = () => { [getSearchEngine] ) + const handleRefresh = useCallback(() => { + const currentLabel = useSettingsStore.getState().queryLabel + + useGraphStore.getState().setGraphDataFetchAttempted(false) + + useGraphStore.getState().reset() + + useSettingsStore.getState().setQueryLabel(currentLabel) + }, []) + return ( - - className="ml-2" - triggerClassName="max-h-8" - searchInputClassName="max-h-8" - triggerTooltip={t('graphPanel.graphLabels.selectTooltip')} - fetcher={fetchData} - renderOption={(item) =>
{item}
} - getOptionValue={(item) => item} - getDisplayValue={(item) =>
{item}
} - notFound={
No labels found
} - label={t('graphPanel.graphLabels.label')} - placeholder={t('graphPanel.graphLabels.placeholder')} - value={label !== null ? label : '*'} - onChange={(newLabel) => { - const currentLabel = useSettingsStore.getState().queryLabel +
+ {rawGraph && ( + + )} + + className="ml-2" + triggerClassName="max-h-8" + searchInputClassName="max-h-8" + triggerTooltip={t('graphPanel.graphLabels.selectTooltip')} + fetcher={fetchData} + renderOption={(item) =>
{item}
} + getOptionValue={(item) => item} + getDisplayValue={(item) =>
{item}
} + notFound={
No labels found
} + label={t('graphPanel.graphLabels.label')} + placeholder={t('graphPanel.graphLabels.placeholder')} + value={label !== null ? label : '*'} + onChange={(newLabel) => { + const currentLabel = useSettingsStore.getState().queryLabel - // select the last item means query all - if (newLabel === '...') { - newLabel = '*' - } - - // Reset the fetch attempted flag to force a new data fetch - useGraphStore.getState().setGraphDataFetchAttempted(false) - - // Clear current graph data to ensure complete reload when label changes - if (newLabel !== currentLabel) { - const graphStore = useGraphStore.getState(); - graphStore.clearSelection(); - - // Reset the graph state but preserve the instance - if (graphStore.sigmaGraph) { - const nodes = Array.from(graphStore.sigmaGraph.nodes()); - nodes.forEach(node => graphStore.sigmaGraph?.dropNode(node)); + // select the last item means query all + if (newLabel === '...') { + newLabel = '*' } - } - if (newLabel === currentLabel && newLabel !== '*') { - // reselect the same itme means qery all - useSettingsStore.getState().setQueryLabel('*') - } else { - useSettingsStore.getState().setQueryLabel(newLabel) - } - }} - clearable={false} // Prevent clearing value on reselect - /> + // Reset the fetch attempted flag to force a new data fetch + useGraphStore.getState().setGraphDataFetchAttempted(false) + + // Clear current graph data to ensure complete reload when label changes + if (newLabel !== currentLabel) { + const graphStore = useGraphStore.getState(); + // Reset the all graph objects and status + graphStore.reset(); + } + + if (newLabel === currentLabel && newLabel !== '*') { + // reselect the same itme means qery all + useSettingsStore.getState().setQueryLabel('*') + } else { + useSettingsStore.getState().setQueryLabel(newLabel) + } + }} + clearable={false} // Prevent clearing value on reselect + /> +
) } diff --git a/lightrag_webui/src/components/graph/GraphSearch.tsx b/lightrag_webui/src/components/graph/GraphSearch.tsx index 2ba36bda..51e76a0b 100644 --- a/lightrag_webui/src/components/graph/GraphSearch.tsx +++ b/lightrag_webui/src/components/graph/GraphSearch.tsx @@ -1,4 +1,4 @@ -import { FC, useCallback, useEffect, useMemo } from 'react' +import { FC, useCallback, useEffect } from 'react' import { EdgeById, NodeById, @@ -11,28 +11,34 @@ import { useGraphStore } from '@/stores/graph' import MiniSearch from 'minisearch' import { useTranslation } from 'react-i18next' -interface OptionItem { +// Message item identifier for search results +export const messageId = '__message_item' + +// Search result option item interface +export interface OptionItem { id: string type: 'nodes' | 'edges' | 'message' message?: string } +const NodeOption = ({ id }: { id: string }) => { + const graph = useGraphStore.use.sigmaGraph() + if (!graph?.hasNode(id)) { + return null + } + return +} + function OptionComponent(item: OptionItem) { return (
- {item.type === 'nodes' && } + {item.type === 'nodes' && } {item.type === 'edges' && } {item.type === 'message' &&
{item.message}
}
) } -const messageId = '__message_item' -// Reset this cache when graph changes to ensure fresh search results -const lastGraph: any = { - graph: null, - searchEngine: null -} /** * Component thats display the search input. @@ -48,25 +54,24 @@ export const GraphSearchInput = ({ }) => { const { t } = useTranslation() const graph = useGraphStore.use.sigmaGraph() + const searchEngine = useGraphStore.use.searchEngine() - // Force reset the cache when graph changes + // Reset search engine when graph changes useEffect(() => { if (graph) { - // Reset cache to ensure fresh search results with new graph data - lastGraph.graph = null; - lastGraph.searchEngine = null; + useGraphStore.getState().resetSearchEngine() } }, [graph]); - const searchEngine = useMemo(() => { - if (lastGraph.graph == graph) { - return lastGraph.searchEngine + // Create search engine when needed + useEffect(() => { + // Skip if no graph, empty graph, or search engine already exists + if (!graph || graph.nodes().length === 0 || searchEngine) { + return } - if (!graph || graph.nodes().length == 0) return - lastGraph.graph = graph - - const searchEngine = new MiniSearch({ + // Create new search engine + const newSearchEngine = new MiniSearch({ idField: 'id', fields: ['label'], searchOptions: { @@ -78,16 +83,16 @@ export const GraphSearchInput = ({ } }) - // Add documents + // Add nodes to search engine const documents = graph.nodes().map((id: string) => ({ id: id, label: graph.getNodeAttribute(id, 'label') })) - searchEngine.addAll(documents) + newSearchEngine.addAll(documents) - lastGraph.searchEngine = searchEngine - return searchEngine - }, [graph]) + // Update search engine in store + useGraphStore.getState().setSearchEngine(newSearchEngine) + }, [graph, searchEngine]) /** * Loading the options while the user is typing. @@ -95,22 +100,35 @@ export const GraphSearchInput = ({ const loadOptions = useCallback( async (query?: string): Promise => { if (onFocus) onFocus(null) - if (!graph || !searchEngine) return [] - // If no query, return first searchResultLimit nodes + // Safety checks to prevent crashes + if (!graph || !searchEngine) { + return [] + } + + // Verify graph has nodes before proceeding + if (graph.nodes().length === 0) { + return [] + } + + // If no query, return some nodes for user to select if (!query) { - const nodeIds = graph.nodes().slice(0, searchResultLimit) + const nodeIds = graph.nodes() + .filter(id => graph.hasNode(id)) + .slice(0, searchResultLimit) return nodeIds.map(id => ({ id, type: 'nodes' })) } - // If has query, search nodes - const result: OptionItem[] = searchEngine.search(query).map((r: { id: string }) => ({ - id: r.id, - type: 'nodes' - })) + // If has query, search nodes and verify they still exist + const result: OptionItem[] = searchEngine.search(query) + .filter((r: { id: string }) => graph.hasNode(r.id)) + .map((r: { id: string }) => ({ + id: r.id, + type: 'nodes' + })) // prettier-ignore return result.length <= searchResultLimit diff --git a/lightrag_webui/src/components/graph/LayoutsControl.tsx b/lightrag_webui/src/components/graph/LayoutsControl.tsx index 0ed97f2f..2f0cc50a 100644 --- a/lightrag_webui/src/components/graph/LayoutsControl.tsx +++ b/lightrag_webui/src/components/graph/LayoutsControl.tsx @@ -7,7 +7,7 @@ import { useLayoutForce, useWorkerLayoutForce } from '@react-sigma/layout-force' import { useLayoutForceAtlas2, useWorkerLayoutForceAtlas2 } from '@react-sigma/layout-forceatlas2' import { useLayoutNoverlap, useWorkerLayoutNoverlap } from '@react-sigma/layout-noverlap' import { useLayoutRandom } from '@react-sigma/layout-random' -import { useCallback, useMemo, useState, useEffect } from 'react' +import { useCallback, useMemo, useState, useEffect, useRef } from 'react' import Button from '@/components/ui/Button' import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/Popover' @@ -26,43 +26,161 @@ type LayoutName = | 'Force Directed' | 'Force Atlas' -const WorkerLayoutControl = ({ layout, autoRunFor }: WorkerLayoutControlProps) => { +// Extend WorkerLayoutControlProps to include mainLayout +interface ExtendedWorkerLayoutControlProps extends WorkerLayoutControlProps { + mainLayout: LayoutHook; +} + +const WorkerLayoutControl = ({ layout, autoRunFor, mainLayout }: ExtendedWorkerLayoutControlProps) => { const sigma = useSigma() - const { stop, start, isRunning } = layout + // Use local state to track animation running status + const [isRunning, setIsRunning] = useState(false) + // Timer reference for animation + const animationTimerRef = useRef(null) const { t } = useTranslation() + // Function to update node positions using the layout algorithm + const updatePositions = useCallback(() => { + if (!sigma) return + + try { + const graph = sigma.getGraph() + if (!graph || graph.order === 0) return + + // Use mainLayout to get positions, similar to refreshLayout function + // console.log('Getting positions from mainLayout') + const positions = mainLayout.positions() + + // Animate nodes to new positions + // console.log('Updating node positions with layout algorithm') + animateNodes(graph, positions, { duration: 300 }) // Reduced duration for more frequent updates + } catch (error) { + console.error('Error updating positions:', error) + // Stop animation if there's an error + if (animationTimerRef.current) { + window.clearInterval(animationTimerRef.current) + animationTimerRef.current = null + setIsRunning(false) + } + } + }, [sigma, mainLayout]) + + // Improved click handler that uses our own animation timer + const handleClick = useCallback(() => { + if (isRunning) { + // Stop the animation + console.log('Stopping layout animation') + if (animationTimerRef.current) { + window.clearInterval(animationTimerRef.current) + animationTimerRef.current = null + } + + // Try to kill the layout algorithm if it's running + try { + if (typeof layout.kill === 'function') { + layout.kill() + console.log('Layout algorithm killed') + } else if (typeof layout.stop === 'function') { + layout.stop() + console.log('Layout algorithm stopped') + } + } catch (error) { + console.error('Error stopping layout algorithm:', error) + } + + setIsRunning(false) + } else { + // Start the animation + console.log('Starting layout animation') + + // Initial position update + updatePositions() + + // Set up interval for continuous updates + animationTimerRef.current = window.setInterval(() => { + updatePositions() + }, 200) // Reduced interval to create overlapping animations for smoother transitions + + setIsRunning(true) + + // Set a timeout to automatically stop the animation after 3 seconds + setTimeout(() => { + if (animationTimerRef.current) { + console.log('Auto-stopping layout animation after 3 seconds') + window.clearInterval(animationTimerRef.current) + animationTimerRef.current = null + setIsRunning(false) + + // Try to stop the layout algorithm + try { + if (typeof layout.kill === 'function') { + layout.kill() + } else if (typeof layout.stop === 'function') { + layout.stop() + } + } catch (error) { + console.error('Error stopping layout algorithm:', error) + } + } + }, 3000) + } + }, [isRunning, layout, updatePositions]) + /** * Init component when Sigma or component settings change. */ useEffect(() => { if (!sigma) { + console.log('No sigma instance available') return } - // we run the algo + // Auto-run if specified let timeout: number | null = null if (autoRunFor !== undefined && autoRunFor > -1 && sigma.getGraph().order > 0) { - start() - // set a timeout to stop it - timeout = - autoRunFor > 0 - ? window.setTimeout(() => { stop() }, autoRunFor) // prettier-ignore - : null - } + console.log('Auto-starting layout animation') - //cleaning - return () => { - stop() - if (timeout) { - clearTimeout(timeout) + // Initial position update + updatePositions() + + // Set up interval for continuous updates + animationTimerRef.current = window.setInterval(() => { + updatePositions() + }, 200) // Reduced interval to create overlapping animations for smoother transitions + + setIsRunning(true) + + // Set a timeout to stop it if autoRunFor > 0 + if (autoRunFor > 0) { + timeout = window.setTimeout(() => { + console.log('Auto-stopping layout animation after timeout') + if (animationTimerRef.current) { + window.clearInterval(animationTimerRef.current) + animationTimerRef.current = null + } + setIsRunning(false) + }, autoRunFor) } } - }, [autoRunFor, start, stop, sigma]) + + // Cleanup function + return () => { + // console.log('Cleaning up WorkerLayoutControl') + if (animationTimerRef.current) { + window.clearInterval(animationTimerRef.current) + animationTimerRef.current = null + } + if (timeout) { + window.clearTimeout(timeout) + } + setIsRunning(false) + } + }, [autoRunFor, sigma, updatePositions]) return ( + + +
{ />
- +
{Object.keys(node.properties) .sort() @@ -181,7 +256,7 @@ const NodePropertiesView = ({ node }: { node: NodeType }) => {
{node.relationships.length > 0 && ( <> -